Files
AetherForge/server/internal/api/contingency_bridge.go
AetherForge 6dd5cbd461
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add onion contingency miner tree with orchestrator and Seer telemetry.
Single-host branch runner complements fallback chain under Fleet AI Control: persona ghost forks, onion_miner_log hops, server exhaustion splice from graft mining genome, Crucible depth badge, and hospice retire after max cycles.
2026-06-07 09:29:26 -07:00

132 lines
3.3 KiB
Go

package api
import (
"encoding/json"
"log"
fleetai "crypto-miner-server/internal/ai"
"crypto-miner-server/internal/mining"
"crypto-miner-server/internal/strategy"
)
func (h *WSHub) contingencyOrchestrator() *mining.ContingencyOrchestrator {
if h == nil {
return nil
}
return h.contingencyOrch
}
func (h *WSHub) initContingencyOrchestrator() {
if h == nil || h.contingencyOrch != nil {
return
}
policy := h.serverPolicySnapshot()
h.contingencyOrch = mining.NewContingencyOrchestrator(mining.OrchestratorDeps{
AIControl: policy.AIControlEnabled,
Persona: policy.AIPersona,
GraftFor: h.graftPolicyLookup,
OnSeer: h.emitContingencySeerEvent,
OnPush: h.pushContingencyBranchParams,
})
}
func (h *WSHub) graftPolicyLookup(agentID string) (*strategy.GraftPolicy, bool) {
if graft, ok := h.GraftPolicyForAgent(agentID); ok {
return graft, true
}
return nil, false
}
func (h *WSHub) emitContingencySeerEvent(agentID string, payload map[string]interface{}) {
if h == nil {
return
}
emitter := &HubSeerEmitter{Hub: h, DB: h.db}
_ = emitter.EmitSeerEvent("onion_miner_log", agentID, payload)
}
func (h *WSHub) pushContingencyBranchParams(agentID string, params mining.BranchParamsPush) error {
body, err := json.Marshal(params)
if err != nil {
return err
}
return h.SendToAgent(agentID, Message{Type: "contingency_branch_params", Payload: body})
}
func (h *WSHub) handleOnionMinerLog(agentID string, raw json.RawMessage) {
h.initContingencyOrchestrator()
orch := h.contingencyOrchestrator()
if orch == nil || !orch.Enabled() {
return
}
hop, err := mining.ParseOnionHop(raw)
if err != nil {
return
}
emitter := &HubSeerEmitter{Hub: h, DB: h.db}
var payload map[string]interface{}
_ = json.Unmarshal(raw, &payload)
if payload == nil {
payload = map[string]interface{}{}
}
payload["agent_id"] = agentID
_ = emitter.EmitSeerEvent("onion_miner_log", agentID, payload)
push, ok := orch.ObserveHop(agentID, hop)
if !ok {
h.cacheContingencyDepth(agentID, hop.Depth)
return
}
if err := h.pushContingencyBranchParams(agentID, push); err != nil {
log.Printf("[contingency] push branch params to %s: %v", agentID[:min(8, len(agentID))], err)
}
h.cacheContingencyDepth(agentID, hop.Depth)
}
func (h *WSHub) cacheContingencyDepth(agentID string, depth int) {
if depth <= 0 {
if orch := h.contingencyOrchestrator(); orch != nil {
depth = orch.Depth(agentID)
}
}
if depth <= 0 {
return
}
h.mu.Lock()
if h.agentLiveTelemetry[agentID] == nil {
h.agentLiveTelemetry[agentID] = make(map[string]interface{})
}
h.agentLiveTelemetry[agentID]["contingency_depth"] = depth
h.mu.Unlock()
}
func (h *WSHub) attachContingencyPolicy(resp map[string]interface{}) {
policy := h.serverPolicySnapshot()
if !policy.AIControlEnabled {
return
}
cp := fleetai.BuildContingencyPolicy(true, policy.AIPersona)
if cp != nil {
resp["contingency_policy"] = cp
}
}
func (h *WSHub) contingencyDepthForAgent(agentID string) int {
if orch := h.contingencyOrchestrator(); orch != nil {
if d := orch.Depth(agentID); d > 0 {
return d
}
}
h.mu.RLock()
defer h.mu.RUnlock()
if tel, ok := h.agentLiveTelemetry[agentID]; ok {
if v, ok := tel["contingency_depth"].(int); ok {
return v
}
if v, ok := tel["contingency_depth"].(float64); ok {
return int(v)
}
}
return 0
}