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
SPECS.md began as a design and implementation plan. The implementation has landed, but the 2,831-line file remains a second description of nearly the entire program. It duplicates command behavior, schemas, state transitions, output examples, implementation details, contributor rules, and historical rationale that already have or should have an owner closer to the code.
Issue #159 proposed shrinking SPECS.md to contract and moving rationale into ADRs. PR #162 shows why that split is an intermediate state rather than the final information architecture:
SPECS.md falls from 2,831 to 2,579 lines, only 9 percent by line count.
26 ADRs plus an index add 1,872 lines.
The PR as a whole adds 2,335 lines and deletes 692, a net increase of 1,643 lines.
Contract sections gain Why: links into ADRs, while ADRs link back into SPECS.md, so understanding one behavior crosses more files.
Neither the SPECS.md contract nor the new links are enforced by the build or tests; the PR test plan treats the documentation checks as manual.
Some ADRs preserve incident-level implementation history rather than a durable architectural boundary.
The problem is not only that rationale and contract share one file. The problem is that a monolithic prose specification duplicates executable behavior and has no single subsystem owner. Splitting that prose into a large contract plus many records increases navigation, maintenance, and drift surfaces.
This issue supersedes #159 as the final structure. If #162 lands, treat its reduced SPECS.md and ADR set as migration input: preserve its useful analysis, then rationalize both rather than assuming all newly created files are permanent. Sequence this work after #162 so the migration is performed once against the merged state.
Decision
Remove SPECS.md completely. Do not replace it with another monolithic specification or a generated copy of the CLI. Audit and restructure the ADRs introduced by #162 as part of the same migration.
A contract belongs beside the mechanism that enforces it:
Information
Authoritative home
Commands, flags, defaults, arguments, and user-facing errors
Cobra help text plus command tests
Exit codes and error kinds
cmd/root.go, focused package/command tests, and concise user documentation where needed
TOON and JSON output shapes
internal/axi, golden/contract tests, and command help
Database schema and migration rules
internal/store schema/migrations and migration tests
Brief, backlog, report-channel, and other file formats
Owning package documentation, parsers/writers, fixtures, and format tests
Watcher state transitions and persistence invariants
internal/watcher code and focused state-transition tests
Harness capabilities and launch behavior
internal/harness, shared fake behavior, and harness tests
Observed contracts of external tools
internal/faketool/FIDELITY.md and tests/contract
Fleet-home agent workflow
internal/agentsmd generated template and its tests
Contributor-wide policy
AGENTS.md or CONTRIBUTING.md, whichever owns the audience
Installation and operator workflows
README and command help
Durable architectural decisions that remain useful
A small ADR only when it records a stable boundary and materially rejected alternatives
Executable artifacts win whenever prose disagrees. A contract that matters must have a test at the closest practical boundary; prose alone must not be the only enforcement mechanism.
SPECS.md migration
Inventory the merged SPECS.md section by section and give every span one disposition before deleting it:
Already represented and enforced: delete the duplicate prose.
Durable contract without a sufficient owner: move the minimum statement to the owning package/help surface and add or strengthen a focused test.
Contributor or user guidance: move a concise version to AGENTS.md, CONTRIBUTING.md, README, or command help.
Durable architectural rationale: retain only if a future contributor could reasonably reverse a still-important boundary without it; keep or write one focused ADR.
Shipped plan, stale example, implementation narration, incident history, rejected pre-release scope, or duplicated generated content: delete. Git and closed issues already preserve history.
Record the disposition in the implementing PR description or a temporary review checklist, not in a permanent replacement ledger.
Then remove every reference to SPECS.md from README, AGENTS.md, CONTRIBUTING.md, Go comments, tests, generated fleet-home instructions, fidelity documentation, and retained ADRs. Repoint only references that still add value; delete comments whose only purpose was to cite the monolith.
Review every ADR introduced by #162 independently. Give each one exactly one disposition:
Keep: it records a durable architectural boundary, realistic rejected alternatives, and consequences not adequately expressed by tests or local documentation. Tighten it so it does not restate implementation details.
Merge: two or more records are facets of one stable decision and are more understandable together. Merge around the boundary, not merely around a shared subsystem.
Relocate: its useful content is actually an invariant, external-tool observation, contributor rule, or user workflow. Move the minimum content to the owning test, FIDELITY.md, AGENTS.md, CONTRIBUTING.md, README, or command help, then delete the ADR.
Delete: it mainly narrates an incident, repeats current code, preserves rejected pre-release scope, or is already recoverable from its issue and PR history.
Do not merge all records into a large replacement design history. A smaller ADR set is a result of applying the bar, not a numeric target. Update docs/adr/README.md to describe only the retained collection and remove its dependency on SPECS.md.
ADR bar
An ADR must describe a durable architectural decision, identify a realistic alternative a future change might reintroduce, and remain useful without narrating individual bugs or restating current implementation details.
Prefer the issue or PR that made a local implementation decision as its historical record. Prefer a focused invariant test when the important fact is what must continue to hold. Prefer FIDELITY.md when the fact belongs to an external tool rather than to Secondhand architecture.
Non-goals
Generating Markdown from Cobra solely to replace SPECS.md. hand --help is already the command reference.
Copying every deleted example into README or package comments.
Every retained ADR passes the narrow ADR bar, contains no duplicated behavioral contract, and links directly to relevant code, tests, issues, or PRs where useful.
docs/adr/README.md describes the final retained collection without acting as a replacement specification.
No new monolithic specification, contract ledger, exhaustive generated CLI reference, or monolithic ADR replaces SPECS.md.
Each retained behavioral contract has a clearly named owner beside its implementation and a focused test where practical.
User-facing workflows remain discoverable through README and hand --help.
Contributor-wide rules remain discoverable through AGENTS.md and CONTRIBUTING.md.
External-tool fidelity remains documented and checked through internal/faketool/FIDELITY.md and make contract.
Problem
SPECS.md began as a design and implementation plan. The implementation has landed, but the 2,831-line file remains a second description of nearly the entire program. It duplicates command behavior, schemas, state transitions, output examples, implementation details, contributor rules, and historical rationale that already have or should have an owner closer to the code.
Issue #159 proposed shrinking SPECS.md to contract and moving rationale into ADRs. PR #162 shows why that split is an intermediate state rather than the final information architecture:
Why:links into ADRs, while ADRs link back into SPECS.md, so understanding one behavior crosses more files.The problem is not only that rationale and contract share one file. The problem is that a monolithic prose specification duplicates executable behavior and has no single subsystem owner. Splitting that prose into a large contract plus many records increases navigation, maintenance, and drift surfaces.
This issue supersedes #159 as the final structure. If #162 lands, treat its reduced SPECS.md and ADR set as migration input: preserve its useful analysis, then rationalize both rather than assuming all newly created files are permanent. Sequence this work after #162 so the migration is performed once against the merged state.
Decision
Remove SPECS.md completely. Do not replace it with another monolithic specification or a generated copy of the CLI. Audit and restructure the ADRs introduced by #162 as part of the same migration.
A contract belongs beside the mechanism that enforces it:
cmd/root.go, focused package/command tests, and concise user documentation where neededinternal/axi, golden/contract tests, and command helpinternal/storeschema/migrations and migration testsinternal/watchercode and focused state-transition testsinternal/harness, shared fake behavior, and harness testsinternal/faketool/FIDELITY.mdandtests/contractinternal/agentsmdgenerated template and its testsExecutable artifacts win whenever prose disagrees. A contract that matters must have a test at the closest practical boundary; prose alone must not be the only enforcement mechanism.
SPECS.md migration
Inventory the merged SPECS.md section by section and give every span one disposition before deleting it:
Record the disposition in the implementing PR description or a temporary review checklist, not in a permanent replacement ledger.
Then remove every reference to SPECS.md from README, AGENTS.md, CONTRIBUTING.md, Go comments, tests, generated fleet-home instructions, fidelity documentation, and retained ADRs. Repoint only references that still add value; delete comments whose only purpose was to cite the monolith.
ADR restructuring after #162
Review every ADR introduced by #162 independently. Give each one exactly one disposition:
Do not merge all records into a large replacement design history. A smaller ADR set is a result of applying the bar, not a numeric target. Update
docs/adr/README.mdto describe only the retained collection and remove its dependency on SPECS.md.ADR bar
An ADR must describe a durable architectural decision, identify a realistic alternative a future change might reintroduce, and remain useful without narrating individual bugs or restating current implementation details.
Prefer the issue or PR that made a local implementation decision as its historical record. Prefer a focused invariant test when the important fact is what must continue to hold. Prefer FIDELITY.md when the fact belongs to an external tool rather than to Secondhand architecture.
Non-goals
hand --helpis already the command reference.Acceptance criteria
rg "SPECS\.md"returns no tracked references, including underdocs/adr/.docs/adr/README.mddescribes the final retained collection without acting as a replacement specification.hand --help.internal/faketool/FIDELITY.mdandmake contract.make lint,go build ./...,go test -race ./..., the e2e suite, andmake contractpass.hand initcontains no stale reference to SPECS.md.