Skip to content

The consumers' switch: extension + installer + guard read the projection, never the raw file (fleet rearchitect P3b-2) #1106

Description

@aarontrowbridge

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

  • RECON: every current raw-fleet.json read site in the three consumers is identified and listed in the PR (the F1 anti-goal: zero surviving raw-file parsers on the amicode side)
  • The projection-cache convention lands (verb-refreshed artifact at the known path; a stale/absent artifact is a RENDERED state, never an error dump)
  • The extension's fleet topology read flows through the reader (contract-validated, freshness-surfaced); a grep-style guard test asserts the extension no longer parses raw fleet.json
  • The installer consumes the verb's machine-parseable output; exit 75 branches to the honest base-standalone bootstrap (stated + pointer); CLI-absent bootstrap behaves identically
  • The guard reads topology from the projection (or the verb's output) — no hostname inference from raw files
  • F1 green: the triple-consumer replay — extension + installer + guard fed the SAME stale/broken/absent topology cases through the F-harness where applicable; n_fleet_topology_parsers == 1 asserted (the one parser is amicissimo's, behind the CLI)
  • Typecheck + suite green at the 9-failure environmental baseline; no behavioral change to base standalone installs (the solo floor is untouched)

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    hitlNeeds human review before merge

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions