--- title: Adopt a checked format for ADRs and implementation plans date: 2026-10-23 status: proposed implementation: in-progress summary: Use one documented ADR and plan format, enforced by a shared Go CLI (docs check). tags: - documentation - adr - tooling supersedes: [] superseded_by: [] related: [] tracking: [] implemented_by: [] --- # Adopt a checked format for ADRs and implementation plans ## Context and Problem Statement We record architecture decisions as ADRs and track delivery work as implementation plans. Across our repositories, four independent implementations of this practice grew up: each had its own filename scheme, frontmatter keys, status vocabulary and checking script (or none). The same concept was spelled differently from repository to repository, cross-references were relative paths that broke when files moved, and "accepted" did not say whether anything had been built. Tooling and agents had to learn each variant, and fixes to one checker did not reach the others. We need one format that people and tools can write without surprises, that separates *the decision* from *its delivery*, and that is verified mechanically so records do not rot. The format must be public and documented well enough that someone can write valid files from the specification alone. ## Decision Drivers * One vocabulary and one layout everywhere, so a record means the same thing in every repository. * Stable identity: a record's ID and path never change, so references stay valid. * The decision status and the implementation status are tracked separately. * Checks run locally and in CI with no service dependency. * Low upkeep: one tool to maintain, not one per repository. ## Considered Options * MADR 4 template plus generic Markdown and link linting. * Keep a checking script per repository, converging informally. * Extract and publish one existing checker. * Define one format and implement one shared Go CLI that creates and checks records. ## Decision Outcome Chosen option: "Define one format and implement one shared Go CLI that creates and checks records", because it is the only option that gives a single enforced vocabulary and identity scheme while keeping the checks free of service dependencies. The format is specified in [docs-format](/docs/docs-format.md). It uses the MADR 4 layout, with `### Consequences` under Decision Outcome made mandatory, and adds the parts MADR leaves open: timestamp-based permanent IDs in filenames, a fixed frontmatter schema, a separate `implementation` field, reciprocal supersession, durable repo-root references, and a plan record with its own lifecycle. The CLI, `docs`, offers `docs new adr|plan` and `docs check`. ### Consequences * Good, because the format has one specification, one checker and one set of error messages. * Good, because records are validated, so dead links, missing sections and contradictory statuses fail CI instead of accumulating. * Good, because the permanent ID survives title edits. * Bad, because the format is ours: we own the specification and the tool, and breaking changes before 1.0 will require updating adopters. * Neutral, because the check validates structure only; it cannot tell whether a decision is sound. ## Pros and Cons of the Options ### MADR 4 template plus generic Markdown and link linting * Good, because it is a public, widely understood template and nothing custom is built. * Bad, because MADR is a template with no checker of its own, and generic linters enforce no ID, status, supersession or reference rules. ### Keep a checking script per repository * Good, because there is no new shared artifact and each team keeps full control. * Bad, because the four existing variants already diverged; nothing stops further divergence. * Bad, because each script is maintained, tested and fixed separately, and most repositories would simply not have one. ### Extract and publish one existing checker * Good, because it is cheaper: an existing Go checker already handles timestamp IDs, exclusive creation and reciprocal supersession. * Bad, because it has no plan record, no `implementation` field and no public specification, and it is tied to one repository's conventions. ### Define one format and implement one shared Go CLI that creates and checks records * Good, because one specification and one implementation can be tested thoroughly and installed with `go install`. * Good, because the same binary creates records, so new files start with the required structure. * Bad, because we commit to maintaining a small public tool and a specification. ## More Information MADR 4: https://adr.github.io/madr/. The specification is [docs-format](/docs/docs-format.md); the implementation lands in the same pull request that records this decision.