Problem — Row 1's whole point: fleet topology truth is still parsed independently by three consumers — the extension's typed read, the installer's grep, the guard's hostname logic — the exact duplication that shipped the placeholder bug. The machinery to end it is ALL on main now: the fleet authority (amicissimo #413/#415), the projection reader (@amicode/schema), the amico fleet status --projection verb + bootstrap exception (exit 75) (#1071). This slice switches the consumers.
Approach — RECON FIRST (the consumers are live surfaces — find them precisely): the extension's fleet.json typed-parse path(s) (fleet activation / service modules), the installer (tools/fleet/install.sh's grep reads), and the guard script (the ~/.local/bin guard's hostname logic). Then: (1) establish the stable projection-cache convention — the verb refreshes a projection at a known path (~/.amico/ops/fleet/projection.json — the live layout precedent; the CLI's --out already supports it), so consumers have ONE artifact to read; (2) the extension consumes the reader (@amicode/schema's fleet_projection — contract validation + D1 freshness + provenance; NEVER the raw file; stale/unknown freshness surfaces, never silently renders); (3) the installer shells the verb (amico fleet status --projection — machine-parseable output; exit 75 = the bootstrap exception → base-standalone stated with the pointer, the SAME branch the installer uses for CLI-absent bootstrap); (4) the guard consumes the projection (no hostname inference from raw state); (5) every consumer handles absent/stale/broken projection honestly (stale badge, bootstrap message — never a silent fallthrough to raw-file reading).
Acceptance Criteria
Key Decisions
- The verb surface stays
status --projection (the naming revisit is P4's flagged item — NOT this slice)
- Consumers read the CACHED artifact / verb output; they never invoke the Python directly (the CLI is the only door — invariant 5's same-path rule)
- The extension's reader consumption reuses @amicode/schema verbatim (consume, never re-define)
Testing Decisions — vitest for the extension paths; the installer/guard are scripts — test their behavior through the surfaces the repo already tests scripts by (follow how tools/fleet is tested today; if script tests don't exist, wrap the logic in a testable seam and keep the script a thin shell — do NOT leave the switch untested)
Constraints — vitest only; no new deps; the scripts' live behavior for EXISTING enrolled fleets must not break (the fleet is a real 3-device fleet — the switch must be safe for the machines running today: additive read paths first, raw-file removal only where the projection path is proven); overlay-mutation side effects uncommitted; shared checkouts + skills-agent worktrees OFF-LIMITS; worktree off origin/main only
Source — Part of approved spec spec-20260913-114814 (row 1, D1, §8 F1) · builds on #1071 (merged) + amicissimo #413/#415 (merged) · Completes the row-1 countermeasure with the F1 fixture
Notes — gate discipline: director re-runs every verdict from commands; merges per the standing green directive.
Problem — Row 1's whole point: fleet topology truth is still parsed independently by three consumers — the extension's typed read, the installer's grep, the guard's hostname logic — the exact duplication that shipped the placeholder bug. The machinery to end it is ALL on main now: the fleet authority (amicissimo #413/#415), the projection reader (@amicode/schema), the
amico fleet status --projectionverb + bootstrap exception (exit 75) (#1071). This slice switches the consumers.Approach — RECON FIRST (the consumers are live surfaces — find them precisely): the extension's fleet.json typed-parse path(s) (fleet activation / service modules), the installer (tools/fleet/install.sh's grep reads), and the guard script (the ~/.local/bin guard's hostname logic). Then: (1) establish the stable projection-cache convention — the verb refreshes a projection at a known path (
~/.amico/ops/fleet/projection.json— the live layout precedent; the CLI's--outalready supports it), so consumers have ONE artifact to read; (2) the extension consumes the reader (@amicode/schema's fleet_projection — contract validation + D1 freshness + provenance; NEVER the raw file; stale/unknown freshness surfaces, never silently renders); (3) the installer shells the verb (amico fleet status --projection— machine-parseable output; exit 75 = the bootstrap exception → base-standalone stated with the pointer, the SAME branch the installer uses for CLI-absent bootstrap); (4) the guard consumes the projection (no hostname inference from raw state); (5) every consumer handles absent/stale/broken projection honestly (stale badge, bootstrap message — never a silent fallthrough to raw-file reading).Acceptance Criteria
n_fleet_topology_parsers == 1asserted (the one parser is amicissimo's, behind the CLI)Key Decisions
status --projection(the naming revisit is P4's flagged item — NOT this slice)Testing Decisions — vitest for the extension paths; the installer/guard are scripts — test their behavior through the surfaces the repo already tests scripts by (follow how tools/fleet is tested today; if script tests don't exist, wrap the logic in a testable seam and keep the script a thin shell — do NOT leave the switch untested)
Constraints — vitest only; no new deps; the scripts' live behavior for EXISTING enrolled fleets must not break (the fleet is a real 3-device fleet — the switch must be safe for the machines running today: additive read paths first, raw-file removal only where the projection path is proven); overlay-mutation side effects uncommitted; shared checkouts + skills-agent worktrees OFF-LIMITS; worktree off origin/main only
Source — Part of approved spec spec-20260913-114814 (row 1, D1, §8 F1) · builds on #1071 (merged) + amicissimo #413/#415 (merged) · Completes the row-1 countermeasure with the F1 fixture
Notes — gate discipline: director re-runs every verdict from commands; merges per the standing green directive.