Skip to content

ADR 0020: Dissolve .discern/ — one root config file, config-driven point-and-override, feature toggles

Amendments.

  • Vocabulary: current pointers use standards (formerly ratchets), [jobs] / [jobs.<name>] (formerly [capabilities] / [checks.<name>]), Agent file (formerly Compiled agent file), Project-owned file (formerly the Your files / Yours category), and Generated file (formerly The binary's files); the retired product-category wording reads as discern, the gate, or the bar; the decisions below are unchanged.
  • ADR 0137 — Project Scripts: the config-pointing and ownership rule now applies to [scripts].dir; Project Scripts live under discern script, not the root command namespace.

Status: accepted; supersedes ADR 0016; the single-root-file config footprint is narrowed for runtime per-worktree state by ADR 0025 (the resource ledger under .git/); the [features] set introduced here is later revised by ADR 0045 (which drops mcp — the MCP server became core infrastructure, not a toggle); the root-scatter defaults introduced here are consolidated under a visible discern/ namespace by ADR 0099, and the [features] set is retired outright by ADR 0101 — this ADR's config-pointing and ownership rules stand

Context

§

ADR 0016 consolidated everything the kit owned under a hidden .discern/ namespace: config.toml, guidelines/, brief.md, recipes/, and skills/. That answered "discern is all over the place" — but the single-binary cutover changed the calculus, and three DX problems remained, all about the install footprint rather than the tool:

  1. It hid content you author. Guidance, recipes, and skills are things you write and want to see — burying them in a dotfolder is poor discoverability.
  2. It forced the binary's artifacts to cohabit with your files. .discern/skills/ held bundled skills (generated, gitignored, re-published) and authored skills (project-owned, tracked) in one directory — a part-tracked/part-ignored mess that silently de-tracked authored skills on upgrade. (The concrete trigger: a repo with hand-authored skills under .discern/skills/ would lose them by following the upgrade guide literally.)
  3. There was no provider-agnostic, config-driven way to point discern at your own conventions.

This is still pre-adoption beyond the maintainer, so the layout can change freely.

Decision

§

Dissolve .discern/. The entire discern footprint in a project becomes one root file: discern.toml. Everything else is one of three things:

  1. Bundled in the binary — the engine (already), the built-in discern guidance (templates/guidance/*), and the built-in skills (templates/skills/).
  2. A config-pointed location you choose, with a sensible discoverable default, read only when present: [guidance].sources (→ guidance.md), [skills].dir (→ ./skills), [recipes].dir (→ ./recipes).
  3. Generated files and directories discern writes (never project-owned): the Agent files (AGENTS.md tracked; CLAUDE.md/GEMINI.md gitignored) and the materialized .claude/skills/.

Concretely:

  • Root discovery keys on discern.toml. The pre-6 .discern/config.toml is demoted to a legacy/migration-source marker (recognised so a not-yet-upgraded install still works and is carried forward).
  • Skills, guidance, recipes are bundled built-ins ⊕ project-owned config-pointed additions, project-owned sources overriding/extending — one consistent rule for all three.
  • Skills materialize into the provider dir .claude/skills/ (gitignored): bundled skills as copies (their source is in the binary, out of the tree), authored skills as symlinks into [skills].dir (so edits are live). No directory is ever part-tracked/part-ignored — [skills].dir is 100% project-owned, .claude/skills/ is 100% generated. discern skills list|eject manage the set.
  • Built-in discern guidance is bundled, always-on, and feature-aware. The compiler assembles [built-in base] + [built-in section per enabled feature] + [your [guidance].sources] into each provider file in [guidance].agents. A generated banner heads every output; only AGENTS.md is tracked.
  • [features] toggles whole subsystems (worktrees, standards, guidance, skills, docs); each defaults on. A disabled feature vanishes coherently: its verbs hide from --help (and error "feature disabled" if invoked), its hooks aren't written, its guidance section is omitted, and its doctor checks skip. This is distinct from [capabilities] (the gate's command table) — they are different sections with different jobs.
  • .claude/ is the provider's, not discern's. discern writes hooks and materializes skills there because that is where Claude Code looks; it is a write-target, never part of "where discern keeps its stuff."

This is a schema 5 → 6 migration (the first under the ADR 0014 chain to move the config back to the root — where the pre-0016 layout already had it).

Consequences

§
  • An empty install is one file: discern.toml (plus the generated AGENTS.md/ CLAUDE.md and the two integration files .claude/settings.json + .gitignore). As you opt in, your files appear in the open at paths you control.
  • The part-tracked/part-ignored skills bug is gone by construction (R1): the 5→6 migration splits .discern/skills/ by name — authored dirs move to ./skills/, pristine bundled copies are pruned, and a customized bundled-named dir is preserved (moved to ./skills/ as an override) rather than lost. A fixture-backed test asserts the split.
  • AGENTS.md is tracked but generated. A loud banner and the docs say so; a stale AGENTS.md fails CI's git diff --exit-code. Every other provider mirror is gitignored.
  • Downstream installs with custom recipes that sourced the old shell library still need a manual rewrite (the R3 contract from ADR 0019); doctor flags them, and the upgrade guide calls it out.
  • This supersedes [ADR 0016]: the .discern/ namespace it introduced is gone. It also retires 0016's managed-skills relocation question — skills are now bundled-plus-authored with a clear override rule.

Alternatives considered

§
  • Keep .discern/ but un-hide the authored parts. Rejected: the real problem was the mixed-ownership directory and the lack of config-driven pointing, not merely the dot-prefix. A half-measure would keep the de-tracking trap.
  • Put authored skills/guidance under .claude/. Rejected: .claude/ is the provider's directory (gitignored, regenerated). Authored content must be the user's, tracked, and provider-agnostic.
  • Keep AGENTS.md gitignored like the other mirrors. Rejected: a tracked agent file makes guidance changes reviewable and gives CI a drift check; one tracked mirror is enough, and AGENTS.md is the committed cross-tool standard.
  • A blanket prune of .discern/skills/ on migration. Rejected: it would lose hand-authored skills (the exact bug that triggered this). The by-name split with a content guard preserves authored work.
choose openEsc close