You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Problem — The fleet runs five physical artifact surfaces (frozen server binary serving the chat UI, installed VSIX, vendored binary, staged skills, agent cards) with no shared state and no staleness visibility. Merged-to-main updates none of them; upgrading any is a manual chain whose runbook lives in shell-script headers. The 2026-08-23 session is the pain record: staleness noticed by a human, forensics to locate the serving artifact, fork sync → build → freeze → sidecar → kick, three interrupts each forcing state re-derivation. Approach — Four layers per spec-20260823-094507: doctor v2 (six-record surface inventory, injectable probes, four verdicts, the JSON contract); upgrade verbs (receipt-emitting idempotent runbooks with git discipline, flock, rollback); a Settings panel that is a pure view over doctor's JSON; a notturno watchdog posting nightly drift. The UI is a view over the CLI, never a parallel implementation — headless SSH and the panel consume the same contract. Approaches considered — (1) Watchdog only (report, no repair): leaves the manual chains; (2) auto-upgrade on drift: rejected — night never mutates the fleet, humans decide; (3) build the panel first with its own probes: the exact parallel-implementation failure mode the view-over-CLI invariant exists to prevent. Scope — in: doctor v2 + the four verbs + receipts/lock + the panel section + the watchdog job/registry · out: scheduled/automatic upgrades, multi-machine fan-out, the fork's release automation. Assumptions — single-operator fleet (the launchd user; panel and SSH are the same user); the frozen-binary discipline stands (never a live-path swap under a running server).
Acceptance Criteria
doctor_surface_inventory_complete == 100% — six records, version + verdict + evidence, individual degradation
doctor_verdict_matrix_complete == 100% — every cell asserts its expected verdict; all six unknown-capable; both server-binary stale mechanisms + server-down as separate fixtures
upgrade_verbs_receipted == 100% — four verbs, hermetic fixtures + verification independence + the live dispatch proof (receipt cited in the PR; CI blocks hermetic, review blocks live)
upgrade_idempotent_pass == 100% — stale → upgraded → no-op per verb, digest sets enumerated, receipt stores excluded by definition
panel_renders_doctor == true — render function tests, verbatim facts, enabled for stale AND integrity-failure, disabled-property assertions
watchdog_registered == true — renderDriftDigest pure function, zero-calls dry-run, fixture TOML with enabled=false
Testing Decisions
Hermetic vitest suites throughout (injected roots, fake binaries, pinned dates); the one stated live exemption is server-binary's sync/build chain, proven by the parent-run dispatch whose receipt lands in the PR. Authorship split per the house pattern.
Key Decisions
Digests and version strings, never mtime. Doctor's fetch is a source refresh, not a surface mutation. Never reset, never merge — divergence is human territory. The receipt store is the exit state of record. Night never mutates the fleet.
Prior Art
The 2026-08-23 session; amico-server.sh's runbook (becoming verbs); deploy-agents.mjs (the receipt pattern); doctor v1 (#402); ADR 0001; the 2026-08-08 mtime race.
Important
Problem — The fleet runs five physical artifact surfaces (frozen server binary serving the chat UI, installed VSIX, vendored binary, staged skills, agent cards) with no shared state and no staleness visibility. Merged-to-main updates none of them; upgrading any is a manual chain whose runbook lives in shell-script headers. The 2026-08-23 session is the pain record: staleness noticed by a human, forensics to locate the serving artifact, fork sync → build → freeze → sidecar → kick, three interrupts each forcing state re-derivation.
Approach — Four layers per spec-20260823-094507: doctor v2 (six-record surface inventory, injectable probes, four verdicts, the JSON contract); upgrade verbs (receipt-emitting idempotent runbooks with git discipline, flock, rollback); a Settings panel that is a pure view over doctor's JSON; a notturno watchdog posting nightly drift. The UI is a view over the CLI, never a parallel implementation — headless SSH and the panel consume the same contract.
Approaches considered — (1) Watchdog only (report, no repair): leaves the manual chains; (2) auto-upgrade on drift: rejected — night never mutates the fleet, humans decide; (3) build the panel first with its own probes: the exact parallel-implementation failure mode the view-over-CLI invariant exists to prevent.
Scope — in: doctor v2 + the four verbs + receipts/lock + the panel section + the watchdog job/registry · out: scheduled/automatic upgrades, multi-machine fan-out, the fork's release automation.
Assumptions — single-operator fleet (the launchd user; panel and SSH are the same user); the frozen-binary discipline stands (never a live-path swap under a running server).
Acceptance Criteria
doctor_surface_inventory_complete == 100%— six records, version + verdict + evidence, individual degradationdoctor_json_schema_pass == 100%— committed schema (minItems 6), canonical round-tripdoctor_verdict_matrix_complete == 100%— every cell asserts its expected verdict; all six unknown-capable; both server-binary stale mechanisms + server-down as separate fixturesupgrade_verbs_receipted == 100%— four verbs, hermetic fixtures + verification independence + the live dispatch proof (receipt cited in the PR; CI blocks hermetic, review blocks live)upgrade_idempotent_pass == 100%— stale → upgraded → no-op per verb, digest sets enumerated, receipt stores excluded by definitionpanel_renders_doctor == true— render function tests, verbatim facts, enabled for stale AND integrity-failure, disabled-property assertionswatchdog_registered == true— renderDriftDigest pure function, zero-calls dry-run, fixture TOML with enabled=falseTesting Decisions
Hermetic vitest suites throughout (injected roots, fake binaries, pinned dates); the one stated live exemption is server-binary's sync/build chain, proven by the parent-run dispatch whose receipt lands in the PR. Authorship split per the house pattern.
Key Decisions
Digests and version strings, never mtime. Doctor's fetch is a source refresh, not a surface mutation. Never reset, never merge — divergence is human territory. The receipt store is the exit state of record. Night never mutates the fleet.
Prior Art
The 2026-08-23 session; amico-server.sh's runbook (becoming verbs); deploy-agents.mjs (the receipt pattern); doctor v1 (#402); ADR 0001; the 2026-08-08 mtime race.
Source
Durable record:
~/.amico/vaults/armonia-aaron-trowbridge/specs/spec-20260823-094507-fleet-dev-tools.md(approved: 3 manual critic rounds, round 3 clean; same-day editorial pass verified by inspection — no tool-verified seal).