ADR-019: Template Scope Boundary
Status
Section titled “Status”Accepted
2026-06-11
Context
Section titled “Context”As a starter template developed with agents, the repo needs explicit boundaries on what an agent may change without asking. Without them, agents “improve” documentation, invent deployment infrastructure, or hand-edit generated code — all of which create noise and drift. Some directories are generated artefacts (internal/database/ from sqlc, *_templ.go from templ, AGENTS.md from the constitution) and must never be hand-edited.
Decision
Section titled “Decision”Define a scope table (canonical copy in .claude/workflow.md):
| Category | Paths | Rule |
|---|---|---|
| Modify freely | cmd/, internal/, web/, sql/, migrations/, build/config files, .github/workflows/, .windsurfrules | Full read/write |
| Read-only | docs/ | Don’t modify unless explicitly asked |
| Generated — never hand-edit | internal/database/*, internal/view/*_templ.go, AGENTS.md | Edit the source, then regenerate |
| Don’t create | Deployment infra, marketing content, maintenance scripts | Suggest adding to docs/ instead |
Amended 2026-07-05 by ADR-025 §6 (note added 2026-09-30): one worked-example deployment config,
fly.tomlat the repo root, is permitted despite the “Don’t create deployment infra” row (adr025-deploy-scopechecks there is exactly one). Two further clarifications recorded 2026-09-30: appending a graduation-log entry to an ADR’s Enforcement section when a check is promoted or demoted (ADR-033 §4) is the one standing exception to “docs/is read-only”; and the canonical table in.claude/workflow.mdlistsscripts/,checks/,CLAUDE.mdand.claude/under “Modify freely” and existing ADRs as “Append-only”.
Amended 2026-10-12 (#158; append-only per ADR-033): two changes to the canonical table in
.claude/workflow.md. (1) Adding a new ADR file underdocs/adr/with statusProposed, and its index row, is a standing exception to “docs/is read-only” — the Architect role (ADR-020) requires it and the guard already allowed it, but the table did not say so, which left an agent that needed an ADR no legal move. (2)CLAUDE.md,.claude/,checks/,scripts/adrcheck/andscripts/adrguard/move from “Modify freely” to a “Governed layer” row: editable, but never in order to make a change comply, and the PR names the ADR or note that authorises the edit. Evidence: the 2026-10 with/without-documents test of the sibling Astro starter, where the read-only rule halted a harmless feature in 6 of 6 runs and one run rewrote an ADR, a rule and a check to fit its change.
Consequences
Section titled “Consequences”- Agents stop touching
docs/and generated files uninvited; diffs stay reviewable. - Generated-file edits are caught (templ/sqlc/AGENTS.md regeneration is part of the workflow and the
task cigate). - The boundary is advisory to humans but enforced for agents via the constitution.
Alternatives Considered
Section titled “Alternatives Considered”- No explicit boundary. Rejected — observed agent scope creep into docs and generated files.
- Lock generated dirs via tooling only. Partial — CI drift checks help, but a stated rule prevents the wasted work upstream.
References
Section titled “References”- ADR-018, ADR-022
.claude/workflow.md- The forker-facing counterpart of this boundary — which pieces of the template are load-bearing vs. removable — lives in the README’s “What’s Load-Bearing vs. Removable” section (added 2026-07 with the ADR-024 demo).
Enforcement
Section titled “Enforcement”- Testable consequences:
- TC-1: Generated artefacts (
internal/database/*via sqlc,internal/view/*_templ.govia templ,AGENTS.md) are never hand-edited.
- TC-1: Generated artefacts (
- Checks:
- TC-1 → drift checks in
task ci(agents:check; build regeneration) (status: block, pre-existing) - TC-1 → PreToolUse guard (
scripts/adrguard) denies agent edits to these paths at write time (status: block, hook — see ADR-033)
- TC-1 → drift checks in
- Not machine-checkable: The “docs/ is read-only unless asked” and “don’t create deployment infra/marketing” rules require knowing what the operator asked for — agent-behavioural, enforced by review.
- Graduation log: (empty)
- Amendment 2026-10-12 (#165): TC-2 — a change to the governed layer (
CLAUDE.md,.claude/engineering.md,.claude/workflow.md,.claude/roles/,.claude/hooks/,.claude/settings.json,checks/,scripts/adrcheck/,scripts/adrguard/) is put in front of the reviewer →adr019-governed-layerinscripts/adrcheck(status: warn, added 2026-10-12), which lists every such file that differs from the merge base withorigin/master. This check does not graduate: it fires on every legitimate edit as well, because no machine can tell a rule changed for its own reason from one changed so that something else passes. It is a review flag; the reviewer confirms the PR names the authorising ADR note. Evidence: in the 2026-10 test of this repo (#162), with the documents removed, all eleven runs that renamed thecitask also rewrote the check guarding it, five of them with that check at block status and both hooks on; with the documents present, none renamed.