Packages

development-driven-specs — the dds toolchain (protocol 2) as a Mix task. A thin shim over the bundled instruments (Python, stdlib); never a port.

Current section

Files

Jump to
dds priv toolchain canon AGENTS.md
Raw

priv/toolchain/canon/AGENTS.md

# Notes for LLM agents working in this repository
Strict documentation discipline applies. Before generating prose,
modifying docs, or producing commit messages, load:
1. [`docs/principles.md`](docs/principles.md) — the directive (three permitted forms; forbidden form), layered epistemology, source authority. Defines vocabulary the rest assumes.
2. [`docs/conventions.md`](docs/conventions.md) — concrete formats for ADRs, goals, domain documents, inline comments, commit messages, CODEOWNERS.
3. [`docs/README.md`](docs/README.md) — navigation and ownership.
## Hard constraints
- **Code is the source of truth; non-executable artifacts are the
*why*.** If you find yourself paraphrasing a schema, state machine,
or field list, delete the prose and use a pointer (`Realization:`,
`Codified-by:`, `Verified-by:`, `See:`). See
[`principles.md` §1](docs/principles.md#1-the-directive).
- **No uncoupled present-tense prose** describing how the system works.
Use the three permitted forms in their proper locations. See
[`principles.md` §1](docs/principles.md#1-the-directive).
- **Do not invent sources.** If a requirement's source is not present
in the conversation or linked artifacts, **stop and ask the user**.
Fabricated `Source:` lines pass through CODEOWNERS as if real.
See [`principles.md` §5](docs/principles.md#5-sources-authority-and-the-requirement-as-premise).
- **No conjecture.** Existence-predicate comments name `Premise:` and
`Consequence:` only. Do not specify replacements, migrations, or
timelines — those decisions belong to the future maintainer.
See [`conventions.md` §4.1](docs/conventions.md#41-existence-predicate).
- **Content-named filenames.** No leading numbers; no dates in
filenames. Dates live inside artifacts.
See [`conventions.md` §8](docs/conventions.md#8-naming-and-cross-referencing).
- **No behavior paraphrase in comments.** If a comment is not an
existence-predicate, a local invariant, or a pointer to another
artifact, delete it.
See [`conventions.md` §4.4](docs/conventions.md#44-forbidden).
## Where decisions go
The repository does not maintain a per-feature document layer.
Decisions route as follows, with the test in the **trigger** column
deciding which destination applies:
| Trigger | Destination |
|---|---|
| Anything captured at the moment of *this* change — original ask, rejected alternatives, out-of-scope, premises assumed | Commit-message trailers ([`conventions.md` §5](docs/conventions.md#5-commits-and-prs)) |
| Work derives from outside engineering (product, customer, regulator, domain expert), and commits the system to a user-facing capability | Goal entry, in `docs/goals/<area>.md` ([`conventions.md` §2](docs/conventions.md#2-goals-docsgoals)) |
| Captures a cross-cutting rule across many code sites (technical convention or value-level principle) | ADR in `docs/adr/` ([`conventions.md` §1](docs/conventions.md#1-adrs-docsadr)) |
| Defines or refines a fact about the business the system models | Domain document in `docs/domain/` ([`conventions.md` §3](docs/conventions.md#3-domain-documents-docsdomain)) |
**Not every change has every destination.** Internal refactors, dev
tooling, dependency bumps, and engineering-initiated technical
decisions do not produce goal entries — only commit trailers (and
sometimes an ADR if the decision is cross-cutting). If content fits
none of these destinations, it likely duplicates code or paraphrases
tests. Do not write it.
## Continual doc-update awareness
When you make a change, look for what else might need updating, and
propose those changes proactively rather than letting them drift.
The directive's co-maintenance gradient depends on contributors
catching propagation needs at the moment of the change — silent
drift is itself a directive violation.
Specifically:
- **Adding or renaming a referenced file** → grep for inbound
references (other docs, code comments) and update them in the same
change.
- **Adding a goal that names a domain concept** → ensure the named
domain doc exists; if not, propose creating it (or fold the
concept into an existing domain doc).
- **Modifying an ADR** → grep for code/docs citing that ADR and
verify the citations still hold.
- **Adding code that realizes a goal** → the goal's `Realization:`
trailer should reference the new code path.
- **Adding a test that enforces a goal** → the goal's `Verified-by:`
trailer should reference the new test.
- **Modifying a domain definition** → check goals and ADRs that
reference the concept; confirm the definition change does not
invalidate any of them. If it does, those need updating too.
If you discover a propagation need you can't fulfill (e.g., the
authority for the related artifact is someone else), surface it
explicitly rather than paper over it.
## Subagent delegation
Some documentation operations benefit from delegation to a subagent
for context isolation; others must stay in the main agent because
they depend on the working memory of the session. The discriminator
is whether the work is *mechanical* (well-defined inputs and outputs,
no conversation context required) or *conversation-context-sensitive*
(needs the user's stated intent, verbatim turns, or the arc of the
session).
| Delegate to a subagent | Stay in the main agent |
|---|---|
| Prep-merge final documentation alignment check | Composing consolidated commit messages (Original-ask must be verbatim from this session) |
| Finding inbound references to a renamed file | Continual doc-update awareness during regular editing |
| Sweeping for a term across many files | Deciding chunk boundaries in prep-merge |
| Verifying worked examples match the format spec | Any sourcing-sensitive operation per [`principles.md` §5.1](docs/principles.md#51-sourcing-under-uncertainty) |
The pattern in one sentence: **delegate when the task is mechanical,
self-contained, and one-shot; keep in main when it depends on the
session's working memory or requires verbatim sourcing.**
When delegating: pass the subagent the file paths and rules it needs
to apply; ask for a structured report; surface the report to the
user without re-loading the per-file contents into the main agent's
context.
## Prep-merge procedure
The consolidated commits are the audit-grade record that survives the
PR. The conversation is raw material; the consolidated commits are the
editorial distillation. Every line of every commit message earns its
place.
When the user signals consolidation (e.g., "prep the merge",
"/prep-merge"), **prepare the branch for merge** — identify the
per-decision chunks, draft each commit message, run a final
documentation alignment check, execute the rebase, and force-push
(with user confirmation at each gate). Per
[`docs/conventions.md` §5](docs/conventions.md#5-commits-and-prs):
1. **Validate preconditions.** Refuse on dirty working tree, default
branch, or unpublished branch.
2. **Identify the chunks.** One decision is the common case. Multiple
decisions warrants a stop-and-confirm with the user (the user may
prefer to split the PR rather than merge it as multi-commit).
3. **Draft each commit's message** — title (imperative, one line),
body (what + why), and trailers per `docs/conventions.md` §5,
each only if it has material that earns the line:
- `Original-ask:` — verbatim quote of the load-bearing turn.
- `Considered-alternatives:` — each as `<alt>: rejected because <premise>`.
- `Out-of-scope:` — each as `<item>: out of scope because <premise>`.
- `Assumes:` / `Optimized-for:` / `Goal:` / `ADR:` / `Refs:` only
if load-bearing.
4. **Final documentation alignment check****delegated to a
subagent** for context isolation (see [Subagent delegation](#subagent-delegation)).
The subagent reads the conventions and the diff, then verifies:
- **Cross-reference integrity.** Every `docs/...md` path mentioned
in the staged diff resolves in the resulting tree. Paths inside
fenced code blocks are illustrative and skipped.
- **Trailer references resolve.** `ADR:`, `Goal:`, `Domain:`,
`Realization:`, `Verified-by:` paths point at actual files.
- **Co-maintenance check.** Goals named in the diff have their
domain dependencies present; ADRs cited by goals exist; code
paths cited in `Realization:` exist; test paths cited in
`Verified-by:` exist.
- **Orphan check.** If the diff renames a file, inbound references
to the old name were updated.
- **Trailer format.** `Original-ask:` followed by quoted (`>`)
lines; `Considered-alternatives:` and `Out-of-scope:` items in
`<X>: rejected/out-of-scope because <premise>` form.
The subagent returns a structured warning list; the main agent
surfaces it to the user. The user decides whether to fix-then-
continue or proceed despite warnings. No silent auto-fix.
5. **Present the plan** — chunks, messages, rebase plan, and the
merge-strategy implication (1 chunk allows any GitHub merge
strategy; N chunks must use rebase-merge or merge-commit, *not*
GitHub's "Squash and merge" which would re-collapse the chunks).
6. **Save a backup ref** (`refs/prep-merge/backup/<branch>-<ts>`)
before rewriting history.
7. **Execute the rebase**, show the result, and pause for review.
8. **Force-push only on explicit user approval**, using
`--force-with-lease`.
**Distill, do not transcribe.** A trailer that lists every passing
idea is noise. Each entry must earn its line by being audit-relevant.
**Ask, don't fabricate.** Per
[`principles.md` §5.1](docs/principles.md#51-sourcing-under-uncertainty),
sourcing under uncertainty is asked, not guessed. Specifically:
- Original-ask not quotable verbatim → ask.
- Rejected alternative without an articulated premise → ask what made
it rejected.
- Chunk decomposition unclear → ask the user where the boundaries are.
**Hard refusals.**
- Operating on the default branch (`master` / `main`).
- Force-pushing without explicit user approval.
- Multi-decision chunking without stop-and-confirm at step 2.
- Dirty working tree.
The `/dds-prep-merge` skill (provided by the `dds` package, not
committed to this repo) is the executable form of this procedure for
Claude Code, including the recovery protocol via the backup ref.
## When in doubt
`principles.md` is the authority on intent. If a request appears to
require present-tense description of how the system works, restate the
request in terms of the three permitted forms before producing output.
If a request requires authorial attribution you don't have, ask.
Silent drift between conventions and practice is itself a directive
violation — raise it explicitly rather than papering over it.