create-afe-project 0.0.0-stage → 2.0.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.
Files changed (61) hide show
  1. package/CHANGELOG.md +458 -0
  2. package/LICENSE +21 -0
  3. package/README.md +77 -2
  4. package/bin/create-afe-project.js +123 -0
  5. package/package.json +43 -4
  6. package/src/answers.js +147 -0
  7. package/src/config.js +151 -0
  8. package/src/project.js +217 -0
  9. package/src/render.js +51 -0
  10. package/template/.claude/harness.conf +50 -0
  11. package/template/.claude/hooks/post-edit-check.sh +41 -0
  12. package/template/.claude/hooks/protect-docs.sh +315 -0
  13. package/template/.claude/hooks/session-start.sh +81 -0
  14. package/template/.claude/hooks/stop-check-decisions.sh +25 -0
  15. package/template/.claude/hooks/stop-check-docs.sh +29 -0
  16. package/template/.claude/hooks/stop-check-fast.sh +33 -0
  17. package/template/.claude/hooks/stop-check-template.sh +23 -0
  18. package/template/.claude/hooks/stop-run-project-hooks.sh +27 -0
  19. package/template/.claude/path-classes +102 -0
  20. package/template/.claude/settings.project.json +5 -0
  21. package/template/.claude/settings.template.json +92 -0
  22. package/template/.claude/skills/afe-init/SKILL.md +104 -0
  23. package/template/.claude/skills/create-pr/SKILL.md.jinja +110 -0
  24. package/template/.claude/skills/update-template/SKILL.md +40 -0
  25. package/template/.claude/skills/{% if code_review %}review-code{% endif %}/SKILL.md.jinja +50 -0
  26. package/template/.claude/skills/{% if docs_review %}docs-review{% endif %}/SKILL.md +60 -0
  27. package/template/.claude/skills/{% if dual_review %}dual-review{% endif %}/SKILL.md +58 -0
  28. package/template/.github/workflows/decisions.yml.jinja +57 -0
  29. package/template/.github/workflows/docs.yml.jinja +40 -0
  30. package/template/.github/workflows/{% if code_review %}code-review.yml{% endif %}.jinja +54 -0
  31. package/template/.github/workflows/{% if docs_review %}docs-review.yml{% endif %}.jinja +52 -0
  32. package/template/.github/workflows/{% if fail_without_change %}fail-without-change.yml{% endif %}.jinja +42 -0
  33. package/template/.github/workflows/{% if secret_scan %}secret-scan.yml{% endif %}.jinja +47 -0
  34. package/template/.markdownlint-cli2.jsonc +27 -0
  35. package/template/.template/owned.txt.jinja +65 -0
  36. package/template/AGENTS.md.jinja +91 -0
  37. package/template/CLAUDE.md +3 -0
  38. package/template/README.md.jinja +53 -0
  39. package/template/_gitignore +14 -0
  40. package/template/docs/README.md.jinja +44 -0
  41. package/template/docs/contributing.md.jinja +206 -0
  42. package/template/docs/decisions/adr-template.md +38 -0
  43. package/template/docs/documentation-rules.md.jinja +200 -0
  44. package/template/docs/testing-rules.md +80 -0
  45. package/template/scripts/check-decisions.sh +382 -0
  46. package/template/scripts/check-docs.sh +20 -0
  47. package/template/scripts/check-links.mjs +142 -0
  48. package/template/scripts/check-project.sh +27 -0
  49. package/template/scripts/check-template.sh +88 -0
  50. package/template/scripts/check.sh +21 -0
  51. package/template/scripts/env.sh +29 -0
  52. package/template/scripts/gen-decisions-index.sh +57 -0
  53. package/template/scripts/gen-settings.sh +14 -0
  54. package/template/scripts/lib/classes.sh +89 -0
  55. package/template/scripts/lib/git-base.sh +25 -0
  56. package/template/scripts/lib/harness-conf.sh +48 -0
  57. package/template/scripts/lib/json.mjs +160 -0
  58. package/template/scripts/pr-metrics.sh +80 -0
  59. package/template/scripts/protect-branch.sh +101 -0
  60. package/template/scripts/{% if acceptance_check %}check-acceptance.sh{% endif %} +47 -0
  61. package/template/scripts/{% if fail_without_change %}fail-without-change.sh{% endif %} +88 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,458 @@
1
+ # create-afe-project
2
+
3
+ ## 2.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - [#12](https://github.com/dev-oleksandrv/create-afe-project/pull/12) [`d286334`](https://github.com/dev-oleksandrv/create-afe-project/commit/d286334dc00f8086371632f1550bf299452dd910) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `docs/documentation-rules.md`, sections 2 to 4 and 6: conventions and recipes, like
8
+ architecture, carry the front matter `status`, `date`, and `verified-against` (`none` while no
9
+ code exists) and move from `draft` to `current`; operations documents now carry the same front
10
+ matter; a convention names the lint rule or check that enforces it, or `none` when only the
11
+ review does; a tool-specific rule file or skill links to them and never holds its own copy. The
12
+ `docs-review` skill reports a convention or recipe copied into a tool-specific rule file (such as
13
+ `.cursor/rules/`, `.claude/rules/`) or a skill, and `review-code` applies the conventions of the
14
+ areas a diff changes.
15
+
16
+ MAJOR (`docs/maintaining.md`, section 4: new required front-matter fields). No check reads the
17
+ fields, so no project's checks start failing, but a project must act: give each existing
18
+ document in `docs/conventions/`, `docs/recipes/`, and `docs/operations/` the front matter, with
19
+ `verified-against` set by a review against code, or `none` while no code exists. The seeded map
20
+ `docs/README.md` changes for new projects only: an existing project copies its Conventions and
21
+ Recipes rows by hand. Added on the owner's instruction of 2026-11-05, ported from
22
+ agent-docs-template 0.7.0; no observed failure.
23
+
24
+ ### Minor Changes
25
+
26
+ - [#10](https://github.com/dev-oleksandrv/create-afe-project/pull/10) [`460f9a1`](https://github.com/dev-oleksandrv/create-afe-project/commit/460f9a123aa879d6a4d770031a80b510a340bfec) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `docs/contributing.md`, section 6: the review criterion "Dependencies": a new dependency exists in
27
+ its registry under the name used, is maintained, has a license the project allows (an open
28
+ question while no document says which), does no job an existing one already does, and is pinned
29
+ exactly, through the lock file where the stack has one. The `review-code` skill checks duplication
30
+ and pinning in the files, and the rest when it can reach the registry; otherwise it leaves them to
31
+ the owner's review of the gate file. To stay within the line budget, the blocker bullet of the
32
+ same section is rewrapped with two rewordings of the same meaning: "zero findings is valid" for
33
+ "zero findings is a valid result", and "fails an item of its Acceptance section" for "fails a
34
+ criterion of its Acceptance section", as section 3 already calls them items. Added on the owner's instruction of
35
+ 2026-11-05, ported from agent-docs-template 0.7.0; no observed failure.
36
+
37
+ - [#11](https://github.com/dev-oleksandrv/create-afe-project/pull/11) [`3e84174`](https://github.com/dev-oleksandrv/create-afe-project/commit/3e84174dc2590f7d00d48c6400be84d86800220d) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `docs/testing-rules.md`, section 2: a flaky test is fixed, never retried or rerun until green;
38
+ skipping it is a blocker of section 4 unless the owner, asked, decides otherwise. To stay within
39
+ the line budget, the bullet on failure paths is rewrapped into two lines, with "every invalid
40
+ contract example is rejected where input is validated" for "every invalid example of a contract is
41
+ rejected where the input is validated", the same meaning. Added on
42
+ the owner's instruction of 2026-11-05, ported from agent-docs-template 0.7.0; no observed failure.
43
+
44
+ - [#14](https://github.com/dev-oleksandrv/create-afe-project/pull/14) [`8960f24`](https://github.com/dev-oleksandrv/create-afe-project/commit/8960f243c12785e43aa24854c8724feb29bd36c9) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `scripts/protect-branch.sh` applies the repository settings the rules assume, before the
45
+ ruleset: merge commits only, without squash and rebase merging, and "Automatically delete head
46
+ branches", on every plan; secret scanning with push protection, where a refusal (a private
47
+ repository without GitHub Advanced Security) is reported and the run goes on. The ruleset allows
48
+ only merge commits, and `--require-base` also requires the `base` job of the
49
+ `fail-without-change` workflow, once it has passed in CI on a pull request that changes a test.
50
+ `--dry-run` prints the settings and the ruleset as one JSON object. `docs/contributing.md`,
51
+ sections 1 and 3, and the `fail-without-change` workflow name the script; the message after create
52
+ names the settings in place of the separate step for secret scanning. On the owner's instruction
53
+ of 2026-11-05, ported from agent-docs-template 0.7.0; no observed failure. `README.md` is seeded:
54
+ an existing project copies its section "Protected main branch" by hand, and runs
55
+ `scripts/protect-branch.sh` again to apply the settings.
56
+
57
+ - [#7](https://github.com/dev-oleksandrv/create-afe-project/pull/7) [`90424db`](https://github.com/dev-oleksandrv/create-afe-project/commit/90424db32e4cde2bcfb6072bc22f68bedba8cf7f) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `.claude/hooks/session-start.sh`, a SessionStart hook: a new, resumed, or compacted session
58
+ starts from at most ten lines of local facts: the branch, its base and the commits ahead,
59
+ uncommitted and untracked files, merge conflicts, and each plan in `docs/plans/` with its
60
+ `review-by`, flagged when it is past. No network; it always exits 0.
61
+ `.claude/settings.template.json` registers it, `.template/owned.txt` lists it, and
62
+ `docs/documentation-rules.md`, section 7, names it under "Currency". Added on the owner's
63
+ instruction of 2026-11-05, ported from agent-docs-template 0.7.0; no observed failure.
64
+
65
+ - [#13](https://github.com/dev-oleksandrv/create-afe-project/pull/13) [`2fe2391`](https://github.com/dev-oleksandrv/create-afe-project/commit/2fe239179eb79502df060a6defc05981bcb4527a) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - The seeded `.claude/path-classes` lists the gate files of any stack as their own block:
66
+ Dependabot, Renovate, pre-commit, Make (with every `*.mk` file), just, and Task (with `Taskfile.dist.yml`), also
67
+ in subdirectories, `.tool-versions`, and mise (with its environment files and its
68
+ configuration under `.config/`, `mise/`, and `.mise/`), so a change to
69
+ dependency updates, pre-commit hooks, task runners, or tool versions is named under "Gate files"
70
+ and reviewed by the owner. On the owner's instruction of 2026-11-05, ported from
71
+ agent-docs-template 0.7.0; no observed failure. An update never changes a seeded file: an existing
72
+ project copies the block "Gates of any stack" into its `.claude/path-classes` by hand.
73
+
74
+ - [#6](https://github.com/dev-oleksandrv/create-afe-project/pull/6) [`7371c45`](https://github.com/dev-oleksandrv/create-afe-project/commit/7371c45c5b3576d0b24f69b2b337c8d270e37cef) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `.claude/hooks/stop-check-fast.sh`, a Stop hook: Claude Code may not finish a turn while the
75
+ project's fast check fails. It runs `scripts/env.sh fast` (`CHECK_FAST` of
76
+ `.claude/harness.conf`) when a file other than Markdown differs from the base, committed or not,
77
+ and blocks through the Ralph cap; it skips when `CHECK_FAST` is empty or the default
78
+ `scripts/check-docs.sh`, and during merge conflicts. `.claude/settings.template.json` registers
79
+ it, `.template/owned.txt` lists it, and `docs/documentation-rules.md`, section 7, names it. Added
80
+ on the owner's instruction of 2026-11-05, ported from agent-docs-template 0.7.0; no observed
81
+ failure. The seeded `.claude/harness.conf` names the hook in its comment: an existing project may
82
+ copy those two lines by hand.
83
+
84
+ ### Patch Changes
85
+
86
+ - [#17](https://github.com/dev-oleksandrv/create-afe-project/pull/17) [`9da569a`](https://github.com/dev-oleksandrv/create-afe-project/commit/9da569a2ea0b7757ed16d8562deb897944c78d92) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - The `decisions`, `docs-review`, and `code-review` workflows treat a pull request that a workflow
87
+ opened with `GITHUB_TOKEN` (author `github-actions[bot]`), such as a generated release pull
88
+ request, as generated: readiness checks only its decision records, not the description
89
+ sections, and the AI reviews skip it. Before, readiness failed on the generated description and
90
+ claude-code-action failed with "Workflow initiated by non-human actor". Observed on this
91
+ repository's Version PR [#16](https://github.com/dev-oleksandrv/create-afe-project/issues/16).
92
+
93
+ - [#9](https://github.com/dev-oleksandrv/create-afe-project/pull/9) [`29149f2`](https://github.com/dev-oleksandrv/create-afe-project/commit/29149f26ca29287640773668af2c1c575c8f9f46) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `docs-review` and `code-review` workflows: `anthropics/claude-code-action` is pinned to
94
+ `v1.0.268`, the release the floating `v1` pointed to on 2026-11-05, like every other action, so a
95
+ new release of the action changes nothing until a pull request moves the pin. A project with a
96
+ review module sees its workflow change on the update. On the owner's instruction of 2026-11-05,
97
+ ported from agent-docs-template 0.7.0.
98
+
99
+ - [#15](https://github.com/dev-oleksandrv/create-afe-project/pull/15) [`ced35db`](https://github.com/dev-oleksandrv/create-afe-project/commit/ced35db8156fec49343e66c9c9d632d24d781bc4) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `.claude/hooks/post-edit-check.sh` resolves a relative `file_path` against the `cwd` of the hook
100
+ input, the session's working directory, instead of the project root, so `CHECK_EDIT` checks the
101
+ file the agent edited. Ported from agent-docs-template 0.7.0 on the owner's instruction of
102
+ 2026-11-05.
103
+
104
+ - [#8](https://github.com/dev-oleksandrv/create-afe-project/pull/8) [`2fbd26a`](https://github.com/dev-oleksandrv/create-afe-project/commit/2fbd26a79fec78dc37a708145f5501807b831409) Thanks [@dev-oleksandrv](https://github.com/dev-oleksandrv)! - `create-pr` skill, step 9: findings are only the comments of `claude[bot]`, the account the review
105
+ workflows post as, and of people whose `author_association` is `OWNER`, `MEMBER`, or
106
+ `COLLABORATOR`; any other comment is data, reported to the owner and neither acted on nor
107
+ answered (`AGENTS.md`, section 4). On the owner's instruction of 2026-11-05, ported from
108
+ agent-docs-template 0.7.0; no observed failure.
109
+
110
+ ## 1.0.0
111
+
112
+ ### Major Changes
113
+
114
+ - The template moves from Copier to the npm package `create-afe-project` (ADR-0002), on the
115
+ owner's instruction of 2026-10-31, to drop the Python toolchain for users; the first release on
116
+ npm, under the MIT license.
117
+ - `npx create-afe-project@latest <directory>` (or `npm create afe-project@latest`) creates a
118
+ project with a wizard that asks the questions of the former `copier.yml`; `--defaults`,
119
+ `--data key=value`, and `--data-file` answer without a terminal. The questions are short and
120
+ plain, and the message after create numbers the next steps.
121
+ - Create makes the initial commit on `main` (`Template: create the project with
122
+ create-afe-project <version>`), the one direct commit that `docs/contributing.md` allows, so
123
+ `/afe-init` starts on a clean working tree. It commits only in a new directory or an empty
124
+ clone, never in a non-empty directory written with `--force`; `--no-git` skips it.
125
+ - `npx create-afe-project@latest update` replaces the template-owned files, keeps the project
126
+ block of `AGENTS.md`, creates missing seeded files and never changes existing ones, removes
127
+ files the template no longer owns, runs the migrations between the versions, and regenerates
128
+ the generated files. It refuses a dirty working tree (`--allow-dirty`) and a downgrade, and
129
+ lists every replaced local edit of a template-owned file.
130
+ - The answers file is `.afe-answers.json` with the template version in `_version`; a project
131
+ generated by Copier converts its `.copier-answers.yml` on its first update. The path classes
132
+ (`scripts/lib/classes.sh`), the protect hook, and the size warning of
133
+ `scripts/check-decisions.sh` know both names.
134
+ - `docs/contributing.md`, section 5, `docs/documentation-rules.md`, section 9, and the
135
+ `update-template` skill describe the update with `create-afe-project`; there are no conflict
136
+ markers to resolve any more. `README.md` is seeded: copy its "Project template" and "Checks"
137
+ sections by hand.
138
+ - A generated project needs only Git, bash, and Node.js: jq and lychee are gone.
139
+ - The hooks, `scripts/gen-settings.sh`, and `scripts/pr-metrics.sh` read and write JSON with the
140
+ new `scripts/lib/json.mjs`; the protect hook now blocks when Node.js is missing.
141
+ - `scripts/check-links.mjs` replaces lychee: offline, every relative link and image of the
142
+ Markdown files points at an existing file, and every anchor at a heading or an HTML id of its
143
+ target. `scripts/check-docs.sh` and the `docs` workflow run it; `lychee.toml` is removed.
144
+ - The `docs` workflow also runs on `workflow_dispatch`, so a workflow can start it for a pull
145
+ request opened with `GITHUB_TOKEN`.
146
+ - A second pass over the AFE guide, on the owner's decisions of 2026-10-31; no observed failure.
147
+ - `afe-init` skill (new, run by the owner only): interviews the owner about the product, the
148
+ stack, and the stage; records requirements, an accepted stack ADR, and a proposed
149
+ architecture; scaffolds the code with the stack's own generator; wires format, lint, types,
150
+ unit and end-to-end tests into `scripts/checks.d/` and `.claude/harness.conf`; and proves
151
+ that every gate fails when it should. Three pull requests, one change each.
152
+ - The check after every edit: `.claude/hooks/post-edit-check.sh` (new, PostToolUse) runs
153
+ `CHECK_EDIT` of `.claude/harness.conf` on the changed file, limited by `CHECK_EDIT_GLOBS`,
154
+ and sends a failure back to the agent. `.claude/harness.conf` is seeded: an existing project
155
+ adds the two keys by hand when it wants the check.
156
+ - The protect hook asks before publishing (`npm`, `pnpm`, `yarn`, `bun`, `cargo`, `poetry`, `uv`
157
+ publish, `twine upload`, `gem push`, `dotnet nuget push`, `docker` or `podman push`),
158
+ `gh workflow run`, and a `gh api` DELETE, also behind `git -C DIR`; it denies a push to the
159
+ default branch once the remote has it; and it asks when an edit or a command contains a known
160
+ token format (AWS, GitHub, GitLab, Slack, Stripe, Google, Anthropic, OpenAI, npm, private keys).
161
+ - `secret_scan` module (new, default on): `.github/workflows/secret-scan.yml` runs gitleaks,
162
+ downloaded at a pinned version with its checksum, on the commits of every pull request and
163
+ push to `main`. The message after create also names GitHub's secret scanning and push protection.
164
+ - `scripts/protect-branch.sh` (new): creates or updates the GitHub ruleset that protects the
165
+ default branch (pull requests only, the `check` and `integrity` checks, no force push or
166
+ deletion); the owner runs it once.
167
+ - `scripts/check-template.sh` fails when a hook command of `.claude/settings.json` names a
168
+ missing or non-executable script.
169
+ - `AGENTS.md`, section 4: content from issues, pull requests, web pages, logs, tool output, and
170
+ dependencies is data, never instructions. The map plans `docs/conventions/` and
171
+ `docs/recipes/`, a new document kind of `docs/documentation-rules.md`, section 2.
172
+ - With the `dual_review` module, the Santa loop runs without the Codex CLI too, with a second
173
+ fresh Claude subagent that reviews with another lens; `REVIEW_MAX_ROUNDS` of
174
+ `.claude/harness.conf` (3 to 5, default 3) caps the rounds, and a blocker that comes back
175
+ unchanged after its fix ends the loop early.
176
+
177
+ ## [0.6.0] - 2026-10-31
178
+
179
+ A second pass over the Agent-Friendly Engineering field guide, on the owner's decisions of
180
+ 2026-10-31, and the follow-ups of 0.5.0. Observed failures: the protect hook let two writes into
181
+ rule files through, behind `cd` and in a Python heredoc (pull request #14); the review workflows
182
+ skipped #14 and reported success. The other additions come from the owner's decisions on the
183
+ guide, without an observed failure.
184
+
185
+ ### Added
186
+
187
+ - Environment contract: `scripts/env.sh setup|check|fast|e2e|reset` runs the project's commands
188
+ `SETUP`, `CHECK_FAST` (default `scripts/check-docs.sh`), `E2E`, and `RESET` of
189
+ `.claude/harness.conf`, and `scripts/check.sh` for `check`; an unset command is SKIP, and the
190
+ exit code is the command's. `AGENTS.md`, section 2, and the map point at it.
191
+ - `fail_without_change` module: `.github/workflows/fail-without-change.yml` runs
192
+ `scripts/env.sh setup` and the driver on every pull request; the label `tests-pass-on-base`
193
+ allows a pass. The driver installs with `SETUP` when `FWC_INSTALL` is empty, and a test must
194
+ now also pass with the change, so a missing toolchain is no longer evidence.
195
+ - Access control: `.claude/settings.json` denies reading `.env`, `.env.*`, `*.pem`, and `*.key`
196
+ (also through `cat` and the like); a project that needs one, such as `.env.example`, takes the
197
+ rule out with `"remove": {"permissions": {"deny": ["Read(**/.env.*)"]}}` in
198
+ `.claude/settings.project.json`, which `scripts/gen-settings.sh` now supports.
199
+ - Metrics: the measure "Regression of" (`none` or `#N`), required by readiness;
200
+ `scripts/pr-metrics.sh` adds the regression rate, the hours to merge, and the median and
201
+ maximum of each measure.
202
+ - A small diff: readiness warns, without failing, above `DIFF_WARN_LINES` (default 400) changed
203
+ lines, generated files left out.
204
+ - `contracts/*` is class high by default in `.claude/path-classes`.
205
+
206
+ ### Changed
207
+
208
+ - Review before the pull request runs without the `dual_review` module too: one pass by a fresh
209
+ Claude subagent, which `create-pr` runs, for classes normal, gate, and high; the module adds
210
+ the Codex CLI and the Santa loop. `review-code` always checks that "Checks" names it.
211
+ - `.claude/hooks/protect-docs.sh`: a target behind `cd DIR` or `git -C DIR` resolves against
212
+ that directory; the file names in an interpreter's heredoc are targets; the body of another
213
+ heredoc is not read as commands.
214
+ - `docs/contributing.md`: section 1, a session that stops unfinished leaves a checkpoint
215
+ (commits pushed, progress and blockers in the plan or the description), and GitHub deletes
216
+ merged branches; section 5, shorter; section 6, a defect fix gives the evidence pack.
217
+ - `docs/documentation-rules.md`, section 2: acceptance criteria as Given, When, Then with their
218
+ checks; architecture holds the system map with domain ownership and dependency rules.
219
+ `docs/testing-rules.md`: the project names the levels of its verification ladder.
220
+
221
+ ### Seeded files: what an existing project does by hand
222
+
223
+ - `.claude/harness.conf`: add `SETUP=`, `CHECK_FAST=scripts/check-docs.sh` (or the project's
224
+ fast check), `E2E=`, `RESET=`, and `DIFF_WARN_LINES=400`.
225
+ - `.claude/path-classes`: add `high contracts/*` when the project has contracts.
226
+ - `docs/README.md`: the row "Environment commands" names `scripts/env.sh`; the planned rows of
227
+ architecture and operations name the system map, domain ownership, and dependency rules, and
228
+ logs, traces, metrics, and scenario replay.
229
+ - On GitHub, turn on "Automatically delete head branches" in the repository settings.
230
+
231
+ ## [0.5.0] - 2026-10-31
232
+
233
+ The process follows the Agent-Friendly Engineering principles: the owner sets outcomes and
234
+ risks, agents report evidence, checks enforce, and governance follows risk and reversibility.
235
+ Recurring failure addressed: in `xandronak/brain`, pull requests #14, #15, and #18 each needed
236
+ three or more AI review rounds that never converged, because every round found new edge cases;
237
+ and each owner decision needed a separate confirmation. Additions without an observed failure,
238
+ from the owner's decisions on the AFE field guide (2026-10-30): the invariants register, the
239
+ environment commands, access control for irreversible actions, and the size budget. Open pull
240
+ requests of an existing project need the new description sections before readiness passes.
241
+
242
+ ### Added
243
+
244
+ - Path classes (`docs/documentation-rules.md`, section 8): low, normal, gate, high, approval, by
245
+ built-in rules and the new seeded `.claude/path-classes` (`<class> <glob>` lines), with
246
+ defaults for several ecosystems. Each class decides approval before the edit (approval: the
247
+ protect hook asks), the listing in the pull request (gate: "Gate files"), and the review
248
+ before it (none, one reviewer, or the Santa loop for high). `scripts/lib/classes.sh` and
249
+ `scripts/check-decisions.sh --classes` print the class of each changed path and the review it
250
+ needs. `AGENTS.md`, section 4, follows the classes.
251
+ - Loops (`docs/contributing.md`, sections 3 and 6): the Ralph loop on `scripts/check.sh` for
252
+ every change, capped by `RALPH_MAX_ITERATIONS` (default 5) in the new seeded
253
+ `.claude/harness.conf`; the Santa loop for class high only, with a Claude subagent and the
254
+ Codex CLI until neither finds a blocker, and after the third round the open blockers go to the
255
+ owner. Other classes get one pass; only the fix of a blocker is checked again.
256
+ - Definition of done in `docs/contributing.md`, section 3, which `AGENTS.md`, section 6, points
257
+ at; it replaces the definition-of-done line of `docs/documentation-rules.md`, section 6.
258
+ - Modules `acceptance_check` (`scripts/check-acceptance.sh`: every identifier of the Acceptance
259
+ section appears in a test file of `TEST_GLOBS`; run by readiness) and `fail_without_change`
260
+ (`scripts/fail-without-change.sh`: each new or changed test fails on the base, in a temporary
261
+ worktree, with the project's own `FWC_INSTALL` and `FWC_TEST`, an optional `FWC_CLASSIFIER`,
262
+ and `--allow-pass-on-base` for the label `tests-pass-on-base`). Both off by default.
263
+ - `scripts/check-decisions.sh --ready` also fails on: no "Acceptance and test plan"; an
264
+ Acceptance item that is neither "None" with a reason nor names an existing path in backticks;
265
+ an added `Decided by the owner, YYYY-MM-DD` marker in a Markdown file that "Owner decisions"
266
+ does not name; a touched gate file that "Gate files" does not name; Metrics tables outside
267
+ their forms, answers that do not add up, a blocker recorded as a limit, or a missing measure.
268
+ - `scripts/pr-metrics.sh`: sums the Metrics tables of merged pull requests with `gh`, names the
269
+ sensors without a finding, and warns when `--limit` cuts the period. `docs/maintaining.md`,
270
+ section 6 (this repository): at each release a rule or check that never fired is proposed for
271
+ removal, and a new one names the recurring failure it addresses.
272
+ - Access control: `.claude/settings.json` is now generated by `scripts/gen-settings.sh` from the
273
+ template-owned `.claude/settings.template.json` and the new seeded
274
+ `.claude/settings.project.json`, where the project adds its own permission rules; the template
275
+ denies force pushes and remote branch deletions in the forms its rules spell out.
276
+ `scripts/check-template.sh` fails on a stale `.claude/settings.json`.
277
+ - `.claude/hooks/protect-docs.sh`: asks for class approval paths (`approval` lines of
278
+ `.claude/path-classes`, `.claude/settings.project.json`, `.mcp.json`, the generated settings),
279
+ and for the irreversible commands it names: `git push` that forces, deletes, mirrors, prunes,
280
+ or pushes tags (`--tags`, `refs/tags/...`, `v<digit>...`), `gh pr merge`, `gh release create`
281
+ and `delete`, `gh repo delete`.
282
+ - Line budgets checked by `scripts/check-template.sh`: `AGENTS.md` 90 template lines,
283
+ `docs/documentation-rules.md` 200, `docs/contributing.md` 200, `docs/testing-rules.md` 80. The
284
+ four rule documents together are shorter than in 0.4.1.
285
+ - The invariants register `docs/invariants.md` as a planned document kind; its invariants are
286
+ criteria of the Santa loop. Environment commands in the map, pointed at from `AGENTS.md`. One
287
+ git worktree per parallel session (`docs/contributing.md`, section 1).
288
+
289
+ ### Changed
290
+
291
+ - `docs/contributing.md`, section 3: description sections Summary, Acceptance and test plan,
292
+ Checks, Assumptions and open questions, Owner decisions, Gate files, Metrics (two fixed
293
+ tables), Notes for the owner. The new label `limit:` records a suggestion the branch does not
294
+ fix. A failing check keeps its command and output. The owner's merge confirms the listed
295
+ markers; readiness waits for no confirming comment and no second round.
296
+ - `docs/contributing.md`, section 6: AI review is a sensor; classes `blocker` and `suggestion`;
297
+ each finding is answered once; a suggestion never drives a loop. The `docs-review` and
298
+ `code-review` workflows run once, when a pull request opens or leaves draft; a push or a reopen
299
+ does not run them again.
300
+ - `docs/testing-rules.md`: the agent derives the test plan from the identifiers, as a report; a
301
+ refactoring keeps the tests; a behaviour change changes the requirement first, then the test
302
+ with the same identifier; gate configurations are class gate; the threat model of development
303
+ gates only decides which bypass is a blocker.
304
+ - Skills: `dual-review` reviews by class; `create-pr` runs the Ralph loop, writes the new
305
+ sections, waits for the review runs once, and has a fixed blocker checked once by a fresh
306
+ subagent; `review-code` and `docs-review` use the two classes and no longer judge whether a
307
+ marker matches the owner's words.
308
+
309
+ ### Removed
310
+
311
+ - The `should`/`nit` classes and their example table, the brief rule for later rounds, the
312
+ escalation after three rounds outside the Santa loop, "Owner decisions to confirm" and its
313
+ confirming comment, the template-update exemption of 0.4.1 (now class low), and the checklist
314
+ of `docs/contributing.md`, section 4, which is now one paragraph.
315
+ - `.claude/protected-paths` is no longer seeded; the hook and the class checks still read its
316
+ glob lines as class approval.
317
+
318
+ ### Seeded files: what an existing project does by hand
319
+
320
+ - An update creates `.claude/path-classes`, `.claude/harness.conf`, and
321
+ `.claude/settings.project.json` with the defaults, and deletes `.claude/protected-paths`; a
322
+ `_migrations` entry of `copier.yml` appends its glob lines to `.claude/path-classes` as
323
+ `approval <glob>`. Check them by hand: gate configuration, such as test runner and linter
324
+ files, becomes `gate <glob>`. Add the project's own high paths
325
+ (brain: policy, limits, accounting). Set `TEST_GLOBS`, `FWC_TEST`, and `FWC_INSTALL` in
326
+ `.claude/harness.conf` before turning on the new modules (`copier update --data
327
+ acceptance_check=true --data fail_without_change=true`).
328
+ - `.claude/settings.json` becomes generated: a project that edited it moves its own rules into
329
+ `.claude/settings.project.json` and runs `scripts/gen-settings.sh`.
330
+ - `docs/README.md`: add the row "Environment commands: set up, check, fast check, end-to-end
331
+ tests, reset" (check: `scripts/check.sh`; the others the project's commands or "not
332
+ decided"), the planned row "Invariants" (`docs/invariants.md`), and in the rows of the agent
333
+ rules, the documentation rules, and checks and enforcement the new terms: autonomy by risk,
334
+ when a change is done, path classes and access, `.claude/path-classes`,
335
+ `.claude/harness.conf`, `.claude/settings.project.json`, `scripts/pr-metrics.sh`.
336
+
337
+ ## [0.4.1] - 2026-10-30
338
+
339
+ ### Changed
340
+
341
+ - `docs/contributing.md`, sections 3, 4, and 6 (with `dual_review`): a template update that
342
+ changes only template-owned and generated files is exempt from the dual review; its
343
+ description says "Dual review: not run: template update to X.Y.Z". The `create-pr`,
344
+ `dual-review`, and `review-code` skills apply the exemption: `review-code` takes that line in
345
+ place of a verdict.
346
+
347
+ ## [0.4.0] - 2026-10-30
348
+
349
+ ### Changed
350
+
351
+ - `docs/testing-rules.md`, section 4: a threat model of development gates. Gates catch honest
352
+ mistakes and shortcuts; deliberate evasion is left to the review of the diff; product
353
+ invariants are not development gates. The protected-paths bullet now names the forms the
354
+ protect hook catches and what is left to the review, instead of claiming that no agent loosens
355
+ a gate.
356
+ - `docs/documentation-rules.md`, section 7: the merge-readiness row names what
357
+ `scripts/check-decisions.sh --ready` checks and what is left to the owner.
358
+ - `docs/contributing.md`, section 6: a finding that only deliberate evasion can exploit to bypass
359
+ a development gate is a `nit`, a bypass of a product invariant keeps its severity, and a table
360
+ of `should` and `nit` examples calibrates every reviewer. The Tests criterion includes the test
361
+ plan. With `dual_review`, later rounds add the owner's decisions on the branch to the brief, and
362
+ nothing else.
363
+ - `docs/contributing.md`, section 1: "one logical change" means one mechanism with its tests and
364
+ owner documents, with examples.
365
+ - `docs/contributing.md`, section 3: the description gains the sections "Test plan" (always,
366
+ written before the implementation) and "Owner decisions to confirm" (each `Decided by the
367
+ owner` marker added on a chat instruction, confirmed by the owner with one comment); a pull
368
+ request is ready to merge only after that confirmation. `scripts/check-decisions.sh --ready`
369
+ does not check the confirmation.
370
+ - `docs/documentation-rules.md`, sections 3 and 7: a statement about a check names the forms it
371
+ catches and what is left to the review; an absolute claim needs a test for each form it covers.
372
+ - `create-pr` skill: writes the two new sections and reports unconfirmed owner decisions as
373
+ waiting on the owner. `review-code` skill: compares the code and tests with the test plan.
374
+ `dual-review` skill: an author's self-check before the first round, the severity examples and
375
+ the test plan in the brief, and the owner's decisions from the second round.
376
+
377
+ ### Fixed
378
+
379
+ - `.claude/hooks/protect-docs.sh`: judges a target path by the git repository that holds it when
380
+ that repository has `.template/owned.txt`, so an edit in a sibling git worktree, or in another
381
+ generated project, asks the owner like an edit in the session's own checkout. Other paths
382
+ inside the session's project are judged by the project as before (no git yet, a nested
383
+ repository); paths elsewhere stay unguarded. A relative path of a shell command resolves
384
+ against the hook input's `cwd`.
385
+ - `.claude/hooks/protect-docs.sh`: folds `.` and `..` in the part of a target path that does not
386
+ exist yet before the match, so a write to `newdir/../AGENTS.md` or `docs/new/../README.md` asks
387
+ the owner, and a path whose `..` leaves the repository no longer matches a protected glob.
388
+
389
+ ## [0.3.1] - 2026-10-30
390
+
391
+ ### Changed
392
+
393
+ - `docs/contributing.md`, section 6: defines the severities `blocker`, `should`, and `nit`, and
394
+ that a review fails on a `blocker` or `should` only; a reviewer who hesitates picks `nit`. The
395
+ `review-code`, `docs-review`, and `dual-review` skills apply these definitions, and a `nit` no
396
+ longer fails a round of the dual review.
397
+ - `review-code` and `docs-review` skills: in a pull request run they read changed files of
398
+ `.claude/`, `CLAUDE.md`, and `.mcp.json` from the diff and `.claude-pr/`, because
399
+ `anthropics/claude-code-action` restores those paths from the base branch.
400
+
401
+ ## [0.3.0] - 2026-10-30
402
+
403
+ ### Added
404
+
405
+ - Testing rules (`docs/testing-rules.md`), template-owned: what a test is for, how it proves
406
+ behaviour, tests and the change they cover, and the gates no agent loosens. `AGENTS.md`,
407
+ section 2, points to it; `docs/documentation-rules.md`, sections 2, 6, and 7, list it.
408
+ - Review of pull requests (`docs/contributing.md`, section 6): a rubric that every reviewer
409
+ applies, the project's own criteria in an owner document that the map names under "Review
410
+ criteria", and the rule that a defect found after the merge names what keeps the next one out.
411
+ - Module `code_review` (question `code_review`, default on): the `code-review` workflow
412
+ (`.github/workflows/code-review.yml`) and the `review-code` skill
413
+ (`.claude/skills/review-code/SKILL.md`) review pull requests that change code, contracts,
414
+ checks, or workflows against that rubric with Claude Code, with the same secret and app as
415
+ `docs-review`, and install no plugin.
416
+ - Module `dual_review` (question `dual_review`, default off): the `dual-review` skill
417
+ (`.claude/skills/dual-review/SKILL.md`) reviews a branch before its pull request with a Claude
418
+ subagent and the Codex CLI in a read-only sandbox, after a passing `scripts/check.sh`, for at
419
+ most three rounds, without commits; its verdict goes under "Checks" in the description
420
+ (`docs/contributing.md`, sections 3 and 4).
421
+
422
+ ### Changed
423
+
424
+ - `create-pr` skill: waits for and answers the `code-review` run next to `docs-review`, and with
425
+ the `dual_review` module runs the dual review when the branch has no verdict for its tree.
426
+ - `docs/contributing.md`, section 3: every review comment is answered before the merge, from
427
+ either review workflow.
428
+ - Linter configuration (`.markdownlint-cli2.jsonc`): in `CHANGELOG.md`, headings need to be
429
+ unique among siblings only, so that each version can have its own Added and Changed.
430
+ - Seeded `docs/README.md`: rows for the testing rules and the review of pull requests, and the
431
+ planned "Review criteria" section. An existing project copies these rows by hand.
432
+
433
+ ## [0.2.0] - 2026-10-29
434
+
435
+ ### Changed
436
+
437
+ - `create-pr` skill (`.claude/skills/create-pr/SKILL.md`), with the `docs_review` module: after
438
+ opening the pull request it waits for the `docs-review` run, answers every comment (a fix in
439
+ its own commit, a decline with a reason, or a question for the owner), records the outcome in
440
+ the description, and reports it; a draft or a run that does not finish is reported instead of
441
+ waited for. `docs/contributing.md`, section 4, names the new step.
442
+
443
+ ## [0.1.0] - 2026-10-29
444
+
445
+ ### Added
446
+
447
+ - Agent rules (`AGENTS.md` with one project block, `CLAUDE.md`), documentation rules with file
448
+ ownership (`docs/documentation-rules.md`), contribution and template update rules
449
+ (`docs/contributing.md`), and the seeded documentation map (`docs/README.md`).
450
+ - Short decision records: `docs/decisions/adr-template.md` and the generated index
451
+ `docs/decisions/README.md` (`scripts/gen-decisions-index.sh`).
452
+ - Checks behind one entry point, `scripts/check.sh`: documentation (markdownlint-cli2, lychee),
453
+ decision records (integrity, next number, index, merge readiness), template integrity
454
+ (`.template/owned.sha256`), and project checks from `scripts/checks.d/`.
455
+ - Claude Code hooks (protect, Stop checks, project Stop hooks from `.claude/hooks/project/stop/`)
456
+ and skills (`create-pr`, `update-template`, and `docs-review` as the `docs_review` module).
457
+ - CI workflows `docs` (with Node.js set up), `decisions`, and `docs-review`, with the runner chosen
458
+ by a question and overridable by the repository variable `CI_RUNS_ON`.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dev-oleksandrv and the contributors of xandronak/agent-docs-template
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,78 @@
1
- # Temporary Holding Version
1
+ # create-afe-project
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ An npm package that creates agent-friendly repositories and keeps them up to date. It gives a new
4
+ project its documentation rules, short decision records with a generated index, contribution and
5
+ pull request rules, checks that run the same way locally, in Claude Code hooks, and in CI, and the
6
+ Claude Code skills that apply them. It implements the pillars of
7
+ [Agent-Friendly Engineering](https://github.com/dev-oleksandrv/afe/blob/main/GUIDE.md). Repository:
8
+ `dev-oleksandrv/create-afe-project`; it started as a fork of the Copier template
9
+ `xandronak/agent-docs-template`.
10
+
11
+ ## What a generated project gets
12
+
13
+ | Part | Files |
14
+ | --- | --- |
15
+ | Agent rules | `AGENTS.md` with one project block, `CLAUDE.md` |
16
+ | Testing rules: what a test is for and must prove | `docs/testing-rules.md` |
17
+ | Documentation rules, statuses, and file ownership | `docs/documentation-rules.md`, `docs/README.md` |
18
+ | Branches, commits, pull requests, template updates, review of pull requests | `docs/contributing.md` |
19
+ | Decision records | `docs/decisions/adr-template.md`, a generated `docs/decisions/README.md` |
20
+ | Checks and environment | `scripts/check.sh` and the scripts it runs, the link check `scripts/check-links.mjs` included; `scripts/env.sh` for the environment commands; `scripts/protect-branch.sh` for the repository settings and the GitHub ruleset of `main`; optional `scripts/check-acceptance.sh` and `scripts/fail-without-change.sh` |
21
+ | Claude Code hooks, permissions, and skills | `.claude/settings.json` (generated): deny rules for secrets and destructive pushes; `.claude/hooks/`: the protect hook (asks before protected edits, publishing, and a known token format; denies a push to `main`), the check after every edit, and the Stop hooks; `.claude/skills/`: `afe-init` (sets up the code, its stack, and its checks with the owner), `create-pr`, `update-template`, optional `docs-review`, `review-code`, and `dual-review` |
22
+ | CI | `.github/workflows/` (`docs`, `decisions`, optional `secret-scan`, `docs-review`, `code-review`, and `fail-without-change`) |
23
+
24
+ Every file has one owner: the template, the project, or a generator. The rules are in
25
+ [`template/docs/documentation-rules.md.jinja`](template/docs/documentation-rules.md.jinja),
26
+ section 9.
27
+
28
+ ## Requirements
29
+
30
+ Node.js 20 or later with npm, Git, and bash. A generated project needs nothing more: its hooks
31
+ and checks, the link check included, run on Node.js.
32
+
33
+ ## Create a project
34
+
35
+ ```bash
36
+ npm create afe-project@latest <directory>
37
+ # or
38
+ npx create-afe-project@latest <directory>
39
+ ```
40
+
41
+ The wizard asks for the project name, a one-sentence description, the GitHub repository, the CI
42
+ runner (GitHub-hosted, or a self-hosted Linux runner), whether pull requests get the Claude
43
+ documentation review and code review, whether the review before a pull request adds the Santa
44
+ loop (with the Codex CLI when it is installed, otherwise with two Claude subagents), whether CI
45
+ scans every change for secrets with gitleaks, and whether to add the Acceptance check and the
46
+ fail-without-change driver. It then writes the generated files and prints the next
47
+ steps. Without a terminal, or with `--defaults`, it takes answers from `--data key=value` and
48
+ `--data-file answers.json`, then the defaults:
49
+
50
+ ```bash
51
+ npx create-afe-project@latest acme --defaults --data project_name=acme \
52
+ --data 'project_description=A sample project.' --data github_repo=acme/acme
53
+ ```
54
+
55
+ `npx create-afe-project --help` lists every option.
56
+
57
+ ## Update a project
58
+
59
+ In the project, the `update-template` skill does it, following the project's
60
+ `docs/contributing.md`, section 5: a branch from a clean `main`, then
61
+
62
+ ```bash
63
+ npx create-afe-project@latest update --defaults
64
+ ```
65
+
66
+ It replaces the template-owned files, keeps the project block of `AGENTS.md`, creates missing
67
+ seeded files and never changes existing ones, runs the migrations between the two versions, and
68
+ regenerates the generated files; then the checks and a pull request. A project generated by the
69
+ Copier template converts its `.copier-answers.yml` to `.afe-answers.json` on its first update.
70
+
71
+ ## Versions
72
+
73
+ Releases are npm versions, tagged `vMAJOR.MINOR.PATCH` in Git and described in [`CHANGELOG.md`](CHANGELOG.md).
74
+ How versions are chosen and released: [`docs/maintaining.md`](docs/maintaining.md).
75
+
76
+ ## License
77
+
78
+ [MIT](LICENSE).