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

@@ -54,6 +54,7 @@ export interface AccessDepthServerPolicy {
lotl_onion_tiers?: string[];
mining_tier_order?: string[];
mining_skip_tiers?: string[];
graft_enabled?: boolean;
triple_onion?: {
recon_tiers?: string[];
deploy_lanes?: string[];
@@ -521,6 +522,8 @@ export function buildAccessDepthModel(
export function parseAccessDepthServerPolicy(config: {
server?: {
lotl_onion_tiers?: string[];
ai_control_enabled?: boolean;
fleet_roles_enabled?: boolean;
triple_onion_policy?: {
recon_tiers?: string[];
deploy_lanes?: string[];
@@ -528,9 +531,12 @@ export function parseAccessDepthServerPolicy(config: {
};
}): AccessDepthServerPolicy {
const server = config.server;
const graftEnabled =
server?.ai_control_enabled === true && server?.fleet_roles_enabled === true;
return {
lotl_onion_tiers: server?.lotl_onion_tiers,
mining_tier_order: [...DEFAULT_MINING_TIER_ORDER],
graft_enabled: graftEnabled,
triple_onion: server?.triple_onion_policy
? {
recon_tiers: server.triple_onion_policy.recon_tiers,

View File

@@ -0,0 +1,29 @@
import { describe, it, expect } from 'vitest';
import { PAGE_WEATHER } from './pageWeather';
import { dominantScoutVenue, mergeScoutBiomeWeather } from './scoutBiomeWeather';
describe('scoutBiomeWeather', () => {
it('picks dominant venue by agent weight', () => {
const venue = dominantScoutVenue({
constellations: [
{ ssid: 'a', venue_class: 'campus', agent_ids: ['1', '2', '3'] },
{ ssid: 'b', venue_class: 'airport', agent_ids: ['4', '5', '6', '7'] },
],
});
expect(venue).toBe('airport');
});
it('boosts emberwake pulse for retail scout biome', () => {
const base = PAGE_WEATHER['/emberwake'];
const merged = mergeScoutBiomeWeather(base, {
constellations: [{ ssid: 'Target-Guest', venue_class: 'retail', agent_ids: ['a', 'b', 'c'] }],
});
expect(merged.pulse).toBeGreaterThan(base.pulse);
expect(merged.energyPulse).toBe(true);
});
it('returns base weather when no constellations', () => {
const base = PAGE_WEATHER['/dashboard'];
expect(mergeScoutBiomeWeather(base, null)).toEqual(base);
});
});

View File

@@ -0,0 +1,56 @@
/** Scout constellation venue → ambient weather biome overlay. */
import type { PageWeatherConfig } from './pageWeather';
export interface ScoutConstellationBiome {
ssid: string;
venue_class: string;
persona_pack?: string;
agent_ids?: string[];
hits?: number;
}
export interface ScoutConstellationSnapshot {
constellations?: ScoutConstellationBiome[];
}
const VENUE_BIOME: Record<string, Partial<PageWeatherConfig>> = {
airport: { pulse: 1.35, linkStrength: 0.92, density: 0.95, palette: 'campaign' },
campus: { pulse: 1.1, linkStrength: 0.82, density: 0.88, palette: 'default' },
retail: { pulse: 1.75, speed: 0.62, linkStrength: 0.88, palette: 'campaign', energyPulse: true },
unknown: { pulse: 0.95, linkStrength: 0.7, density: 0.8 },
};
/** Pick the dominant venue class from active scout constellations. */
export function dominantScoutVenue(snapshot: ScoutConstellationSnapshot | null | undefined): string | null {
const list = snapshot?.constellations ?? [];
if (!list.length) return null;
const rank: Record<string, number> = { airport: 4, retail: 3, campus: 2, unknown: 1 };
let best = list[0].venue_class || 'unknown';
let bestScore = (list[0].agent_ids?.length ?? 1) * (rank[best] ?? 1);
for (let i = 1; i < list.length; i++) {
const venue = list[i].venue_class || 'unknown';
const score = (list[i].agent_ids?.length ?? 1) * (rank[venue] ?? 1);
if (score > bestScore) {
best = venue;
bestScore = score;
}
}
return best;
}
/** Merge fleet scout biome hints into route weather (Emberwake / dashboard). */
export function mergeScoutBiomeWeather(
base: PageWeatherConfig,
snapshot: ScoutConstellationSnapshot | null | undefined,
): PageWeatherConfig {
const venue = dominantScoutVenue(snapshot);
if (!venue) return base;
const overlay = VENUE_BIOME[venue] ?? VENUE_BIOME.unknown;
return {
...base,
...overlay,
intensity: Math.min(1, (base.intensity + (overlay.intensity ?? base.intensity)) / 2 + 0.08),
energyPulse: overlay.energyPulse ?? base.energyPulse,
};
}

View File

@@ -156,6 +156,10 @@ export const UI_HELP: Record<string, string> = {
md_preflight:
'Wallet, control URL, and worker name must pass validation before Equip & Strike unlocks. Spread Kit export is skipped automatically when your loadout ships a single-platform or fusion deliverable instead.',
subnet_immune_autopsy:
'Auto-built when a /24 hits five spread failures: last LOTL attempts, WSUS mimic, persona, erasure fallback, atlas gossip whispers, cause-of-death, and BGP vaccination lane from the spread router.',
pt_subnet_autopsy:
'Immune autopsy for spread-target /24 prefixes paused by subnet_spread_pause — shows vaccination route hints beside Path Tracer spread routes.',
ew_overview:
'Spread desk after you forge: tag install links with ?c=, export lure kits, and read campaign funnels. Forge agents on Mission Deck (fast) or Forge (full control).',
ew_campaign_setup:

View File

@@ -90,6 +90,7 @@ export const WS_LATEST_MESSAGE_TYPES = new Set([
'notes_typing',
'emberwake_notes_updated',
'emberwake_war_room',
'scout_constellations',
'agent_online',
'agent_offline',
'new_share',