scaffold-agent-specs 0.1.6 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,38 +6,12 @@ A deliberately small, dependency-free CLI for **spec-driven agentic coding**. It
6
6
 
7
7
  Node.js 20 or newer and npm (for installation or `npx`). The scaffolded repository itself can use **any** programming language or framework.
8
8
 
9
- ## Use locally before publishing
10
-
11
- Download and extract this project, then run:
12
-
13
- ```sh
14
- cd scaffold-agent-specs
15
- npm test
16
- node bin/scaffold-agent-specs.js --help
17
-
18
- # Preview what will be created in any repo:
19
- node bin/scaffold-agent-specs.js init --dir /path/to/your/repo --dry-run
20
-
21
- # Actually initialize the repo:
22
- node bin/scaffold-agent-specs.js init --dir /path/to/your/repo
23
- ```
24
-
25
- Or use `npm link` from this package directory to install the development command into your PATH:
26
-
27
- ```sh
28
- npm link
29
- cd /path/to/your/repo
30
- scaffold-agent-specs init
31
- ```
32
-
33
- Unlink later with `npm unlink -g scaffold-agent-specs`.
34
-
35
- ## After publishing to npm
9
+ ## Usage
36
10
 
37
11
  From the root of any project:
38
12
 
39
13
  ```sh
40
- npx scaffold-agent-specs init
14
+ npx scaffold-agent-specs init --profile opinionated
41
15
  ```
42
16
 
43
17
  When the user and agent have discussed a feature and the user **explicitly accepts its scope**:
@@ -46,7 +20,7 @@ When the user and agent have discussed a feature and the user **explicitly accep
46
20
  npx scaffold-agent-specs feature "User statistics page" --approved
47
21
  ```
48
22
 
49
- This would create `docs/features/feature-001-user-statistics-page/` with these files:
23
+ This creates `docs/features/feature-001-user-statistics-page/` with these files:
50
24
 
51
25
  - `PLAN.md` for the approved scope, constraints, requirements and proposed approach.
52
26
  - `ACCEPTANCE_MATRIX.md` for objective acceptance criteria and verification evidence.
@@ -64,7 +38,19 @@ npx scaffold-agent-specs feature "Account dashboard" --approved --design --resea
64
38
 
65
39
  The `feature` command is a convenience for people. Agents are told to create feature directories by copying the templates themselves, following the steps in `docs/WORKFLOW.md`, so they don't depend on the CLI being installed or reachable from a sandbox.
66
40
 
67
- ## `init` installs
41
+ For a complete request-to-verification walkthrough with runnable code, see the [worked example](examples/feature-workflow/README.md).
42
+
43
+ ## Install profiles
44
+
45
+ Run `npx scaffold-agent-specs init` to choose interactively between **basic** (quality safeguards and existing project conventions) and **opinionated** (formal feature specs, approval gates, acceptance tracking, and milestone commits). Noninteractive installs default to basic. Select explicitly with `--profile basic` or `--profile opinionated`.
46
+
47
+ Basic installs `AGENTS.md` and the thin `CLAUDE.md` adapter. Opinionated installs the full scaffold below. Both record the selection in `.agent-specs/profile.json`; commit this file so updates preserve the profile. Older installations without this file retain opinionated behavior when their workflow or template directory exists.
48
+
49
+ Use `update --profile opinionated` or `update --profile basic` to switch. Released instructions are replaced, customized files are skipped, and `--dry-run` previews without changing the profile. Switching to basic leaves existing templates and feature documents in place; its instructions no longer require the formal workflow. Review skipped instructions when switching, since they can still describe the previous profile. `init` never switches an existing profile; use `update` instead.
50
+
51
+ The `feature` command requires the opinionated templates. Basic users can install them with `update --profile opinionated`.
52
+
53
+ ## Opinionated `init` installs
68
54
 
69
55
  ```text
70
56
  AGENTS.md
@@ -74,14 +60,18 @@ CLAUDE.md
74
60
  adr/ADR.md
75
61
  conventions/CONVENTION.md
76
62
  feature/{PLAN,ACCEPTANCE_MATRIX,TASKS,DESIGN,RESEARCH,HANDOFF}.md
77
- project/{ARCHITECTURE,GLOSSARY}.md
63
+ project/{ARCHITECTURE,GLOSSARY,VISUAL_DESIGN,TESTING,PRODUCT,DEPLOYMENT}.md
78
64
  docs/
79
65
  WORKFLOW.md
80
66
  adr/README.md
81
67
  features/README.md
82
68
  ```
83
69
 
84
- No speculative feature, ADR, architecture document, glossary, or convention document is created. Those appear only when needed. The templates in `.agent-specs/` are yours to edit; **the `feature` command reads your repository's copy**, including your customizations, not the package's default templates.
70
+ No speculative feature, ADR, architecture document, glossary, visual design reference, testing guide, product context, deployment guide, or convention document is created. Those appear only when needed. The templates in `.agent-specs/` are yours to edit; **the `feature` command reads your repository's copy**, including your customizations, not the package's default templates.
71
+
72
+ The workflow's [optional project document catalog](scaffold/docs/WORKFLOW.md#optional-project-document-catalog) lists creation triggers and ownership for architecture, glossary, visual design, testing, product context, deployment, conventions, and ADRs. Agents reuse adequate existing documentation and recommend missing shared references only when useful. `AGENTS.md` links to this catalog instead of maintaining a separate list.
73
+
74
+ For applicable features, release and recovery considerations live in `PLAN.md`, required checks and evidence in `ACCEPTANCE_MATRIX.md`, and release tasks in `TASKS.md`. Optional `docs/DEPLOYMENT.md` holds reusable rollout, migration, post-release verification, and recovery procedures when an existing publishing guide or runbook does not suffice. Implementation completion does not imply publication or deployment; required live checks must have evidence before the feature is marked complete.
85
75
 
86
76
  ## Commands and safety
87
77
 
@@ -100,7 +90,7 @@ No speculative feature, ADR, architecture document, glossary, or convention docu
100
90
  | `--dir PATH` | Work in a specified repository root instead of the current directory. |
101
91
  | `--help` / `--version` | Show help or the CLI version. |
102
92
 
103
- Feature IDs are allocated above the **largest existing** feature ID, starting at `001`. Running `init` again adds newly missing files but never replaces existing ones. `init` refuses to write through symlinked paths under the chosen root.
93
+ Feature IDs are allocated above the **largest existing** feature ID, starting at `001`. Feature creation uses a shared lock so concurrent commands cannot allocate the same ID. If another command holds the lock, retry after it finishes. After a crash, remove `docs/features/.agent-specs-feature.lock/` only after confirming no feature command is running. Dry runs do not reserve IDs. Running `init` again adds newly missing files but never replaces existing ones. `init` refuses to write through symlinked paths under the chosen root.
104
94
 
105
95
  ## Updating an existing repository
106
96
 
@@ -109,12 +99,22 @@ npx scaffold-agent-specs@latest update --dry-run # preview
109
99
  npx scaffold-agent-specs@latest update
110
100
  ```
111
101
 
112
- `update` compares each scaffold file in your repository with every released version of it. A file that still matches a released version is replaced with the current one, and a file that is missing is created. A file you have customized is skipped and reported, so you can merge the changes by hand or rerun with `--force`. Formatting-only differences (for example, Prettier padding tables) don't count as customizations. Feature documents in `docs/features/feature-*/` are never touched, so existing features keep the layout they were written with.
102
+ `update` compares each scaffold file in your repository with every released version of it. A file that still matches a released version is replaced with the current one, and a file that is missing is created. A file you have customized is skipped and reported, so you can merge the changes by hand or rerun with `--force`. Matching is exact: formatting changes also count as customizations, because whitespace and punctuation can affect meaning. Historical releases are recognized using hashes of their original contents; previously reformatted copies may need a manual merge. Feature documents in `docs/features/feature-*/` are never touched, so existing features keep the layout they were written with.
113
103
 
114
104
  There is intentionally no `implement` command: an agent should follow `AGENTS.md` and `docs/WORKFLOW.md` and wait for a separate implementation instruction. ADRs can be created from `.agent-specs/templates/adr/ADR.md` once architectural decisions are adopted.
115
105
 
116
106
  ## Develop
117
107
 
108
+ To run the CLI from a clone of this repository:
109
+
110
+ ```sh
111
+ npm test
112
+ node bin/scaffold-agent-specs.js --help
113
+ node bin/scaffold-agent-specs.js init --dir /path/to/your/repo --dry-run
114
+ ```
115
+
116
+ Or use `npm link` to put the development command on your PATH, and `npm unlink -g scaffold-agent-specs` to remove it later.
117
+
118
118
  ```sh
119
119
  npm test # Built-in Node.js test runner
120
120
  npm run format # Format scaffold Markdown with Prettier
@@ -123,7 +123,9 @@ npm run pack:check # Preview npm-published file manifest
123
123
  npm pack # Produce local npm tarball for testing
124
124
  ```
125
125
 
126
- For publication instructions, see [`PUBLISHING.md`](PUBLISHING.md).
126
+ For the release steps, see [`PUBLISHING.md`](PUBLISHING.md).
127
+
128
+ Pull requests run tests (including an actual npm tarball smoke test) and scaffold formatting checks on Node.js 20, 22, and 24. Publishing remains manual.
127
129
 
128
130
  ## License
129
131
 
@@ -2,7 +2,7 @@
2
2
  import { run } from '../lib/cli.js';
3
3
 
4
4
  try {
5
- run(process.argv.slice(2));
5
+ await run(process.argv.slice(2));
6
6
  } catch (error) {
7
7
  console.error(`Error: ${error.message}`);
8
8
  process.exitCode = 1;
@@ -0,0 +1,13 @@
1
+ # Repository Agent Instructions
2
+
3
+ These shared instructions apply to all coding agents. Follow existing project practices and the user's requested scope.
4
+
5
+ - Inspect relevant code, tests, and documentation before asking questions or proposing an approach.
6
+ - Prefer the smallest coherent change. Follow existing conventions and avoid unrelated refactors.
7
+ - Ask focused questions about consequential choices; choose sensible defaults for minor details. Keep the user in control of scope and significant architectural tradeoffs, and ask before materially expanding the requested work.
8
+ - Explain assumptions, uncertainty, incomplete work, and failed or unrun checks honestly.
9
+ - Follow existing UI conventions and design-system documentation when working on visual interfaces.
10
+ - Update affected documentation alongside code. Document consequential decisions where the project normally records them. Keep documentation concise and prefer an existing source of truth.
11
+ - Run relevant checks before claiming completion. Never claim unverified success. Report changes, verification evidence, and remaining limitations.
12
+ - Follow repository conventions and the user's instructions for Git workflow and commit messages. Keep commits focused; do not commit secrets, credentials, local environment files, or unrelated changes.
13
+ - Do not push, rewrite history, or change branches without the user's authorization.
package/lib/cli.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import fs from 'node:fs';
2
+ import { createInterface } from 'node:readline/promises';
2
3
  import { fileURLToPath } from 'node:url';
3
- import { initProject, createFeature, updateProject } from './scaffold.js';
4
+ import { initProject, createFeature, updateProject, projectProfile } from './scaffold.js';
4
5
 
5
6
  const help = `scaffold-agent-specs: spec-driven scaffolding for coding agents
6
7
 
7
8
  Usage:
8
- scaffold-agent-specs init [--dir PATH] [--dry-run]
9
- scaffold-agent-specs update [--dir PATH] [--dry-run] [--force]
9
+ scaffold-agent-specs init [--profile basic|opinionated] [--dir PATH] [--dry-run]
10
+ scaffold-agent-specs update [--profile basic|opinionated] [--dir PATH] [--dry-run] [--force]
10
11
  scaffold-agent-specs feature "Feature title" --approved [options]
11
12
  scaffold-agent-specs --version
12
13
  scaffold-agent-specs --help
@@ -19,6 +20,9 @@ Options for feature:
19
20
  --dry-run Preview without writing; approval not required for a preview
20
21
  --dir PATH Target repository root (default: current directory)
21
22
 
23
+ Profiles: init prompts in a terminal; otherwise defaults to basic.
24
+ Existing installations keep their profile. update --profile switches explicitly.
25
+
22
26
  Options for update:
23
27
  --dry-run Preview without writing
24
28
  --force Also overwrite files that were modified locally
@@ -31,7 +35,7 @@ still match a released version; locally modified files are skipped unless --forc
31
35
  Feature documents in docs/features/feature-*/ are never touched.
32
36
  `;
33
37
 
34
- export function run(args) {
38
+ export async function run(args) {
35
39
  if (!args.length || args.includes('--help') || args.includes('-h') || args[0] === 'help') {
36
40
  console.log(help);
37
41
  return;
@@ -47,6 +51,7 @@ export function run(args) {
47
51
  const flags = new Set();
48
52
  const positionals = [];
49
53
  let dir = process.cwd();
54
+ let profile;
50
55
  const allowed = new Set({
51
56
  init: ['--dry-run'],
52
57
  update: ['--dry-run', '--force'],
@@ -55,7 +60,11 @@ export function run(args) {
55
60
 
56
61
  for (let i = 0; i < rest.length; i++) {
57
62
  const argument = rest[i];
58
- if (argument === '--dir') {
63
+ if (argument === '--profile' || argument.startsWith('--profile=')) {
64
+ if (command === 'feature') throw new Error('--profile is only supported by init and update.');
65
+ profile = argument === '--profile' ? rest[++i] : argument.slice(10);
66
+ if (!['basic', 'opinionated'].includes(profile)) throw new Error('Profile must be basic or opinionated.');
67
+ } else if (argument === '--dir') {
59
68
  if (i + 1 >= rest.length || rest[i + 1].startsWith('--')) throw new Error('Missing path after --dir.');
60
69
  dir = rest[++i];
61
70
  } else if (argument.startsWith('--dir=')) {
@@ -71,12 +80,20 @@ export function run(args) {
71
80
  }
72
81
  if (command === 'init') {
73
82
  if (positionals.length) throw new Error('init takes no positional arguments.');
74
- initProject(dir, { dryRun: flags.has('--dry-run') });
83
+ if (!profile && !projectProfile(dir) && process.stdin.isTTY && process.stdout.isTTY) {
84
+ const prompt = createInterface({ input: process.stdin, output: process.stdout });
85
+ try {
86
+ const answer = (await prompt.question('Profile: basic (quality safeguards) or opinionated (formal specs, approval gates, milestone commits) [basic]: ')).trim();
87
+ profile = answer || 'basic';
88
+ if (!['basic', 'opinionated'].includes(profile)) throw new Error('Profile must be basic or opinionated.');
89
+ } finally { prompt.close(); }
90
+ }
91
+ initProject(dir, { profile, dryRun: flags.has('--dry-run') });
75
92
  return;
76
93
  }
77
94
  if (command === 'update') {
78
95
  if (positionals.length) throw new Error('update takes no positional arguments.');
79
- updateProject(dir, { dryRun: flags.has('--dry-run'), force: flags.has('--force') });
96
+ updateProject(dir, { profile, dryRun: flags.has('--dry-run'), force: flags.has('--force') });
80
97
  return;
81
98
  }
82
99
  if (!positionals.length) throw new Error('Missing feature title. Try `feature "User statistics page" --approved`.');
@@ -1,63 +1,97 @@
1
1
  {
2
2
  ".agent-specs/templates/adr/ADR.md": [
3
- "6bdd5aa7149e0e3a53ddf1ff3fc067c3797e0c9942844cbb00b34c228204183c"
3
+ "230b94a66fdd41f3bbc7349e3a2c072075771bf5d93ad3acb8701ad560509704",
4
+ "231c494ae7e43641797692e3d2869eaba9ad9a72320e7da5d63ce6c000fea061"
4
5
  ],
5
6
  ".agent-specs/templates/conventions/CONVENTION.md": [
6
- "462a9cbf6c502f6692c9813a2da02e796a3547d02fb58058e2153bf4e3dc91d3",
7
- "636e0b91189004f35c12da1d31bca6a26d5b6e6460547ac7b052f6dcfe4122c8",
8
- "6f048a218b8fa094fe8d12ee1978d0600849db4d8142ca56502e986b5af7dfaa"
7
+ "0100029996755bf1f1cdf34e0d064807ee923256c5c84b0a98787fc067aae8a7",
8
+ "553894159720e718cb0a6938b758d65f9f55c7df3f8ccb969d632981c000cfad",
9
+ "66e57d4c939f9beeb596cc7094ede6436ec9d4096888196a6d8498474f8df445"
9
10
  ],
10
11
  ".agent-specs/templates/feature/ACCEPTANCE_MATRIX.md": [
11
- "0efef77a6c06737d224289611ab9cd7640a987395bcb526fff4f4b5f86295753"
12
+ "2c4ced9eefb608d9dac68708a760b4425bafccb287dfd3701d16d4f416afa7a8",
13
+ "418ad2f5d8693d63d436e77b61d09a335919cbe7caad702c62e330cbfcc8bc2e",
14
+ "13465e7579dee1327232b4d2ca468b4c2dae7e988764a0149f9dfeb9febfa39f",
15
+ "38bf94015959e497a19487e25ba7165ec7dc8d984c38c3bf3e30628f80064432"
12
16
  ],
13
17
  ".agent-specs/templates/feature/DESIGN.md": [
14
- "301b5b38817a3fa1f21d7ac1f9816f5edc294610322e82bbaf51898485a00934"
18
+ "67ab041fede40d545a8a1e39866648e0fbbea0dfcc754082e6484d90d4e9780d",
19
+ "6dd83ff2274e66b2d314d25f11aec77e05914b09a7df29ff8f36f38bead20e42",
20
+ "95b7b6f8930df17fba720217bbdfa49e4fbb130c2f26eed7628b80ed4e7b879c"
15
21
  ],
16
22
  ".agent-specs/templates/feature/HANDOFF.md": [
17
- "5d089e10cd26341154f71262f1f7bbaf851ef42bdea73bf26a2c80cc647cc9dc"
23
+ "cd0531eec14496409f94b087ceb27d269dfb8feb8e9321b8075ed2ec15148794"
18
24
  ],
19
25
  ".agent-specs/templates/feature/PLAN.md": [
20
- "8502cc0a36a3868f8f255863db7abd58b9626ae0b9a9c76875aa77441a0cac2c",
21
- "e23d02f2b21676dcc9493eee8b2ec617b922a912e118762d6afe191ac391f826"
26
+ "41f8adea2769c825a4e50b82ab1c7f20249923fd8fd0cdb2f91a3c45626cd723",
27
+ "66e60c4ac70c18ff549a57691b73113dc0f015fcfefcbad537a20fe1213f3702",
28
+ "08bfa77df5a28778ea6ab9d8c44858c3fe37f6beb2719f38f30cfc314f80f147",
29
+ "23ee3da377f7f99718bfc846fa7e37e5b9470bbbf0f3ec08359d4a53756428dc"
22
30
  ],
23
31
  ".agent-specs/templates/feature/RESEARCH.md": [
24
- "e68f104f0b35440da933573d7f04a861f62a8f8248a3156b975824d2cac40c53"
32
+ "667580dd935face184e8f8a8177a092bf8d146a9e60c9396fddbae2b64c9cb40",
33
+ "709450b00f6c0c0c25a78eccf4ecf2ac1a45a38951157d57eba5d3f63bcba9c5"
25
34
  ],
26
35
  ".agent-specs/templates/feature/TASKS.md": [
27
- "0b6f660cb321bdbbeecd21af788e3954a01726bf111f079707fd927451ef49e7",
28
- "a4c5de105bb6d474e2131994cb90fbcd4f3e436ba22b92a0f865755d00064d0d"
36
+ "aa8494ff4e045f8ab65f360654b0f2f4036c744dd72caa720e14436d48626fde",
37
+ "bed26521049b15acfbd80ebe226873d75c604f9d0c88238a3ecabb8a9dd73cac"
29
38
  ],
30
39
  ".agent-specs/templates/project/ARCHITECTURE.md": [
31
- "3ed1a7ae1021f999fa7769f406f7de5e008d9f8c09e219214c817f580a1d9ae5"
40
+ "d4b2e5ed4449b70746b3dfd628e111edffbb69d7247267cab86e6d48c506943d",
41
+ "fa96b3a94003604b02c8ffdc617ab810b6c96b5df2b647f5b46ec53c35a4a1d3"
42
+ ],
43
+ ".agent-specs/templates/project/DEPLOYMENT.md": [
44
+ "0b2b7a20d49f096a1a9dc3b22f1796de2321cc13b016322b253a33e396458e7b"
32
45
  ],
33
46
  ".agent-specs/templates/project/GLOSSARY.md": [
34
- "5f9109b0699879db0b6563e9df4889c3b0963893c43a1fd82a71f5f3d7327af9"
47
+ "7c70e97600adefb95611c1ba6f675291a5632bcb9e2e866cecc3267d7bc81bad",
48
+ "f84785fd38fb580ed923c212c1a803b9f4abedd1c799dc091fa1d4e854486d51"
49
+ ],
50
+ ".agent-specs/templates/project/PRODUCT.md": [
51
+ "551c8e3b48e4abe29dcac80dd7217674be01570d30de5b5603b71bcc6814b2e3"
52
+ ],
53
+ ".agent-specs/templates/project/TESTING.md": [
54
+ "7771a95ed6808dc14a06f422e17cb0bb87679cb2e60c67cb4bfbe4c6e552e72c"
55
+ ],
56
+ ".agent-specs/templates/project/VISUAL_DESIGN.md": [
57
+ "03b0ad8ab6d435f0de17585fd06d12d7f72eb27ca70281fb97c5d672a0e6210c"
35
58
  ],
36
59
  "AGENTS.md": [
37
- "70196e937a5782962f69c2c0735929059fac6c60b724977ebbfea9d0e4c84b20",
38
- "c08f3412d558b6992b0a2e003d5be0de201502846453c2b2da70c2d682d5815a",
39
- "bc70d6dee9f3f76affb0636ff804a112885b0973aaa2753ac970fc83d0260b5e",
40
- "a09404a3dce7e2c1f7aa0efce59c5b075943ad768a02b62dc51e08e44a050318",
41
- "53776f37c6f55ece45c4b4d32d2a48749031c90e77047d9a730c3f150af0d79f",
42
- "3753a29898a4209208fdbb8f1e9a3de206d845d95e60d8c543f48c2c239780bf"
60
+ "0eab3a77a396a41ea82ec3c2a6c459bffbeac5d4277342edb137d2c48a691412",
61
+ "18693b6856d66ab7ee2f035a5555d3311b8f3cf23a68ebe6af8cef0ddf03d557",
62
+ "3d56b1c3d2706168e23701cbf1fd914c59aa5ef5a53a455e95d5c8551e80aa59",
63
+ "7e7b110327268ab0e374bbee1cf115f1afb5541aaea447cbe28227121cd3a89e",
64
+ "ab68bb3e1415ce764e45debc529a7a87296e1164974f7873db45f1be44dcd81f",
65
+ "cc14da014a959578f7e28970f5168401dd653f97b16b3a81055c549a07c09c9c",
66
+ "cd231a977a879afa19301947a03f2ffb246240bc127fb00b7fedd516231936bc",
67
+ "d527b953d0f1d6fd805e9800ba4ba71db2e5e1c25dcdfe4bdbfc6706e1782314",
68
+ "f730107d9764f5a0a294124e04c9a5c89ecda9e6f3365afc9b0ca4a952dec1d1",
69
+ "9c8d3e7eb471911d0ca58bfd0331298effcee068f28b71f52373c05641c3bc93",
70
+ "94a8b845546e7f7564cac89ee73cdcb24ac4d54989c7a9f6c676e7e8066c64cd"
43
71
  ],
44
72
  "CLAUDE.md": [
45
- "272bcb5a9f136af56c1c93203c21976e02a09ed0a59d2515fad23d24b6c34408"
73
+ "67de3db5b7413656ff1d221df90360fdfd0dd80608eb5dbae0416fecf359cbf8",
74
+ "e1bfd28d839af2ff6ec82759d888081a7c3fa2da2c20dbcfb144f533e0e3f982"
46
75
  ],
47
76
  "docs/WORKFLOW.md": [
48
- "0712abf011e6632fcdaee95c9b0c7bcad39808b5d28678c25aa0c05d281f795f",
49
- "637e83ce425e97ee9751a8500f5928d1f1ed2536e8d1a02b85bf6e11bc937192",
50
- "9dd7762484311d7a2a59620d4e89c61e4eb68688d9ebe1b3e2f2ac6d114373fd",
51
- "049b5a682f613a0bb2dab7bd39e79645860eb30202d358ed9a879dbe238e84bc",
52
- "8f66846159f0f049af2035fd71be7b289cc999099ad2ac6c1aa3b61745754745",
53
- "4e12aed278f410305dc640a9f9cb0fa5135e28b0963c2a9bc4a8b7810e4af63f"
77
+ "5a3595c9db922174f09983d691154b541b2974040e67bc97edfc6ccc7011ab9f",
78
+ "962d11a5e74312a28d3d3fb4c048f259108ea15cd9da9d2bbaf4a010a982b4ac",
79
+ "982ddc5918cd15fe945c32d32e16bd98f6d33ce836fba2e009e284e4b800834b",
80
+ "c80b35e94103071e51712155a3e343271a6599c62b655c821aca95c55218da4f",
81
+ "e737237b908dc482b01f07d69cc9c885216f5268a199863ab56203347af17564",
82
+ "ee6a539425172b2efc0477cbf2cf2b07fa0f5cc79d0b06a794e75922101b2961",
83
+ "ee972b6193146aef80b85fbb76a5289d651173032daa14fc5fe3744c3d36a930",
84
+ "6ae499a00796e17367c1c25bd5f162b040622aa1bcc4f0d39ba5efc8817bfbd3",
85
+ "59708748d05e26859c71eb9beab4f27b1e9dcded7bc4648d04bb35033b853022",
86
+ "70de8d1dc3a24c3bc293a696ad2b150c6d9dced69d0a5d03f54f3f7e275bfa33",
87
+ "05dd5854cb7a287ad2d39119c4f10b647415d2a6b01be0d7c6fe8427a012590c"
54
88
  ],
55
89
  "docs/adr/README.md": [
56
- "2f27a4a5ecfb92725875c0b859194588b0ed367ac87b7d321ba063062abf25d5"
90
+ "1d2c05c11246d0d45592f930b3a339bf454363875b968f650165e91a906c95af"
57
91
  ],
58
92
  "docs/features/README.md": [
59
- "a46ffb46dc49d5304db438179e6b090665d706d2f09c50c56bb2a0c09c92b5da",
60
- "3fb7c6fa1177a5cb940e8066d18624ce0d32c76b945a9b1f183d8809f40a7275",
61
- "ddf40d2b1fd1fb821799e59df15c4ab9ce9edf1e231b3fce5776ff3635c3ffaf"
93
+ "5b995d3af23bbb7eb44fc146690ded522a410deb7d54401b7fd3b8fc4f62c5a2",
94
+ "c871bd8bc6152615851bc2103429c699ba11f8da3cd8c167edc8510204b72bfe",
95
+ "ce489254e2001ad7a5f85ce23474e9e4765dfc6fcf6a43f780e425f2bdab86a5"
62
96
  ]
63
97
  }
package/lib/scaffold.js CHANGED
@@ -54,10 +54,45 @@ function getBundledFiles(dir, base = dir) {
54
54
  }).sort();
55
55
  }
56
56
 
57
- export function initProject(target, { dryRun = false, log = console.log } = {}) {
57
+ const profileFile = '.agent-specs/profile.json';
58
+ export function projectProfile(target) {
59
+ const root = path.resolve(target);
60
+ const file = path.join(root, profileFile);
61
+ assertSafePath(root, file);
62
+ if (pathExists(file)) {
63
+ const { profile } = JSON.parse(fs.readFileSync(file, 'utf8'));
64
+ validateProfile(profile);
65
+ return profile;
66
+ }
67
+ return fs.existsSync(path.join(root, 'docs/WORKFLOW.md')) || fs.existsSync(path.join(root, '.agent-specs/templates')) ? 'opinionated' : undefined;
68
+ }
69
+ function validateProfile(profile) {
70
+ if (!['basic', 'opinionated'].includes(profile)) throw new Error('Profile must be basic or opinionated.');
71
+ }
72
+ function profileFiles(profile) {
73
+ validateProfile(profile);
74
+ return profile === 'basic' ? ['AGENTS.md', 'CLAUDE.md'] : getBundledFiles(bundledScaffold);
75
+ }
76
+ function profileContent(rel, profile) {
77
+ if (profile === 'basic' && rel === 'AGENTS.md') return fs.readFileSync(new URL('./basic-AGENTS.md', import.meta.url), 'utf8');
78
+ return fs.readFileSync(path.join(bundledScaffold, rel), 'utf8');
79
+ }
80
+ function saveProfile(root, profile, dryRun) {
81
+ if (!dryRun) {
82
+ fs.mkdirSync(path.join(root, '.agent-specs'), { recursive: true });
83
+ fs.writeFileSync(path.join(root, profileFile), JSON.stringify({ profile }, null, 2) + '\n');
84
+ }
85
+ }
86
+
87
+ export function initProject(target, { dryRun = false, profile, log = console.log } = {}) {
58
88
  const root = path.resolve(target);
59
89
  assertDirectory(root);
60
- const files = getBundledFiles(bundledScaffold);
90
+ const existing = projectProfile(root);
91
+ profile ??= existing ?? 'basic';
92
+ validateProfile(profile);
93
+ if (existing && existing !== profile) throw new Error('Use update --profile to switch an existing installation.');
94
+ assertSafePath(root, path.join(root, profileFile));
95
+ const files = profileFiles(profile);
61
96
  const created = [];
62
97
  const skipped = [];
63
98
 
@@ -76,21 +111,21 @@ export function initProject(target, { dryRun = false, log = console.log } = {})
76
111
  if (!dryRun) {
77
112
  fs.mkdirSync(path.dirname(destination), { recursive: true });
78
113
  // Atomic no-clobber creation; existing work must never be overwritten.
79
- fs.copyFileSync(path.join(bundledScaffold, rel), destination, fs.constants.COPYFILE_EXCL);
114
+ fs.writeFileSync(destination, profileContent(rel, profile), { flag: 'wx' });
80
115
  }
81
116
  created.push(rel);
82
117
  log(`${dryRun ? 'would create' : 'create'} ${rel}`);
83
118
  }
84
119
 
120
+ saveProfile(root, profile, dryRun);
121
+ log(`Profile: ${profile}`);
85
122
  log(`${dryRun ? 'Preview:' : 'Initialized:'} ${created.length} ${dryRun ? 'to create' : 'created'}, ${skipped.length} skipped.`);
86
123
  return { created, skipped };
87
124
  }
88
125
 
89
- // Identifies a file's content regardless of formatting, so a released file that a
90
- // formatter such as Prettier has rewritten (padding, emphasis markers) still matches.
126
+ // Only exact released contents are safe to replace. Formatting can change meaning.
91
127
  export function fingerprint(content) {
92
- const normalized = content.replace(/[\s*_-]/g, '');
93
- return crypto.createHash('sha256').update(normalized).digest('hex');
128
+ return crypto.createHash('sha256').update(content).digest('hex');
94
129
  }
95
130
 
96
131
  export function getBundledFingerprints() {
@@ -100,18 +135,20 @@ export function getBundledFingerprints() {
100
135
  ]));
101
136
  }
102
137
 
103
- export function updateProject(target, { dryRun = false, force = false, log = console.log } = {}) {
138
+ export function updateProject(target, { dryRun = false, force = false, profile, log = console.log } = {}) {
104
139
  const root = path.resolve(target);
105
140
  assertDirectory(root);
106
141
  const released = JSON.parse(fs.readFileSync(releasedFingerprintsFile, 'utf8'));
107
- const files = getBundledFiles(bundledScaffold);
142
+ profile ??= projectProfile(root) ?? 'opinionated';
143
+ assertSafePath(root, path.join(root, profileFile));
144
+ const files = profileFiles(profile);
108
145
  const plan = [];
109
146
 
110
147
  // Decide every action before writing anything.
111
148
  for (const rel of files) {
112
149
  const destination = path.join(root, rel);
113
150
  assertSafePath(root, destination);
114
- const incoming = fs.readFileSync(path.join(bundledScaffold, rel), 'utf8');
151
+ const incoming = profileContent(rel, profile);
115
152
  if (!pathExists(destination)) {
116
153
  plan.push({ rel, action: 'create', incoming });
117
154
  continue;
@@ -144,6 +181,8 @@ export function updateProject(target, { dryRun = false, force = false, log = con
144
181
  log(`${labels[action]} ${rel}${action === 'overwrite' ? ' (local changes discarded)' : ''}`);
145
182
  }
146
183
 
184
+ saveProfile(root, profile, dryRun);
185
+ log(`Profile: ${profile}`);
147
186
  const count = (...actions) => plan.filter((item) => actions.includes(item.action)).length;
148
187
  const modified = plan.filter((item) => item.action === 'modified').map((item) => item.rel);
149
188
  log(`${dryRun ? 'Preview:' : 'Updated:'} ${count('update', 'overwrite')} ${dryRun ? 'to update' : 'updated'}, ${count('create')} ${dryRun ? 'to create' : 'created'}, ${count('current')} already current, ${modified.length} skipped.`);
@@ -205,7 +244,7 @@ export function createFeature(target, title, {
205
244
  ))];
206
245
  // Ensure initialization and templates exist before changing the repository.
207
246
  if (!fs.existsSync(featuresDir) || !fs.statSync(featuresDir).isDirectory()) {
208
- throw new Error('docs/features/ is missing. Run `scaffold-agent-specs init` first.');
247
+ throw new Error('docs/features/ is missing. Run `scaffold-agent-specs update --profile opinionated` first.');
209
248
  }
210
249
  for (const filename of files) {
211
250
  const template = path.join(templateDir, filename);
@@ -214,32 +253,49 @@ export function createFeature(target, title, {
214
253
  throw new Error(`Feature template missing: ${path.relative(root, template)}. Run init or restore the template.`);
215
254
  }
216
255
  }
217
- const number = nextFeatureNumber(featuresDir);
218
- const id = String(number).padStart(3, '0');
219
- const name = `feature-${id}-${slug}`;
220
- const featureDir = path.join(featuresDir, name);
221
- assertSafePath(root, featureDir);
222
- if (pathExists(featureDir)) throw new Error(`Feature directory already exists: ${featureDir}`);
223
- const date = localDate();
224
- const created = files.map((file) => path.join('docs', 'features', name, file));
256
+ // Serialize allocation across all titles, not just identical directory names.
257
+ const lock = path.join(featuresDir, '.agent-specs-feature.lock');
258
+ assertSafePath(root, lock);
225
259
  if (!dryRun) {
226
- // Exclusive mkdir prevents two concurrent calls from sharing the same feature ID.
227
- fs.mkdirSync(featureDir);
228
260
  try {
229
- for (const file of files) {
230
- const content = fs.readFileSync(path.join(templateDir, file), 'utf8');
231
- fs.writeFileSync(path.join(featureDir, file), fillFeatureTemplate(content, { title: title.trim(), id, slug, date }), { flag: 'wx' });
232
- }
261
+ fs.mkdirSync(lock);
233
262
  } catch (error) {
234
- // A failed scaffold must not leave a half-created feature.
235
- fs.rmSync(featureDir, { recursive: true, force: true });
263
+ if (error.code === 'EEXIST') {
264
+ throw new Error(`Feature creation is locked: ${lock}. Retry after the other command finishes. If it crashed, remove this lock directory only after confirming no feature command is running.`);
265
+ }
236
266
  throw error;
237
267
  }
238
268
  }
239
- for (const file of created) log(`${dryRun ? 'would create' : 'create'} ${file}`);
240
- log(`${dryRun ? 'Preview:' : 'Scaffolded:'} ${name} (${files.length} file${files.length === 1 ? '' : 's'}).`);
241
- if (!dryRun) {
242
- log('Next: fill the files with the approved feature scope, then stop before implementation.');
269
+ try {
270
+ const number = nextFeatureNumber(featuresDir);
271
+ const id = String(number).padStart(3, '0');
272
+ const name = `feature-${id}-${slug}`;
273
+ const featureDir = path.join(featuresDir, name);
274
+ assertSafePath(root, featureDir);
275
+ if (pathExists(featureDir)) throw new Error(`Feature directory already exists: ${featureDir}`);
276
+ const date = localDate();
277
+ const created = files.map((file) => path.join('docs', 'features', name, file));
278
+ if (!dryRun) {
279
+ // Exclusive mkdir also protects against an existing destination.
280
+ fs.mkdirSync(featureDir);
281
+ try {
282
+ for (const file of files) {
283
+ const content = fs.readFileSync(path.join(templateDir, file), 'utf8');
284
+ fs.writeFileSync(path.join(featureDir, file), fillFeatureTemplate(content, { title: title.trim(), id, slug, date }), { flag: 'wx' });
285
+ }
286
+ } catch (error) {
287
+ // A failed scaffold must not leave a half-created feature.
288
+ fs.rmSync(featureDir, { recursive: true, force: true });
289
+ throw error;
290
+ }
291
+ }
292
+ for (const file of created) log(`${dryRun ? 'would create' : 'create'} ${file}`);
293
+ log(`${dryRun ? 'Preview:' : 'Scaffolded:'} ${name} (${files.length} file${files.length === 1 ? '' : 's'}).`);
294
+ if (!dryRun) {
295
+ log('Next: fill the files with the approved feature scope, then stop before implementation.');
296
+ }
297
+ return { featureDir, created };
298
+ } finally {
299
+ if (!dryRun) fs.rmdirSync(lock);
243
300
  }
244
- return { featureDir, created };
245
301
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scaffold-agent-specs",
3
- "version": "0.1.6",
3
+ "version": "0.2.0",
4
4
  "description": "A tiny, spec-driven workflow scaffold for AI coding agents",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -5,6 +5,8 @@
5
5
 
6
6
  Each row must specify **observable behavior**, a verification method, and actual evidence. Write criteria when specifying the feature; update result and evidence during implementation. Do not mark `Pass` based solely on code inspection or optimism.
7
7
 
8
+ When release or recovery checks are part of the approved scope, include rows for the relevant rollout, migration, post-release behavior, and recovery outcomes. Record the version, environment, command or observation, and evidence link. Passing local tests does not establish production success or recoverability. Required checks awaiting release stay `Not run` or `Blocked`; checks explicitly outside this feature's scope belong in the plan's release handoff, not in invented passing rows.
9
+
8
10
  | ID | Requirement | Scenario / expected outcome | Verification method | Result | Evidence |
9
11
  | ------ | ----------- | ------------------------------------------------ | ------------------------------- | ------- | ---------------------------- |
10
12
  | AC-001 | FR-001 | [Given/when/then or clear expected result] | [Test name or manual procedure] | Not run | [Add evidence when verified] |
@@ -19,6 +21,8 @@ Each row must specify **observable behavior**, a verification method, and actual
19
21
 
20
22
  If the user approves changing or waiving a criterion, update the approved scope in `PLAN.md` and document that decision explicitly. Do not silently convert a failing criterion into a pass.
21
23
 
24
+ If a later feature supersedes this behavior, preserve these criteria, results, and evidence as historical records. Add a dated note under verification notes identifying the affected IDs and linking to the replacement feature's plan and acceptance matrix. A historical `Pass` does not verify the replacement; its matrix must record fresh evidence. See the supersession rules in `docs/WORKFLOW.md`.
25
+
22
26
  ## Verification notes
23
27
 
24
28
  [Commands, test environment, observations, limitations, and links to test reports. Leave as 'Not yet verified' during initial specification.]
@@ -37,4 +37,5 @@
37
37
 
38
38
  - Approved scope: [`PLAN.md`](./PLAN.md)
39
39
  - Requirements and checks: [`ACCEPTANCE_MATRIX.md`](./ACCEPTANCE_MATRIX.md)
40
+ - [Shared visual design reference, if relevant; link to existing design-system documentation or `docs/VISUAL_DESIGN.md` rather than repeating shared rules]
40
41
  - [Any relevant convention, architecture documentation, or adopted ADR]
@@ -47,6 +47,12 @@
47
47
 
48
48
  - [Dependency, prerequisite, migration risk, or 'None identified']
49
49
 
50
+ ## Release and recovery (when applicable)
51
+
52
+ [Omit this section when there are no feature-specific release considerations. Otherwise link to the existing deployment/publishing guide and record only this feature's rollout order, compatibility constraints, data migrations, and recovery considerations. Identify irreversible steps, rollback limits, and the supported recovery or forward-fix approach; do not assume reverting code restores data.]
53
+
54
+ [Define observable post-release checks and stop/recovery conditions. State whether release execution and live verification are in the approved scope or a later handoff. Map required checks to acceptance IDs and release work to tasks. Record prerequisites, authorization needed, and who owns deferred work; do not invent approvals or claim untested recovery works.]
55
+
50
56
  ## Assumptions and open questions
51
57
 
52
58
  - [Question or assumption; mark **Blocking** when implementation cannot responsibly proceed without an answer]
@@ -57,6 +63,12 @@
57
63
  | ------------ | ---------------------- | -------------------------------------------- |
58
64
  | [YYYY-MM-DD] | Initial approved scope | [Explicit approval reference / conversation] |
59
65
 
66
+ ## Related and superseded features
67
+
68
+ [State 'None' if unrelated to earlier features. Otherwise link the relevant feature plans and identify the affected requirement and acceptance IDs, the behavior being replaced or extended, and what remains unchanged. Qualify IDs with their feature because IDs are local to each feature. Distinguish planned replacement from implemented supersession; approval alone does not replace existing behavior.]
69
+
70
+ [When replacement is implemented, record its date and implementation reference here and add a reciprocal note to the earlier plan. Preserve the earlier scope and verification history; follow the supersession rules in docs/WORKFLOW.md.]
71
+
60
72
  ## References
61
73
 
62
74
  - Acceptance criteria: [`ACCEPTANCE_MATRIX.md`](./ACCEPTANCE_MATRIX.md)
@@ -0,0 +1,27 @@
1
+ # Release and Recovery Guide
2
+
3
+ > **Optional project document.** Create under `docs/DEPLOYMENT.md` when recurring release, deployment, or recovery procedures need explanation beyond existing scripts, CI, publishing instructions, or runbooks. Reuse an adequate existing guide. Describe actual supported procedures and link to authoritative automation; do not invent infrastructure or claim untested recovery works. Omit irrelevant sections. Feature-specific rollout choices belong in the feature plan, and execution evidence belongs in its acceptance matrix or an existing release record.
4
+
5
+ ## Release targets and prerequisites
6
+
7
+ [What is released or deployed, to which environments or registries, and from which artifact/version. Link to build and release automation. Identify prerequisites, required access, and who can authorize execution; do not include credentials. Documentation or feature approval alone does not authorize a deployment, publication, or production data change.]
8
+
9
+ ## Rollout procedure and compatibility
10
+
11
+ [The supported sequence, commands or automation links, and checkpoints. Explain component ordering, version compatibility, feature flags, staged exposure, or downtime only where applicable. Identify stop conditions and how to determine which version is actually active.]
12
+
13
+ ## Data changes and migration
14
+
15
+ [Migration ordering, compatibility with old and new application versions, backup requirements, and any irreversible steps. State 'Not applicable' if no persistent data is involved. Link to authoritative migration and restore procedures instead of copying them.]
16
+
17
+ ## Post-release verification
18
+
19
+ [Observable smoke checks, health signals, logs or metrics, and their success/failure conditions. Identify when checks run and who follows up. Distinguish a successful build or deployment command from evidence that the released behavior works.]
20
+
21
+ ## Rollback and recovery
22
+
23
+ [When to stop rollout or recover, who decides, the known-good artifact/configuration, and the supported procedure. Explain what reverting code does not undo, including data changes. If rollback is unavailable or unsafe, state that explicitly and describe the supported forward fix or recovery path and its limitations. Record where recovery was rehearsed and link to evidence, or label it unverified.]
24
+
25
+ ## Evidence and maintenance
26
+
27
+ [Link to existing release/deployment records and recovery evidence. Record the version, environment, time, check results, and unresolved issues when executing a release. Keep reusable procedures here and feature-specific evidence in its acceptance matrix or linked release record. Update this guide when release automation, compatibility assumptions, or recovery procedures change.]
@@ -0,0 +1,27 @@
1
+ # Product Context
2
+
3
+ > **Optional project document.** Create under `docs/PRODUCT.md` when shared product context is not adequately explained by the README or existing product documentation. Reuse and link authoritative material instead of maintaining competing descriptions. Capture agreed context and current capabilities; do not invent product strategy or turn this document into a roadmap, backlog, or feature approval mechanism. Omit irrelevant sections.
4
+
5
+ ## Purpose and users
6
+
7
+ [What problem the product solves, for whom, and in what setting. Distinguish primary users from other stakeholders where useful.]
8
+
9
+ ## Core journeys
10
+
11
+ [The main outcomes users can achieve today and the important steps or boundaries of each journey. Link to current user documentation and relevant feature plans rather than copying detailed requirements.]
12
+
13
+ ## Product principles and constraints
14
+
15
+ [Agreed principles that guide product tradeoffs, with their rationale and sources. Include enduring constraints only when established; do not infer commitments from a single implementation choice.]
16
+
17
+ ## Deliberate non-goals
18
+
19
+ [Explicitly agreed exclusions and the reasons for them. Distinguish deliberate boundaries from capabilities that simply have not been built. Changes to these boundaries require scope discussion, not an unannounced documentation edit.]
20
+
21
+ ## Uncertainty and references
22
+
23
+ [Identify unresolved questions as unresolved. Link to authoritative product material, user documentation, the glossary, and relevant decisions. Do not present assumptions or proposals as agreed context.]
24
+
25
+ ## Maintenance
26
+
27
+ Update this reference when approved product direction or implemented core journeys change. Distinguish approved future direction from available behavior. Feature scope and approval remain in each feature's `PLAN.md`, progress in `TASKS.md`, and verification evidence in `ACCEPTANCE_MATRIX.md`.
@@ -0,0 +1,31 @@
1
+ # Project Testing Guide
2
+
3
+ > **Optional project document.** Create under `docs/TESTING.md` when verification setup or test selection needs explanation beyond existing scripts, CI, README, or contributing documentation. Reuse an existing guide when it already serves this purpose. Document the project's actual approach, not a hypothetical test strategy. Link to authoritative scripts and configuration rather than copying their implementation. Omit irrelevant sections.
4
+
5
+ ## Choosing checks
6
+
7
+ | Change or risk | Relevant checks and command | Authoritative script / configuration |
8
+ | ---------------- | ------------------------------------- | -------------------------------------- |
9
+ | [Type of change] | [Checks to run and working directory] | [Link to maintained command or CI job] |
10
+
11
+ [Explain when focused checks suffice and when integration, end-to-end, build, or other checks are needed. Identify differences between local and CI verification. Do not prescribe new tooling without an agreed need.]
12
+
13
+ ## Setup and test data
14
+
15
+ [Required runtimes, services, environment variable names, fixtures, seed data, and setup/cleanup procedures. Link to existing setup documentation. Describe how to obtain authorized test credentials without including secrets. Identify commands that modify data and the isolated test environment they require.]
16
+
17
+ ## Integration boundaries
18
+
19
+ [Which checks use real services and which use substitutes, why those boundaries exist, and what a passing substituted test does not establish.]
20
+
21
+ ## Manual verification
22
+
23
+ [Reproducible checks that automation does not cover, prerequisites such as devices or service access, and what evidence to record. Keep feature-specific expected outcomes in the feature's acceptance matrix.]
24
+
25
+ ## Known limitations and troubleshooting
26
+
27
+ [Known environment restrictions, flaky checks, diagnostic steps, and any maintained issue references. Distinguish unavailable checks from product failures; a limitation does not justify reporting a pass or silently skipping required verification.]
28
+
29
+ ## Evidence and maintenance
30
+
31
+ Record commands, results, and limitations for each feature in its `ACCEPTANCE_MATRIX.md`; this guide owns reusable verification procedures, not execution history. Update it when test setup, commands, or verification boundaries change.
@@ -0,0 +1,28 @@
1
+ # Visual Design
2
+
3
+ > **Optional project document.** Create under `docs/VISUAL_DESIGN.md` when defining or changing shared visual conventions for a visual interface, unless existing design-system documentation already serves this purpose. Ground this reference in the existing interface and agreed direction. Clearly label proposed conventions separately from adopted ones. Omit irrelevant sections and link to authoritative code instead of copying values that can drift.
4
+
5
+ ## Visual direction
6
+
7
+ [Describe the intended visual character, relevant references, and constraints.]
8
+
9
+ ## Foundations
10
+
11
+ [Color roles, typography, spacing, and layout conventions. Link to authoritative tokens, styles, and assets.]
12
+
13
+ ## Components and states
14
+
15
+ [Shared component styles and conventions for hover, focus, disabled, loading, empty, error, and success states. Link to existing components or examples.]
16
+
17
+ ## Responsive behavior, accessibility, and motion
18
+
19
+ [Shared rules for adapting layouts, keyboard focus, contrast, readable content, motion, and reduced-motion preferences.]
20
+
21
+ ## Proposed changes and open questions
22
+
23
+ [Unresolved visual choices, clearly separated from adopted conventions. Remove resolved entries or incorporate adopted choices above.]
24
+
25
+ ## References
26
+
27
+ - [Authoritative tokens, styles, component library, or design assets]
28
+ - [Feature designs for specific interactions; keep feature details there]
@@ -1,67 +1,48 @@
1
1
  # Repository Agent Instructions
2
2
 
3
- These are the shared instructions for AI coding agents working in this repository. Keep tool-specific instructions (for example, Claude Code instructions) in their own thin adapter files rather than duplicating this document.
3
+ These shared instructions apply to all coding agents. Keep tool-specific adapter files thin and link here instead of duplicating rules.
4
4
 
5
5
  ## Working principles
6
6
 
7
- - Read this file before working, and read [`docs/WORKFLOW.md`](docs/WORKFLOW.md) when discussing, specifying, implementing, or completing a feature.
8
- - Inspect relevant code, tests, and existing documentation before asking questions or proposing an approach. Don't ask for information the repository already answers.
9
- - Prefer the smallest coherent change. Follow existing project conventions and avoid unrelated refactors. Consult relevant documents in `docs/conventions/` when that directory exists.
10
- - Be transparent about assumptions, uncertainty, incomplete work, and failed or unrun checks. Never present unverified behavior as tested.
11
- - Use interactive question tools when available; otherwise ask in chat. Ask focused questions that materially affect scope, behavior, UX, data, security, or architecture. Propose sensible defaults for minor details.
7
+ - Inspect relevant code, tests, and documentation before asking questions or proposing an approach. Do not ask for information the repository already answers.
8
+ - Prefer the smallest coherent change, follow project conventions, and avoid unrelated refactors. Consult relevant `docs/conventions/` documents when present.
9
+ - State assumptions, uncertainty, incomplete work, and failed or unrun checks honestly. Never claim unverified success.
10
+ - Use interactive question tools when available, otherwise chat. Ask focused questions about consequential choices and choose sensible defaults for minor details.
12
11
  - Keep the human in control of scope and significant architectural tradeoffs.
13
12
 
14
13
  ## Feature workflow and approval gates
15
14
 
16
- For **new features**, follow this sequence:
15
+ Read [`docs/WORKFLOW.md`](docs/WORKFLOW.md) when discussing, specifying, implementing, or completing a feature. It owns the detailed procedure and document contracts.
17
16
 
18
- 1. **Discover:** Discuss the idea with the user. Understand the problem, users, expected behavior, constraints, boundaries, and unresolved questions. Do not implement the feature or create its feature directory during discovery.
19
- 2. **Propose:** Present a concise scope summary covering the goal, in-scope and out-of-scope behavior, important acceptance outcomes, assumptions, and consequential open questions. Explicitly offer **accept / revise / discard**.
20
- 3. **Get approval:** Treat only a clear, affirmative user response as scope approval. If the user revises the proposal, summarize the revised scope and seek approval again. If discarded, do not create feature artifacts.
21
- 4. **Specify:** After approval, create `docs/features/feature-NNN-kebab-case/` and populate `PLAN.md`, `ACCEPTANCE_MATRIX.md`, and `TASKS.md` from `.agent-specs/templates/feature/`, following the steps in [`docs/WORKFLOW.md`](docs/WORKFLOW.md) (Phase 3). Add `DESIGN.md` for substantial UX/technical design and `RESEARCH.md` for findings worth preserving, only when needed. Create `HANDOFF.md` when a real session handoff is useful. Record the approved scope faithfully. Mark proposed technical choices as proposed, not approved.
22
- 5. **Stop at the spec boundary:** After writing the feature documents, summarize what was created and stop. **Do not start implementation** until the user explicitly requests it, possibly in a later session.
23
- 6. **Implement and verify:** On an explicit implementation request, review the feature documents and relevant code. Resolve blockers, surface consequential technical choices, then execute tasks, validate acceptance criteria, and keep the documents current.
24
- 7. **Finish:** Update related documentation, capture architectural decisions actually adopted, report verification evidence and remaining limitations, and mark the feature complete only when acceptance criteria are satisfied or exceptions explicitly accepted by the user.
17
+ For new features:
25
18
 
26
- Existing-feature work and ordinary fixes should follow the user's requested scope; do not force a new feature directory for every small change.
19
+ 1. Discuss the problem and inspect the repository before proposing scope. Do not implement or create feature artifacts during discovery.
20
+ 2. Present scope, acceptance expectations, exclusions, and consequential open questions. Offer **accept / revise / discard**; obtain clear affirmative approval, including renewed approval after revisions.
21
+ 3. After approval, populate `PLAN.md`, `ACCEPTANCE_MATRIX.md`, and `TASKS.md` from the feature templates. Record approved scope faithfully and distinguish proposed technical choices from adopted decisions.
22
+ 4. **Stop after specification.** Summarize the documents and blockers. Start implementation only when the user explicitly requests it.
23
+ 5. Implement within approved scope, keep documents current, and verify acceptance outcomes before declaring completion.
27
24
 
28
- ### Scope changes and technical decisions
25
+ Existing-feature work and ordinary fixes follow the user's requested scope; do not force a new feature directory for every small change.
29
26
 
30
- - An approved feature scope is the baseline. Ask for renewed approval before materially changing promised behavior, exclusions, or acceptance criteria.
31
- - Technical implementation details can evolve within that scope. Surface decisions that introduce major dependencies, migrations that modify or delete existing data, security implications, substantial complexity, or broad architectural consequences before committing to them.
32
- - Keep proposed decisions in the feature `PLAN.md`. Add a project-wide ADR **when a significant architectural decision has actually been adopted**, typically after implementation. For consequential decisions adopted earlier, record the ADR at adoption rather than losing the rationale. Never turn an unimplemented proposal into an accepted ADR.
27
+ ### Scope and decision boundaries
33
28
 
34
- ## Feature documentation contracts
29
+ - Ask before changing promised behavior, exclusions, or acceptance criteria, or adding an independent user-facing capability, however small.
30
+ - Implementation choices necessary to fulfill agreed outcomes may proceed without renewed approval. This includes validation and error feedback needed to make an agreed form work coherently. Record meaningful choices in the plan. New capabilities such as undo, additional management actions, or a changed recovery policy need approval.
31
+ - Surface major dependencies, migrations that modify or delete existing data, security-sensitive choices, substantial complexity, and broad architectural consequences before committing to them. Follow the workflow for technical refinements within scope.
35
32
 
36
- - **`PLAN.md`** explains _why and what_, including approved scope, requirements, constraints, risks, and the proposed technical direction.
37
- - **`ACCEPTANCE_MATRIX.md`** defines objectively verifiable outcomes and records methods, results, and evidence. Do not claim a pass without evidence.
38
- - **`TASKS.md`** is the authoritative checklist for implementation progress and holds the feature's lifecycle status. Keep items small and link them to acceptance IDs where practical.
39
- - **`DESIGN.md`** is optional detailed technical/interaction design, not a second feature specification.
40
- - **`RESEARCH.md`** is optional durable investigative findings, not an approved decision.
41
- - **`HANDOFF.md`** is optional, temporary context for a session or agent transition. It must never supersede the plan, acceptance matrix, or task checklist.
42
- - Feature directories use `feature-NNN-kebab-case`, with three-digit IDs starting at `001`. Choose the next number above the highest existing feature ID; never reuse a retired ID.
43
- - Use stable IDs such as `FR-001` (requirement), `AC-001` (acceptance), and `T-001` (task) so documents can cross-reference each other.
33
+ ## Documentation and completion
44
34
 
45
- ## Documentation and architecture decisions
46
-
47
- - Update relevant documentation **in the same change** when code changes behavior, architecture, configuration, developer setup, or public interfaces. Documentation is part of done, not an optional follow-up.
48
- - Record durable, cross-cutting architectural decisions in `docs/adr/`. Use `.agent-specs/templates/adr/ADR.md` for the format; real ADRs start at `adr-001-...`.
49
- - An ADR records context, the adopted decision, alternatives and tradeoffs, consequences, and references. Avoid ADRs for routine local implementation details.
50
- - Do not write speculative ADRs during feature discovery or initial specification. Capture proposed approaches and uncertainties in `PLAN.md` instead.
51
- - Keep docs concise and accurate; remove stale claims rather than merely appending new text.
52
- - Practice **progressive documentation**: create an optional document only to solve a concrete problem. Prefer updating an existing source of truth over producing redundant or empty files.
53
- - If maintained, keep `docs/ARCHITECTURE.md` aligned with the _implemented_ system, `docs/GLOSSARY.md` aligned with shared domain language, and `docs/conventions/` aligned with stable project-specific practices. Create them only when useful, from `.agent-specs/templates/project/` or `.agent-specs/templates/conventions/`. When closing a feature, check whether one has become useful and report your recommendation to the user (see [`docs/WORKFLOW.md`](docs/WORKFLOW.md), Phase 5). An adopted architecture decision still belongs in an ADR.
54
-
55
- ## Verification and completion
56
-
57
- - Before claiming completion, run relevant tests, linters, type checks, and build checks supported by the repository, or explain precisely why they were not run.
58
- - Update acceptance results with concrete evidence (test name, command, output summary, or a reproducible manual check). Never infer a pass from implementation alone.
59
- - Keep `TASKS.md` synchronized with actual progress, including its status, which is the single lifecycle status for the feature. Do not mark blocked or incomplete work as done.
60
- - Call out unresolved failures, missing coverage, migrations, and follow-up work explicitly.
35
+ - Update affected documentation in the same change as behavior, architecture, configuration, setup, or public-interface changes.
36
+ - Respect document ownership: `PLAN.md` owns scope and approach; `ACCEPTANCE_MATRIX.md` owns verification evidence; `TASKS.md` owns progress and the sole feature lifecycle status. Optional documents must not supersede them.
37
+ - Use the [optional project document catalog](docs/WORKFLOW.md#optional-project-document-catalog) for creation triggers, ownership, and when to consult shared references. Reuse existing sources, create documents only when useful and authorized, and remove stale claims. Feature-level optional documents are covered by the workflow's Phase 3 table.
38
+ - Record significant adopted architectural decisions in `docs/adr/`; keep unimplemented proposals in the plan. Use the ADR template and avoid ADRs for routine local details.
39
+ - Run relevant tests, linters, type checks, and builds before claiming completion, or explain precisely why checks were not run. Record concrete evidence; implementation alone is not a pass.
40
+ - For applicable changes, document rollout, migrations, recovery limits, and post-release checks in the existing feature documents, linking to shared deployment/publishing guidance. Distinguish implemented and verified work from released behavior. Follow existing authorization for release execution; documentation alone does not grant it.
41
+ - Mark a feature complete only when acceptance criteria pass or the user explicitly accepts exceptions. Report unresolved failures, missing verification, migrations, and follow-up work.
61
42
 
62
43
  ## Git commits
63
44
 
64
- Commit your work as you go, without waiting to be asked. Commit approved feature specs on their own. During implementation, commit at **milestones**: points you would want to return to. A milestone passes the relevant checks and has one theme you can describe in a sentence, such as the domain logic for a feature with its tests, or the UI built on top of it. A feature typically takes a few commits; neither one per task nor one per feature. Also commit before risky steps (large refactors, migrations, dependency changes) and before ending a session. Split a commit that would mix unrelated concerns.
45
+ Follow the user's explicit commit preference first, including requests to review diffs before commits or to leave work uncommitted. Otherwise, commit your work as you go, without waiting to be asked. Commit approved feature specs on their own. During implementation, commit at **milestones**: points you would want to return to. A milestone passes the relevant checks and has one theme you can describe in a sentence, such as the domain logic for a feature with its tests, or the UI built on top of it. A feature typically takes a few commits; neither one per task nor one per feature. Also commit before risky steps (large refactors, migrations, dependency changes) and before ending a session. Split a commit that would mix unrelated concerns.
65
46
 
66
47
  - Run the relevant checks before committing. If you commit while something is failing or incomplete, say so in the message.
67
48
  - Don't commit secrets, credentials, local environment files, or build output that the repository doesn't already track.
@@ -1,6 +1,4 @@
1
1
  # Claude Code Instructions
2
2
 
3
- 1. **Always read and follow `AGENTS.md` before doing any work.** For feature work, also read `docs/WORKFLOW.md` and the relevant files in `docs/features/`.
4
- 2. Treat `AGENTS.md` as the shared source of truth for repository workflow, documentation, verification, and commit style. Do not duplicate or override its instructions here.
5
- 3. **Do not add AI attribution to Git commits.** In particular, do not add `Co-Authored-By: Claude` (or similar AI co-author trailers), `Generated with Claude Code`, or other AI attribution lines to commit messages. Do not append such trailers automatically when generating commits.
6
- 4. Follow the human approval gates in `AGENTS.md`: approval of feature scope authorizes writing specs, **not** beginning implementation.
3
+ 1. **Read and follow `AGENTS.md` before doing any work.** It is the shared source of truth for workflow, documentation, verification, and Git practices.
4
+ 2. Follow any additional documentation referenced by `AGENTS.md`. Do not duplicate or override its instructions here.
@@ -4,10 +4,12 @@ This document expands the feature lifecycle required by [`AGENTS.md`](../AGENTS.
4
4
 
5
5
  ## Phase 1: Discover (conversation only)
6
6
 
7
- - Read existing code and documentation when relevant, then explore the user's idea collaboratively.
8
- - Check for overlap with existing features: list `docs/features/` and judge by folder names. Open a feature's `PLAN.md` only when its name suggests related scope, and read its summary and approved scope rather than the whole folder. If scope overlaps, say so in the proposal and settle with the user which feature owns it.
7
+ - Read existing code and documentation when relevant, then explore the user's idea collaboratively. Consult `docs/PRODUCT.md` or the existing product reference when present to understand users, core journeys, and agreed boundaries; it does not authorize new feature scope.
8
+ - Check for overlap with existing features: list `docs/features/` and judge by folder names. Open a feature's `PLAN.md` only when its name suggests related scope, and read its summary, approved scope, and any supersession notes rather than the whole folder. Follow relevant replacement links to understand current behavior. If scope overlaps, say so in the proposal and settle with the user which feature owns it.
9
9
  - Ask focused clarifying questions, using the agent's interactive question interface where available or normal chat otherwise. Prefer small, purposeful batches over long questionnaires.
10
10
  - Establish the problem, target users, expected behaviors, important edge cases, constraints, dependencies, and exclusions.
11
+ - Ask how the user wants the feature verified when that affects effort or tooling, for example browser end-to-end tests or checks on a device or service the agent can't reach. Read `docs/TESTING.md` or the existing testing/contributing guide when present. If the project already has a test approach, follow it instead of asking.
12
+ - For changes with release or data-recovery implications, inspect the existing deployment/publishing guide or runbook. Establish whether release execution and live verification are part of the requested scope or a later handoff.
11
13
  - Offer sensible defaults and surface tradeoffs; do not silently make consequential product decisions.
12
14
  - Do **not** create a feature directory, commit a spec, or implement the feature yet.
13
15
 
@@ -21,6 +23,8 @@ Present a readable summary with:
21
23
  4. **Acceptance expectations**: how success will be recognized.
22
24
  5. **Assumptions, risks, and open questions**: especially choices that affect cost or design.
23
25
 
26
+ **Size the feature.** A feature is one increment the user can review and verify in one sitting. If the scope contains parts that can be built and verified on their own, or would need more than about ten acceptance criteria, propose splitting it into several features: list them in build order with their dependencies, and let the user choose between the split and a single feature. Each feature gets its own directory; one approval can cover the whole set.
27
+
24
28
  Ask the user to **accept, revise, or discard**.
25
29
 
26
30
  - **Accept:** proceed to specification.
@@ -32,7 +36,7 @@ Ask the user to **accept, revise, or discard**.
32
36
 
33
37
  Create the feature directory by hand:
34
38
 
35
- 1. **Number:** find the highest `NNN` among the existing `docs/features/feature-NNN-*` directories and add one (start at `001`). Never reuse a number.
39
+ 1. **Number:** find the highest `NNN` among the existing `docs/features/feature-NNN-*` directories and add one (start at `001`). Never reuse a number. If the user re-scopes or splits a feature before any of it is implemented, restructure its documents in a new commit; it may keep its number and take a new slug.
36
40
  2. **Name:** `docs/features/feature-NNN-kebab-case/`, where `kebab-case` is a short slug of the feature title (for example `feature-007-user-statistics-page`).
37
41
  3. **Copy:** `PLAN.md`, `ACCEPTANCE_MATRIX.md`, and `TASKS.md` from `.agent-specs/templates/feature/`, plus any optional templates needed (see the table below).
38
42
  4. **Fill identifiers:** in every copied file, replace `feature-NNN-kebab-case` with the directory name, the `NNN` in `Feature NNN:` with the number, `[Feature title]` with the title, and `[YYYY-MM-DD]` with today's date.
@@ -51,15 +55,21 @@ Required and optional documents:
51
55
  | `RESEARCH.md` | Durable findings from meaningful investigation | Optional |
52
56
  | `HANDOFF.md` | Short-lived context for work that will resume elsewhere | Only if useful |
53
57
 
54
- Write the approved scope into `PLAN.md`. Draft acceptance criteria and tasks that correspond to that scope. Cross-reference IDs where practical. Put unresolved technical questions in the plan, rather than inventing answers. Add `DESIGN.md` only for substantial design detail, and `RESEARCH.md` only when research findings are worth retaining. Do not write an ADR for an unimplemented option.
58
+ Write the approved scope into `PLAN.md`. Draft acceptance criteria and tasks that correspond to that scope. Use stable requirement (`FR-001`), acceptance (`AC-001`), and task (`T-001`) IDs and cross-reference them where practical. State each criterion's verification method as the observable check (for example "journey completes in a browser at 360 px width"), not a specific test tool, unless the user or the project has already chosen one; tooling is an implementation choice. Put unresolved technical questions in the plan, rather than inventing answers. Add `DESIGN.md` only for substantial design detail, and `RESEARCH.md` only when research findings are worth retaining. Do not write an ADR for an unimplemented option.
59
+
60
+ For applicable features, fill the plan's "Release and recovery" section: rollout order, compatibility, migrations, irreversible steps, recovery limits, and observable post-release checks. Link to shared procedures rather than copying them. Put required verification outcomes in `ACCEPTANCE_MATRIX.md` and execution work in `TASKS.md`; identify ownership and prerequisites for release work explicitly outside scope. Do not add a release process to features that do not need one.
61
+
62
+ If the approved scope changes behavior owned by an earlier feature, fill the plan's "Related and superseded features" section using the rules below. Treat the relationship as planned until the replacement is implemented.
55
63
 
56
64
  **Then stop.** Tell the user what was scaffolded, identify open decisions or blockers, and wait for an explicit implementation request. Feature approval is **not** implementation authorization.
57
65
 
58
66
  ## Phase 4: Implement (separate explicit request)
59
67
 
60
68
  - Re-read the active feature's plan, acceptance matrix, and tasks, plus any optional design/research documents; inspect relevant code and applicable `docs/conventions/` documentation.
61
- - Check readiness: requirements coherent, blockers identified, implementation direction sensible, verification approach practical. Record any blockers under "Dependencies and blockers" in `TASKS.md`, then set its status to `Ready`, and to `In progress` once work starts.
69
+ - Check readiness: requirements coherent, blockers identified, implementation direction sensible, verification approach practical. Consult the existing testing guide for setup, check selection, and integration boundaries. Record any blockers under "Dependencies and blockers" in `TASKS.md`, then set its status to `Ready`, and to `In progress` once work starts.
62
70
  - Seek human input before significant new dependencies, migrations that modify or delete existing data, security-sensitive choices, or changes to approved behavior. Purely additive migrations (for example, a new table or store that leaves existing data untouched) need no prior approval, but record them in the plan and report them. Technical refinement that stays within scope usually needs no additional approval.
71
+ - Treat an independent user-facing capability beyond the approved requirements as a scope change, however small (for example, undoing an action or an extra management capability): ask before building it, then add it to the plan's requirements and scope change log. Validation and error feedback necessary to fulfill agreed outcomes may proceed without another gate; document meaningful choices in the plan. For example, an agreed form needs feedback when submission fails, but adding a new retry policy or recovery workflow may change the product contract. Supporting work that leaves behavior unchanged, such as operator scripts or security hardening, needs no approval but belongs in the plan's technical approach.
72
+ - Prepare and verify release/recovery steps within the approved scope. Use the project's existing authorization process before deploying, publishing, or modifying production data; a written procedure or implementation request alone is not authorization. Reuse explicit authorization already given rather than asking again.
63
73
  - Work through `TASKS.md`, updating checked items to reflect reality. Keep plan notes synchronized when implementation choices change.
64
74
  - Add or update tests and record concrete results in `ACCEPTANCE_MATRIX.md`.
65
75
  - If interrupted, add or refresh `HANDOFF.md` with the current task, blockers, commands run, and the next actionable step.
@@ -68,21 +78,53 @@ Write the approved scope into `PLAN.md`. Draft acceptance criteria and tasks tha
68
78
 
69
79
  - Review each acceptance criterion against observable evidence. Use `Pass`, `Fail`, `Blocked`, or `Not run`; never invent a result. If a criterion is waived or removed, record the user's approval and update scope accordingly.
70
80
  - Run applicable checks and document anything not run.
71
- - Update affected user/developer/project documentation in the same change. Maintain `docs/ARCHITECTURE.md`, `docs/GLOSSARY.md`, and `docs/conventions/` when they exist and are affected by the change.
72
- - Check whether a missing project document has become useful. Consider `docs/conventions/` for a rule that earlier features also relied on and that the code doesn't make obvious (one whose violation would be a silent bug), and `docs/GLOSSARY.md` for domain terms used across several features or easily confused with each other. **Always include the outcome in your report**: name each candidate and say whether you recommend it and why, even if you recommend against it. The user decides; don't create the document until they agree.
81
+ - Reconcile `PLAN.md` with what shipped: its technical approach, assumptions, and references (ADRs, related features) must describe the implementation, with no stale claims left, and any behavior added during implementation must appear in its requirements.
82
+ - For implemented replacements, reconcile supersession links and historical verification notes in the affected earlier features using the rules below. Apply this reconciliation to the active plan; preserve earlier specifications as historical records with explicit supersession notes.
83
+ - Update affected user/developer/project documentation in the same change. Use the optional project document catalog below to identify relevant references and their ownership; maintain existing equivalents instead of creating duplicates.
84
+ - Review the catalog for a missing document that has become useful and report only useful recommendations with a brief reason. Follow its creation policy rather than treating the catalog as a checklist of files to generate.
85
+ - Report release state separately from implementation completion: distinguish locally verified, ready for release, and actually released behavior, naming the version/environment when known. Required release or recovery checks remain `Not run` or `Blocked` until evidenced; do not mark the feature complete while they remain required and unverified. If release is explicitly outside the approved scope, implementation may be complete once its acceptance criteria pass; record the remaining release work, owner (or unassigned ownership), and prerequisites in the plan and final handoff without claiming it shipped. Do not introduce a second feature lifecycle status.
73
86
  - Create ADRs for meaningful architectural decisions **actually adopted**. Normally do this after the implementation is known; for a consequential choice adopted earlier, record it at that point.
74
- - Report what shipped, what was validated, any limitations, and whether the feature is complete. A feature is not complete while required acceptance criteria remain failing, blocked, or unverified.
87
+ - Report what was implemented and, if applicable, released, what was validated, any limitations, and whether the feature is complete. A feature is not complete while required acceptance criteria remain failing, blocked, or unverified.
75
88
  - Set the `TASKS.md` status to `Complete` only when that holds; otherwise use `Implemented (verification pending)` and list what remains.
76
89
 
90
+ ## Superseding earlier feature specifications
91
+
92
+ A later feature may replace only part of an earlier feature. Related work or an extension does not automatically supersede the entire earlier specification.
93
+
94
+ - **During specification:** In the new plan's "Related and superseded features" section, link the earlier plan and identify exactly which requirements and acceptance criteria will change, the replacement behavior, and what remains in force. Qualify references with the feature ID (for example, `feature-003-export / FR-002`), since IDs repeat across features. Label the replacement as planned; scope approval alone does not mean the current behavior has changed.
95
+ - **When implemented:** Record the effective replacement date and a commit, PR, or other concrete implementation reference in the new plan. Add a reciprocal "Related and superseded features" note to the earlier plan identifying the affected IDs and linking to the replacement. For staged rollouts, state where the replacement is effective and where the earlier behavior still applies. Do not mark unimplemented portions as superseded.
96
+ - **Preserve evidence:** Keep the earlier requirements, acceptance rows, results, and evidence intact. Add a dated supersession note to the earlier acceptance matrix's verification notes, naming affected criteria and linking to the new plan and matrix. An old `Pass` describes the earlier behavior at the recorded verification point; it is not evidence for the replacement. Verify replacement behavior in the new feature's matrix, leaving unverified criteria `Not run` or `Blocked` as appropriate.
97
+ - **Preserve lifecycle history:** Do not reopen a completed feature or rewrite its task checklist merely because a later feature replaces its behavior. Supersession is a relationship recorded in the plans, not a new lifecycle status or acceptance result. Unaffected requirements remain in force. Correcting genuinely inaccurate records is separate from supersession and must be explained explicitly.
98
+
99
+ For example, if feature 012 replaces feature 003's CSV delimiter, both plans identify the affected requirement and acceptance IDs. Feature 003 retains its original delimiter test result with a note pointing to feature 012; feature 012 records its own evidence for the new delimiter. Other export behavior remains governed by the unchanged requirements.
100
+
101
+ ## Optional project document catalog
102
+
103
+ This is the shared index for project-level documentation. The Phase 3 table covers feature-level optional files (`DESIGN.md`, `RESEARCH.md`, and `HANDOFF.md`). Templates are installed for reuse; initialization does not create the completed project documents below.
104
+
105
+ Before creating a shared reference, check whether an existing README, contributing guide, design system, publishing guide, runbook, or other maintained source already serves the purpose. Use that source even if its filename differs. When a missing reference would help, recommend it and why; create it when the user agrees or has already authorized it as part of the work. Do not repeat an approval request already answered. Updating an existing affected reference is part of completing the change. ADRs follow their adoption rule below, not a separate optional-document approval gate.
106
+
107
+ | Document | When it adds value | Ownership and use |
108
+ | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
109
+ | `docs/ARCHITECTURE.md` | The implemented system needs an overview of components, boundaries, and data flows. | Read for cross-cutting implementation work; update when the system changes. Describe current architecture and link to ADRs for rationale. |
110
+ | `docs/GLOSSARY.md` | Domain terms recur across features or are easily confused. | Own precise shared meanings; consult during specification and update when domain language changes. |
111
+ | `docs/VISUAL_DESIGN.md` | Shared visual conventions are being defined or changed and no existing design-system reference suffices. | Read before UI work; maintain shared conventions when they change. Ground them in the interface and agreed direction, distinguish proposals from adopted rules, and leave feature-specific interactions in `DESIGN.md`. |
112
+ | `docs/TESTING.md` | Verification setup, check selection, or integration boundaries need explanation beyond scripts and CI. | Read before planning/running verification; maintain reusable procedures and limitations. Scripts/CI own executable commands; feature matrices own results. |
113
+ | `docs/PRODUCT.md` | Users, purpose, core journeys, principles, or deliberate non-goals are unclear from existing documentation. | Read before scope decisions; update for agreed direction or implemented journey changes. Distinguish current capabilities from future direction and proposals. This is not a roadmap or feature approval mechanism. |
114
+ | `docs/DEPLOYMENT.md` | Recurring release, deployment, or recovery procedures need explanation beyond existing automation or publishing/runbook documentation. | Read for release-impacting changes; maintain rollout order, compatibility, migrations, post-release checks, and recovery limits. Feature plans own deviations; matrices or linked release records own execution evidence. Procedures do not grant execution permission. |
115
+ | `docs/conventions/<topic>.md` | A stable, non-obvious rule applies across features and is not adequately enforced or documented elsewhere. | Read for relevant changes; maintain reusable rules. Tooling owns mechanically enforced rules; feature plans or ADRs own feature-specific decisions. |
116
+ | `docs/adr/adr-NNN-kebab-case.md` | A significant architectural decision has actually been adopted. | Record rationale at adoption under the agreed workflow; preserve history and link superseding decisions. Keep unimplemented proposals in feature plans. |
117
+
118
+ Use `.agent-specs/templates/project/` for the six named project references, `templates/conventions/CONVENTION.md` for conventions, and `templates/adr/ADR.md` for decisions (all under `.agent-specs/`). Fill templates from actual project context and remove irrelevant guidance; never create empty documents merely because a template exists.
119
+
77
120
  ## Maintaining the source of truth
78
121
 
79
122
  - `PLAN.md` owns agreed scope, not task completion.
80
123
  - `ACCEPTANCE_MATRIX.md` owns acceptance and verification evidence, not general project notes.
81
124
  - `TASKS.md` owns implementation progress and the feature's lifecycle status, not architectural rationale.
82
- - `DESIGN.md`, if present, owns detailed technical and UX design, not user-approved scope.
125
+ - `DESIGN.md`, if present, owns detailed technical and UX design, not user-approved scope. Link to the project visual design reference for shared conventions.
83
126
  - `RESEARCH.md`, if present, preserves meaningful investigation and uncertainty, not decisions.
84
127
  - `HANDOFF.md`, if present, is a snapshot for resumption and may be deleted once unnecessary.
85
- - ADRs document _adopted_, broadly relevant architecture decisions; feature plans retain proposals and feature-local tradeoffs.
86
- - `docs/ARCHITECTURE.md` describes the implemented system; `docs/GLOSSARY.md` defines shared domain terminology; `docs/conventions/` records reusable project practices, not decisions specific to one feature (those belong in an ADR or the feature's plan; link them instead of restating them). Create these documents only when they provide value. Templates are under `.agent-specs/templates/`.
128
+ - Shared project references and ADRs follow the ownership and maintenance rules in the optional project document catalog above. Feature-specific release plans and exceptions stay in `PLAN.md`; verification evidence stays in `ACCEPTANCE_MATRIX.md` or its linked release records.
87
129
 
88
130
  Approved scope changes must be brought back to the user before being incorporated as commitments. Keep artifacts understandable to someone resuming the project without the original chat history. **Progressive documentation:** do not create an optional document just because a template exists; prefer updating a single authoritative source over duplicating content.