Add adversarial L4 court chamber with Seer court_debate feed.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Prosecutor and Public Defender use real fleet telemetry only; Judge dispatches L4 commands and emits full transcripts via seer_events and emberwake_court_debate when ai_control_enabled.
This commit is contained in:
92
server/internal/ai/court_chamber_test.go
Normal file
92
server/internal/ai/court_chamber_test.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package ai
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"crypto-miner-server/internal/strategy"
|
||||
)
|
||||
|
||||
func TestBuildCourtDebateIncludesRealEvidence(t *testing.T) {
|
||||
ev := CourtChamberEvidence{
|
||||
AgentID: "a1", AgentName: "stuck", Hashrate: 0, Stuck: true,
|
||||
ChainExhausted: true, AtlasSummary: "docker 5/5 failed (100%)",
|
||||
SubnetImmune: "prefix=10.0.0 fail_count=5 paused_until=2026-06-08T00:00:00Z UTC",
|
||||
ErasureRecovery: "lanes_enabled=true stage_fetch_attempted=false (RS 4+2 shard recovery available via stage_fetch)",
|
||||
GossipWhispers: "docker|defender_on (lan gossip)",
|
||||
}
|
||||
snap := AgentSnapshot{
|
||||
AgentID: "a1", Name: "stuck", Stuck: true, ChainExhausted: true,
|
||||
LOTLAttempts: stuckSpreadAttempts(),
|
||||
}
|
||||
transcript, bundle := BuildCourtDebate(snap, ev, nil, PersonaBalanced)
|
||||
if len(transcript.Transcript) != 2 {
|
||||
t.Fatalf("transcript=%+v", transcript.Transcript)
|
||||
}
|
||||
if transcript.Transcript[0].Role != "prosecutor" || transcript.Transcript[1].Role != "defender" {
|
||||
t.Fatalf("roles=%+v", transcript.Transcript)
|
||||
}
|
||||
pros := transcript.Transcript[0].Text
|
||||
for _, want := range []string{
|
||||
"0.00 H/s", "Failure atlas: docker", "Subnet immune table:",
|
||||
"Erasure recovery:", "Atlas LAN gossip whispers:", "14/14 failed",
|
||||
} {
|
||||
if !strings.Contains(pros, want) {
|
||||
t.Fatalf("prosecutor missing %q: %s", want, pros)
|
||||
}
|
||||
}
|
||||
if !strings.Contains(bundle.SystemPrompt, "## PUBLIC DEFENDER") {
|
||||
t.Fatalf("judge prompt missing defender section")
|
||||
}
|
||||
if !strings.Contains(bundle.UserPrompt, "## JUDGE (L4)") {
|
||||
t.Fatalf("judge user prompt: %s", bundle.UserPrompt)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuildCourtDebateDefenderPhenotype(t *testing.T) {
|
||||
phenotype := &strategy.FleetPhenotype{
|
||||
Fingerprint: "win|1", SourceAgentName: "winner", ActiveTier: "container",
|
||||
PeakHashrate: 900, SpreadLane: "winrm", TierOrder: []string{"container", "wsl"},
|
||||
}
|
||||
ev := CourtChamberEvidence{ErasureRecovery: "lanes_enabled=true stage_fetch_attempted=false"}
|
||||
_, bundle := BuildCourtDebate(AgentSnapshot{AgentID: "a1"}, ev, phenotype, PersonaBalanced)
|
||||
if !strings.Contains(bundle.DefenderSnippet, "Fleet phenotype from winner") {
|
||||
t.Fatalf("defender=%s", bundle.DefenderSnippet)
|
||||
}
|
||||
if !strings.Contains(bundle.DefenderSnippet, "Erasure RS 4+2 lanes") {
|
||||
t.Fatalf("defender erasure=%s", bundle.DefenderSnippet)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFinalizeCourtDebateAddsJudgeTurn(t *testing.T) {
|
||||
raw := "Verdict: restart mining.\n{\"commands\":[{\"type\":\"restart_mining\",\"args\":{}}]}"
|
||||
transcript := CourtDebateTranscript{
|
||||
Transcript: []CourtDebateTurn{{Role: "prosecutor", Text: "charges"}},
|
||||
}
|
||||
out := FinalizeCourtDebate(transcript, raw)
|
||||
if len(out.Transcript) != 2 || out.Transcript[1].Role != "judge" {
|
||||
t.Fatalf("transcript=%+v", out.Transcript)
|
||||
}
|
||||
if out.Verdict != "restart mining." {
|
||||
t.Fatalf("verdict=%q", out.Verdict)
|
||||
}
|
||||
if !strings.Contains(out.CommandsJSON, "restart_mining") {
|
||||
t.Fatalf("commands=%q", out.CommandsJSON)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatSubnetImmuneRowPaused(t *testing.T) {
|
||||
until := time.Now().UTC().Add(2 * time.Hour)
|
||||
line := FormatSubnetImmuneRow("10.0.0", 5, &until)
|
||||
if !strings.Contains(line, "fail_count=5") || !strings.Contains(line, "paused_until=") {
|
||||
t.Fatalf("line=%q", line)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFormatErasureRecovery(t *testing.T) {
|
||||
line := FormatErasureRecovery(true, true, false)
|
||||
if !strings.Contains(line, "lanes_enabled=true") || !strings.Contains(line, "stage_fetch_ok=false") {
|
||||
t.Fatalf("line=%q", line)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user