Add fleet evolution: genetic breeding, atlas gossip, BGP router, seeder/miner, genealogy, court gates, APK scout, personas, WSUS mimic, and P2 test coverage

This commit is contained in:
AetherForge
2026-06-07 05:00:22 -07:00
parent 7b2d41cda8
commit 82d74abfcf
38 changed files with 486 additions and 120 deletions

View File

@@ -273,3 +273,21 @@
opacity: 0.45;
}
}
.access-depth-lineage {
display: flex;
align-items: center;
gap: 0.35rem;
font-size: 0.72rem;
color: #c8d0d8;
margin-top: 0.25rem;
}
.access-depth-strain-swatch {
display: inline-block;
width: 0.65rem;
height: 0.65rem;
border-radius: 2px;
border: 1px solid rgba(255, 255, 255, 0.25);
flex-shrink: 0;
}

View File

@@ -200,6 +200,20 @@ describe('AccessDepthPanel', () => {
expect(screen.getByText(/confidence 72%/i)).toBeInTheDocument();
});
it('shows spread genealogy lineage when watermark present', async () => {
renderPanel(
mockAgent({
platform: 'windows',
parent_agent_id: '11112222-3333-4444-aaaa-bbbbbbbbbbbb',
spread_generation: 2,
spread_strain: '#a1b2c3',
join_lane: 'winrm',
}),
);
expect(await screen.findByText(/lineage gen 2/i)).toBeInTheDocument();
expect(screen.getByText(/parent 11112222/i)).toBeInTheDocument();
});
it('renders clearance badge L0L4 with tooltip permissions', () => {
renderPanel(mockAgent({ clearance_level: 2 }));
const badge = screen.getByLabelText(/Clearance L2/i);

View File

@@ -189,6 +189,22 @@ export default function AccessDepthPanel({ agent, diagnostics }: Props) {
) : (
<div className="access-depth-muted">No join lane yet</div>
)}
{(agent.parent_agent_id || agent.spread_generation || agent.spread_strain) && (
<div className="access-depth-lineage" data-strain={agent.spread_strain?.replace(/^#/, '') ?? ''}>
lineage gen {agent.spread_generation ?? 0}
{agent.spread_strain ? (
<span
className="access-depth-strain-swatch"
style={{ backgroundColor: agent.spread_strain }}
title={`strain ${agent.spread_strain}`}
aria-hidden
/>
) : null}
{agent.parent_agent_id ? (
<span className="access-depth-muted"> · parent {agent.parent_agent_id.slice(0, 8)}</span>
) : null}
</div>
)}
{model.phenotypeSource && (
<div className="access-depth-phenotype">
phenotype cloned from <strong>{model.phenotypeSource}</strong>

View File

@@ -57,9 +57,9 @@ const NAV = [
const DOCS_HREF = '/docs/';
/** Primary tabs on mobile bottom bar — Deck, Crucible, Path Tracer, Forge, Mission Deck */
/** Primary tabs on mobile bottom bar — Deck, Crucible, Activity, ROI, Onion */
const MOBILE_PRIMARY = NAV.slice(0, 5);
/** Mission Deck, Builds, Emberwake, Calibrate — More sheet */
/** Path Tracer, Forge, Mission Deck, Builds, Emberwake, Calibrate — "More" sheet */
const MOBILE_MORE = NAV.slice(5);
function NavIcon({ type }: { type: string }) {
@@ -283,9 +283,12 @@ export default function Layout({ children }: LayoutProps) {
const moreActive = MOBILE_MORE.some((item) => location.pathname === item.to);
const mobileShortLabel: Record<string, string> = {
'/dashboard': 'Deck',
'/crucible': 'Ops',
'/crucible': 'Ops',
'/activity': 'Feed',
'/roi': 'ROI',
'/lotl-timeline': 'Onion',
'/pathtracer': 'Tracer',
'/forge': 'Forge',
'/forge': 'Forge',
};
return (