Skip to content

ADR 0080: The agent map has one configured root

Amendments.

  • Vocabulary: current pointers use [map] / discern map (formerly [docs] / discern docs), standards (formerly ratchets), and known/custom job (formerly gate capability / custom check); ADR 0120 later moved the fresh default to map/, so the historical docs/ examples below record the prior default; the configured-root decision and reasoning are unchanged.
  • ADR 0131 — consent question retired: the consent-checklist docs-location question and the setup begin --map coda retired — setup states that existing docs stay untouched instead of asking, and [map].dir remains address configuration, never an adoption channel.
  • ADR 0286 — live references: ${map.dir} is now one member of the closed, registry-derived live-reference set for configured source paths; the rejection of general-purpose config interpolation remains.
  • Skeleton packaging (2026-09-04): internal setup and write-ADR skeleton sources now live under skeleton/map/, naming their role rather than a historical destination. They still project into the configured [map].dir; source location is not a second destination authority.

Status: accepted; extends ADR 0075 (setup's staged handshake) and ADR 0026 (the typed config schema is the source of truth); the configured root's default moves inside the discern/ namespace by ADR 0099, and the tree's agent-first identity is formalized by ADR 0100.

Context

§

discern's documentation tree describes what coding agents can infer from a project's code. It is conceptually distinct from human-curated project documentation, but every docs-aware surface assumed that both lived at docs/: setup scaffolded there, discern map browsed there, setup-state checks inspected it, and the generated config's prose check, docs Scope, and prose Standard named it literally.

ADR 0075 made discern setup verify detect an existing docs/ tree and ask the human where discern's tree belongs. The preflight could not act on the answer: there was no persisted field, and choosing docs/discern/ would leave the rest of the Engine looking at docs/.

The quality-gate declarations make this more than an Installer flag. Writing a chosen path into several generated strings would work initially, but a later discern config set map.dir ... would silently separate scaffolding and browsing from checks, scope classification, and standards. The configured path needs one live source.

Decision

§

[map].dir is the single source of truth for discern's maintained project Map. It defaults to discern/map/, is relative to the project root, and rejects absolute paths and parent traversal. Setup writes the field into discern.toml, scaffolds the tree there, and renders its authoring instructions with that path. discern map, setup-state checks, instructions, improvement rules, and bundled Map skills resolve the same field.

discern setup verify remains read-only. Existing human documentation stays owner material and is never offered for adoption. A deliberate setup begin --map "<path>" choice persists that project-relative destination before laying the skeleton.

Config strings may contain the exact reference ${map.dir}. The Engine expands it from the loaded config when it runs declared jobs, Scope paths and gates, and Standard commands and extent globs. The hand-authored config template uses that reference for its prose check, docs Scope, and prose Standard, so changing [map].dir later keeps those declarations aligned without rewriting them.

The explicit noes:

  • No merging or folding of human-written docs. Existing project docs remain untouched; this decision only gives discern's separate tree a chosen home.
  • No state written by setup verify. The read-only-to-mutating boundary remains verify | begin.
  • No absolute or parent-traversing Map roots. The tree remains inside the project, where root-relative Scope and glob semantics are defined.
  • No second skeleton-path authority. The source directories are named map; codegen projects those bytes into [map].dir rather than deriving a destination from the package path.

Consequences

§

An established project can keep its human documentation at docs/, place discern's Map at a location such as discern/map/, and have setup, browsing, instructions, setup completion, improvement advice, Scope classification, prose linting, and prose Standards agree on that location.

The config template gains a small interpolation language shared by several Engine surfaces. Expansion is deliberately limited to one exact reference, kept in one helper, and covered across every supported declaration type. Other config paths do not become general-purpose variables.

Skeleton sources live under templates/**/skeleton/map/; that path is the binary's internal packaging layout, not the destination in an installed project. Setup and the Skills copy from it into the configured root.

Alternatives considered

§

Render the chosen path directly into every generated command and glob. Rejected because [map].dir is editable after setup. Duplicated literal paths would drift unless every config edit also rewrote unrelated user-owned fields.

Make discern map --dir the only override. Rejected because it fixes browsing alone; scaffolding, setup proof, Scopes, checks, and Standards would still disagree.

Allow any filesystem path. Rejected because Scopes and Standard extents are project-relative, and setup's ownership promise is limited to the project.

choose openEsc close