ADR 0003 — errata for 0001/0002, and the cross-repo docs graph
- Status: accepted
- Date: 2026-06-03
- Refines: 0001 (the draft-graduation note), 0002 (the command name and reconcile semantics)
Context
ADRs are immutable once accepted — the canonical record, corrected by superseding records, not by editing (adr/README:12). Three accepted claims have since diverged from the shipped CLI and the ratified topology, and one cross-cutting subsystem shipped with no record at all. Because readers trust the ADR as the source of truth, the drift has to be corrected in a record rather than silently in code.
0002 names a command that never shipped. 0002:96 introduces the per-repo check as
atlas manifest lint [--reconcile]. The CLI has nolintsubcommand undermanifest(bin/atlas.mjs:110 dispatchesmanifest validate; the implementation issrc/commands/manifest.mjs:1,17,manifestValidate).lintappears nowhere in the manifest path — this is an internal inconsistency, since 0002's own delivery section already uses the shipped name at 0002:108,114 (atlas manifest validate / init).0002 inverts the reconcile semantics. 0002:97 says
--reconcilematches every declaredbuild/runtimeedge against a real dependency. The code does the opposite:src/reconcile.mjs:140–146 confirms declaredbuild/contractedges and explicitly skipsruntime(if (k === "runtime") continue;), because a running-service relationship never appears in a build manifest of record. The project README:89–95 already states this correctly; only the ADR is wrong.0001's draft note is stale. 0001:44 records that "stele and thesmos are draft today, pending their edges." Both are now ratified substance members: neither
topology/registry.jsonnor the generatedtopology/constellation.jsoncarriesdraft: trueon any member, anddoctor's drafts check (src/commands/doctor.mjs:67–70) reports none.The docs graph shipped with no record. A cross-repo prose-link subsystem —
atlas docs lint/atlas docs export,atlas crosslinks docs --deep, and the manifestdocsblock (schema/atlas-manifest.schema.json:60,68) — landed via #22 and #23. It spans ≥2 systems (one repo's README/ADR deep-links into a sibling's exported doc anchors) and has no single-repo owner, so by the membership test (0001:30–31) it is exactly the kind of decision an ADR should carry, yet none was written.
Decision
Record the corrections and the missing decision here; do not edit 0001 or 0002.
Erratum to 0002 (command name). The per-repo check is
atlas manifest validate [--reconcile], notatlas manifest lint. Read 0002:96 asvalidate; this is the name everywhere in the CLI and in 0002's own delivery section.Erratum to 0002 (reconcile semantics).
--reconcileconfirms declaredbuildandcontractedges against the repo's real dependency manifests and deliberately skipsruntimeedges (which a build manifest can't witness). Read 0002:97 asbuild/contract, matchingsrc/reconcile.mjsand the README.Erratum to 0001 (draft graduation). The note that stele and thesmos are draft (0001:44) is obsolete: both have graduated to ratified substance members and nothing is currently marked
draft. Thedraftmechanism itself (registry-side, per 0002) stands for future members.The cross-repo docs graph is an atlas concern. Cross-repo prose linking — a README/ADR in one repo deep-linking a stable anchor in a sibling's published docs — is owned by atlas, alongside topology and diagrams. atlas ships the tooling that defines and enforces it centrally:
- each repo declares its published doc surface in its
atlas.jsondocsblock (entry+ namedexportswith stable anchors), and an edge may name thedocsdeep-link (path#anchor) backing it; atlas docs exportwrites that surface plus discovered headings todocs/.docs-manifest.json(--checkguards freshness in CI);atlas docs lintbuilds a repo's local prose graph and fails on dead links, missing heading anchors, orphaned pages, and ADR hygiene — anddoctorruns it over atlas's own prose (src/commands/doctor.mjs:72–76);atlas crosslinks docs --deepresolves cross-repo doc links against the sibling's exported manifest, entirely offline from the same local workspacetopology syncuses.
Rationale. A deep-link's two endpoints live in two repos, so no single repo can own or verify the relationship — the same "copies rot silently, so the check ships centrally" force behind topology (0001:34–37). Exporting a stable, machine-readable doc surface per repo and resolving links against it offline keeps the check zero-dependency and runnable in any repo's CI, consistent with the charter's boundary (atlas owns build & relate; design owns look & read) — the docs graph relates prose across systems; it does not style it.
- each repo declares its published doc surface in its
Consequences
- 0001 and 0002 stay byte-for-byte immutable; their stale lines are corrected here and should be read through this erratum.
- The docs graph now has a captured "why," closing the gap where a cross-cutting subsystem existed with no decision record. Future docs-graph changes refine or supersede this record.
- No code or topology changes follow from this ADR — it reconciles the record with
already-shipped behavior;
doctoranddocs lintwere green before and stay green. - The
draftgraduation is a one-time correction; the registry-sidedraftmechanism remains available for future unplaced members.