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:
142
server/internal/api/court_chamber_bridge.go
Normal file
142
server/internal/api/court_chamber_bridge.go
Normal file
@@ -0,0 +1,142 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
fleetai "crypto-miner-server/internal/ai"
|
||||
"crypto-miner-server/internal/atlas"
|
||||
"crypto-miner-server/internal/db"
|
||||
"crypto-miner-server/internal/strategy"
|
||||
)
|
||||
|
||||
// HubCourtChamberAdapter supplies court tribunal data from hub + SQLite.
|
||||
type HubCourtChamberAdapter struct {
|
||||
Hub *WSHub
|
||||
DB *db.Database
|
||||
}
|
||||
|
||||
// NewHubCourtChamberAdapter wires hub evidence for adversarial court sessions.
|
||||
func NewHubCourtChamberAdapter(hub *WSHub, database *db.Database) *HubCourtChamberAdapter {
|
||||
return &HubCourtChamberAdapter{Hub: hub, DB: database}
|
||||
}
|
||||
|
||||
func (a *HubCourtChamberAdapter) FailureAtlasSummary(fingerprintKey, goos string) string {
|
||||
if a == nil {
|
||||
return ""
|
||||
}
|
||||
inner := &DatabaseCourtAdapter{DB: a.DB}
|
||||
return inner.FailureAtlasSummary(fingerprintKey, goos)
|
||||
}
|
||||
|
||||
func (a *HubCourtChamberAdapter) BestPhenotype(fingerprintKey, goos string) (*strategy.FleetPhenotype, bool) {
|
||||
if a == nil {
|
||||
return nil, false
|
||||
}
|
||||
inner := &DatabaseCourtAdapter{DB: a.DB}
|
||||
return inner.BestPhenotype(fingerprintKey, goos)
|
||||
}
|
||||
|
||||
func (a *HubCourtChamberAdapter) ChamberEvidence(agentID string, snap fleetai.AgentSnapshot) fleetai.CourtChamberEvidence {
|
||||
ev := fleetai.CourtChamberEvidence{
|
||||
AgentID: agentID,
|
||||
AgentName: snap.Name,
|
||||
Hashrate: snap.MiningHashrate,
|
||||
Stuck: snap.Stuck,
|
||||
ChainExhausted: snap.ChainExhausted,
|
||||
ClearanceLevel: snap.ClearanceLevel,
|
||||
JoinLane: snap.JoinLane,
|
||||
ActiveMethod: snap.ActiveMethod,
|
||||
FingerprintKey: snap.FingerprintKey,
|
||||
}
|
||||
if a == nil {
|
||||
return ev
|
||||
}
|
||||
goos := firstNonEmpty(snap.GOOS, snap.Platform)
|
||||
ev.AtlasSummary = a.FailureAtlasSummary(snap.FingerprintKey, goos)
|
||||
ev.SubnetImmune, ev.ErasureRecovery, ev.GossipWhispers = a.hubEvidence(agentID, snap)
|
||||
return ev
|
||||
}
|
||||
|
||||
func (a *HubCourtChamberAdapter) hubEvidence(agentID string, snap fleetai.AgentSnapshot) (subnetImmune, erasureRecovery, gossip string) {
|
||||
if a.Hub == nil {
|
||||
return "hub unavailable", fleetai.FormatErasureRecovery(false, false, false), "none"
|
||||
}
|
||||
prefix := a.Hub.agentSubnetFor(agentID)
|
||||
if prefix == "" && a.Hub.db != nil {
|
||||
if ag, err := a.Hub.db.GetAgent(agentID); err == nil && ag != nil {
|
||||
prefix = atlas.PrefixFromHostOrIP(ag.IP)
|
||||
}
|
||||
}
|
||||
failCount := 0
|
||||
var pausedUntil *time.Time
|
||||
if a.Hub.db != nil && prefix != "" {
|
||||
if row, err := a.Hub.db.GetSubnetSpreadPause(prefix); err == nil && row != nil {
|
||||
failCount = row.FailCount
|
||||
pausedUntil = row.PausedUntil
|
||||
}
|
||||
}
|
||||
subnetImmune = fleetai.FormatSubnetImmuneRow(prefix, failCount, pausedUntil)
|
||||
|
||||
policy := a.Hub.serverPolicySnapshot()
|
||||
stageAttempted, stageOK := stageFetchStatus(snap.LOTLAttempts)
|
||||
erasureRecovery = fleetai.FormatErasureRecovery(policy.ErasureLanesEnabled, stageAttempted, stageOK)
|
||||
|
||||
hints := a.Hub.gossipWhispersForSubnet(prefix)
|
||||
gossip = formatGossipForCourt(hints)
|
||||
return subnetImmune, erasureRecovery, gossip
|
||||
}
|
||||
|
||||
func stageFetchStatus(attempts []fleetai.TierAttempt) (attempted, ok bool) {
|
||||
for _, a := range attempts {
|
||||
if a.Tier == "stage_fetch" || a.Tier == "bits_curl" || a.Tier == "bits" || a.Tier == "curl" {
|
||||
attempted = true
|
||||
if a.OK {
|
||||
ok = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return attempted, ok
|
||||
}
|
||||
|
||||
func formatGossipForCourt(hints []atlas.GossipHint) string {
|
||||
if len(hints) == 0 {
|
||||
return "none recorded on this /24"
|
||||
}
|
||||
parts := make([]string, 0, len(hints))
|
||||
for _, h := range hints {
|
||||
line := h.Tier + "|" + h.Condition
|
||||
if h.Reason != "" {
|
||||
line += " (" + h.Reason + ")"
|
||||
}
|
||||
parts = append(parts, line)
|
||||
}
|
||||
return strings.Join(parts, "; ")
|
||||
}
|
||||
|
||||
func firstNonEmpty(values ...string) string {
|
||||
for _, v := range values {
|
||||
if strings.TrimSpace(v) != "" {
|
||||
return strings.TrimSpace(v)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// BroadcastEmberwakeCourtDebate optionally surfaces court transcripts on Emberwake dashboard WS.
|
||||
func (h *WSHub) BroadcastEmberwakeCourtDebate(agentID string, transcript fleetai.CourtDebateTranscript) {
|
||||
if h == nil {
|
||||
return
|
||||
}
|
||||
h.broadcastDashboard(Message{
|
||||
Type: "emberwake_court_debate",
|
||||
Payload: mustMarshal(map[string]interface{}{
|
||||
"agent_id": agentID,
|
||||
"agent_name": transcript.AgentName,
|
||||
"verdict": transcript.Verdict,
|
||||
"transcript": transcript.Transcript,
|
||||
"evidence": transcript.Evidence,
|
||||
"ts": transcript.Timestamp,
|
||||
}),
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user