create-religion 1.2.0 → 1.3.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 (44) hide show
  1. package/CHANGELOG.md +456 -0
  2. package/README.md +2 -1
  3. package/dist/bin/religion.js +87 -7
  4. package/dist/lib/args.js +15 -5
  5. package/dist/lib/changelog.js +29 -0
  6. package/dist/lib/dashboard.js +102 -22
  7. package/dist/lib/doctor.js +134 -26
  8. package/dist/lib/install.js +43 -6
  9. package/dist/lib/paths.js +18 -0
  10. package/dist/lib/settings.js +156 -0
  11. package/dist/lib/state.js +261 -8
  12. package/dist/lib/status.js +38 -3
  13. package/dist/lib/uninstall.js +216 -0
  14. package/package.json +2 -2
  15. package/template/.agents/skills/auto/SKILL.md +9 -3
  16. package/template/.agents/skills/check/SKILL.md +69 -2
  17. package/template/.agents/skills/ci/SKILL.md +28 -0
  18. package/template/.agents/skills/complete/SKILL.md +76 -5
  19. package/template/.agents/skills/distill/SKILL.md +42 -19
  20. package/template/.agents/skills/feature/SKILL.md +19 -4
  21. package/template/.agents/skills/feature/reference/spec-template.md +1 -0
  22. package/template/.agents/skills/fix/SKILL.md +7 -0
  23. package/template/.agents/skills/implement/SKILL.md +16 -2
  24. package/template/.agents/skills/scout/SKILL.md +2 -2
  25. package/template/.agents/skills/spike/SKILL.md +8 -0
  26. package/template/.agents/skills/status/SKILL.md +17 -4
  27. package/template/.agents/skills/tests/SKILL.md +45 -3
  28. package/template/.claude/hooks/warn-on-drift.mjs +74 -0
  29. package/template/.claude/hooks/write-handoff.mjs +54 -2
  30. package/template/.claude/skills/auto/SKILL.md +9 -3
  31. package/template/.claude/skills/check/SKILL.md +69 -2
  32. package/template/.claude/skills/ci/SKILL.md +28 -0
  33. package/template/.claude/skills/complete/SKILL.md +76 -5
  34. package/template/.claude/skills/distill/SKILL.md +42 -19
  35. package/template/.claude/skills/feature/SKILL.md +19 -4
  36. package/template/.claude/skills/feature/reference/spec-template.md +1 -0
  37. package/template/.claude/skills/fix/SKILL.md +7 -0
  38. package/template/.claude/skills/implement/SKILL.md +16 -2
  39. package/template/.claude/skills/scout/SKILL.md +2 -2
  40. package/template/.claude/skills/spike/SKILL.md +8 -0
  41. package/template/.claude/skills/status/SKILL.md +17 -4
  42. package/template/.claude/skills/tests/SKILL.md +45 -3
  43. package/template/religion/.state/settings-template.json +9 -0
  44. package/template/religion/learning/journal.md +4 -3
package/CHANGELOG.md ADDED
@@ -0,0 +1,456 @@
1
+ # create-religion
2
+
3
+ ## 1.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 0731bce: For web work, `check` now scans each interface outcome for accessibility beside its browser
8
+ evidence: with the project's own axe through its browser-test harness when it has one, and
9
+ otherwise by reviewing the page's accessibility tree and keyboard focus. It reports violations per
10
+ outcome, names the method and what it does not cover, records it in the Evidence section, installs
11
+ nothing, and points anything serious at `audit`.
12
+ - 72cd015: `tests backfill` now offers to note each discrepancy it finds with `capture`, one line naming
13
+ the file and what the code does instead of what it should, so the mismatch reaches the inbox
14
+ that `fix` and `feature` read rather than being lost when the context is cleared. The failing
15
+ tests stay as they are, and the skill never writes the inbox itself.
16
+ - 8ffa7af: `check` now records its verdict for each outcome, and what decided it, in an `## Evidence`
17
+ section of the spec, stamped with the commit and whether the tree was clean, so the proof
18
+ survives a cleared context and travels into the archive. `complete` reuses that record only
19
+ when it names the current commit with a clean tree, and runs `check` again otherwise. The
20
+ dashboard's Work view shows the section.
21
+ - ee85f1c: The workflow `ci` writes also runs `religion doctor --json` on every pull request, pinned to the
22
+ installed major version, and fails the build for any failed check that blocks work or
23
+ completion, such as a stale overview or invalid configuration. Advisory checks a runner cannot
24
+ pass honestly, like `hooks` without a committed `.claude/settings.json`, appear as warnings. A
25
+ doctor that prints no report fails the build.
26
+ - 02ba42a: In a project that uses Changesets, `complete` now drafts the finished item's changeset: the
27
+ packages it touched, a proposed bump, and a summary written for the changelog's readers. It asks
28
+ before writing when someone is there, and in an automated run writes the proposal and names it in
29
+ the pull request for the reviewer to approve or change. An item that already has a changeset keeps
30
+ it.
31
+ - 97e5ee0: The dashboard gains a Deferred view: every note each archive left under its Deferred
32
+ heading, newest item first, each item linking to its archive in History. It is a record of
33
+ what was set aside and why, not a to-do list, since an archive is never edited when a note
34
+ is later done.
35
+ - 135f781: `religion doctor` checks every setting in the configuration reference with its type, not only
36
+ the enumerated ones: booleans, branch prefixes, bounded integers such as
37
+ `auto.maxRepairAttempts`, `auto.maxItems` (a positive integer or `null`), and the schema
38
+ version. A failure names the key, the value it found, and what it accepts. Keys the reference
39
+ does not name are still ignored.
40
+ - 6cd5493: A fourth Claude Code hook, `warn-on-drift.mjs`, asks before an edit to a file that neither the
41
+ active spec's current step nor its Files and areas names, pointing at an amendment when the
42
+ spec is what should change. The workflow's own state, changesets and rendered skill trees are
43
+ always allowed, and it stays silent with no spec in progress. New installs wire it; on an
44
+ existing project, `religion doctor`'s hooks check reports it until it is added to
45
+ `.claude/settings.json`.
46
+ - c4bfb56: `distill` now reads the findings archived with each finished item as a second input. Where the
47
+ same kind of finding has recurred across at least two different items, it proposes the
48
+ coding-standard rule that would have prevented them, citing the findings, and waits for
49
+ approval; each decided group is recorded so it is not proposed again.
50
+ - a346c2e: The handoff written at the end of each turn also says when the overview is stale, how many
51
+ notes are waiting in the inbox, which findings are unverified, and when a recorded run is
52
+ blocked, with the command that resumes it. Because every session loads the handoff, nothing
53
+ free-form is copied into it from the activity record: only a skill name and a resume command
54
+ that invokes that skill.
55
+ - 60f58ec: `religion doctor` gains a `hooks` check where Claude Code is installed: it confirms that
56
+ `.claude/settings.json` registers each hook this version ships, under the right event, and
57
+ that each hook's file exists, and names any that are missing with how to add them. Matchers
58
+ you have tuned still count, and a settings file that is a link is not read. Since `update`
59
+ never rewrites the settings, this is how a hook added by a later version gets noticed.
60
+ - 98c7c0e: `complete` now appends one entry to `religion/learning/journal.md` for every item it
61
+ finishes, with what surprised, what went wrong, and what was deferred and why, so `distill`
62
+ has something to read. `complete` is the journal's only writer: `distill` no longer moves
63
+ entries out of it, and instead records what it decided about each one in
64
+ `journal-archive.md`, skipping entries it has already decided on the next pass.
65
+ - 223f2e8: The dashboard gains a Learning view: the lessons every session loads, and the journal's
66
+ entries, newest first, each marked waiting until `distill` has recorded a decision on it in
67
+ `journal-archive.md`. `religion status` warns once five or more entries are waiting, which is
68
+ when a `distill` pass is worth running.
69
+ - 1bb90fa: `religion doctor` gains an advisory `managed files` check, and the dashboard's Install panel
70
+ a list, naming every installed skill or hook whose contents no longer match what was
71
+ installed, and any that are missing. That is the list `update` will report as changed
72
+ locally. Entry files are not compared, since `update` merges them, and a recorded path
73
+ outside the skill and hook trees, or one that is a link, is never read.
74
+ - b4c6167: `check` now names the passing command-line and API outcomes that could become regression
75
+ tests and, where a test command is declared, offers `tests evidence` to keep them. The new
76
+ `evidence` mode of `tests` reads the spec's Evidence section, re-runs each capture, and writes
77
+ one reviewed test per outcome, asserting the exit status and the stable parts of the output.
78
+ Interface outcomes stay browser evidence.
79
+ - 68f41cd: A build-plan line that says `after item N` (or `after items N, M and K`) waits until those are
80
+ ticked, and one that says `spike first` waits until a spike archive records `**For:** item N`
81
+ and `**Settled:** yes`. `religion status`, `feature` with no argument, and `auto` take the first
82
+ item that waits on nothing and name the ones passed over; when every remaining item waits on a
83
+ spike, `status` points at `spike`. A reference to an item the plan does not have, or items that
84
+ wait on each other, is reported as a warning. `status --json` keeps its shape.
85
+ - 3d0cb15: `check preview` runs the spec's outcomes against the preview deployment the host built for the
86
+ pull request, as well as locally. It finds the address from the deployments recorded for the
87
+ head commit through the host's own tool (`gh` on GitHub), asking before each network read
88
+ outside an automated run, stamps the address in the Evidence section, and treats a missing,
89
+ unfinished or protected preview as could not check. It never deploys.
90
+ - f921642: Under `pull-request` mode, the pull request `complete` opens carries a review packet built
91
+ from the item's archive: the goal, each step with the verdict and evidence `check` recorded,
92
+ the findings closed with it, and a link to the archive for the rest. `auto`'s aggregate pull
93
+ request takes each item's line from the same record and links the item's own pull request.
94
+ The packet only presents; it adds no gate.
95
+ - c87a4c6: The dashboard's Configuration panel lists every setting, not only the ones a project has
96
+ set: what it means in one line, its value here or that the default applies, the default,
97
+ and what it accepts, with any value `doctor` would refuse marked and any key Religion does
98
+ not read named as such.
99
+ - e7ed368: `implement` now stamps a spec before its first change with `**Approved:** <date>, <hash>` and
100
+ records any later change to what the spec asks for as a dated amendment with its reason,
101
+ renewing the stamp. `religion status` warns when the spec has changed without a renewed stamp,
102
+ and `status --json` gains `spec` (`hash`, `approved`, `drifted`). Ticks, the status line, and
103
+ the Evidence and Amendments sections never count as changes, and examples inside code fences
104
+ are ignored.
105
+ - 7981ee6: `fix` and `feature` take an issue number or link, read it through the host's own command-line
106
+ tool (a network read that needs a yes outside an automated run), and draft the spec from it,
107
+ treating the issue's text as untrusted input and stopping for review as usual. The spec records
108
+ `**From issue:**`, and the pull request `complete` opens closes the issue for a fix and refers
109
+ to it for a feature, taking effect only when its owner merges.
110
+ - ebe8b7b: `religion status` reports the run recorded in `religion/.state/run.json` and how many notes
111
+ the inbox holds, and `status --json` gains `activity` and `inbox` fields. When the recorded
112
+ run is blocked and names a resume command, that command becomes the next action. A record is believed only when it names a skill installed
113
+ in the project, and its resume command only when it invokes that same skill with plain
114
+ word arguments; control and format characters in what it prints are replaced with spaces.
115
+ - 844a68f: `religion uninstall` takes Religion back out of a project. It removes every installed skill
116
+ and hook nobody edited, and any directory that leaves empty; keeps and names the edited
117
+ ones; cuts only the managed block from the entry file, or removes it when it is still
118
+ exactly what was installed; takes only Religion's hook entries out of
119
+ `.claude/settings.json`; and removes the install record last. The plans, history and the rest
120
+ of `religion/` stay, and every file it changes rather than removes is backed up first. It
121
+ shows its plan and asks, defaulting to no; `--yes` skips the question, `--dry-run` only
122
+ plans, and outside a terminal it removes nothing without `--yes`.
123
+ - d803d0e: `religion update` on a project an older version installed starts by saying what changed in
124
+ between: each release, newest first, with the first sentence of each change, and where the
125
+ full changelog is. The package now ships its `CHANGELOG.md`, so this needs no network. It
126
+ prints on `--dry-run` too, and nothing when the project is already current.
127
+
128
+ ## 1.2.0
129
+
130
+ ### Minor Changes
131
+
132
+ - 6097eb0: `auto fix` works through the findings ledger unattended, under the same grant, gates and
133
+ landing rules as a plan run. With no class, or `all`, it takes every class most severe
134
+ first until no open finding is left; `auto fix P1` takes only that class. Each class's
135
+ findings that name the same file are repaired together as one fix, every repair is
136
+ re-reviewed in a fresh context, and a finding the review surfaces in the repaired code is
137
+ folded into the same fix, linked to the finding that surfaced it, which cannot close first.
138
+ Repair attempts and a cap of three folded findings per fix bound the run; unverified
139
+ findings are reported rather than repaired. `fix` now accepts several finding identifiers,
140
+ and `audit` records the `Surfaced by` link.
141
+
142
+ ## 1.1.0
143
+
144
+ ### Minor Changes
145
+
146
+ - 624001c: `religion dashboard` is rebuilt as an operational console with an overview and four views,
147
+ following the system's light or dark theme and updating live. Work shows the active spec as
148
+ written: its goal, every step with what it builds and when it is done, its scope and files.
149
+ Findings charts the ledger by lens, by file and by the item that closed each one, and lists
150
+ every finding in full with status and severity filters. History lists what shipped, with its
151
+ commits, repairs, closed findings, lessons and deferrals, beside the plan. Health shows the
152
+ activity record, doctor's checks, the configuration, the install and the inbox, and says
153
+ when the project was installed by an older version than the one running. The page still
154
+ loads nothing but its own data, under the same policy.
155
+
156
+ `status --json` now reports the whole name of the next step in `work.nextStep`, such as
157
+ `Step 3 - client`, where it was cut at the first ` - ` before. A dashboard that cannot read
158
+ the project answers with the error instead of stopping.
159
+
160
+ ## 1.0.0
161
+
162
+ ### Major Changes
163
+
164
+ - 0794c6e: Religion 1.0. From this release the public surface is stable: a 1.x release will not remove,
165
+ rename or narrow anything the [stability statement](https://github.com/foo-stack/religion/blob/main/docs/stability.md)
166
+ names as public, and [Updating a project](https://github.com/foo-stack/religion/blob/main/docs/upgrading.md)
167
+ walks through what an update does.
168
+
169
+ Breaking changes since 0.5.0:
170
+
171
+ - **Node 22 or later is required.** Node 20 has reached its end-of-life.
172
+ - **Unrecognised input is refused.** An unknown command, an unknown option, an option the
173
+ command does not take, or a second directory now exits 2 with a usage error instead of
174
+ being ignored or taken as the target directory.
175
+ - **Exit codes are fixed**: `0` for success, `1` for a reported failure, `2` for a usage
176
+ error. `install` and `update` now exit 1 when they leave conflicts, a declined entry-file
177
+ merge, or files reached through a symbolic link, where they used to exit 0.
178
+ - **`doctor --json` prints an object**, `{ "schemaVersion": 1, "healthy": ..., "checks": [...] }`,
179
+ instead of a bare array. Read `.checks` where you read the array before.
180
+ - **The dashboard answers only requests addressed to it.** A request whose `Host` is not its
181
+ own `127.0.0.1` or `localhost` address and port gets a 403, so a tunnel that rewrites the
182
+ host to another port is refused. Every response carries a content security policy, and
183
+ the page loads nothing beyond its own data.
184
+ - **`update` refuses a project a newer version installed**, and never writes through a
185
+ symbolic link, even with `--force`.
186
+
187
+ ### Minor Changes
188
+
189
+ - d175f26: The command-line tool refuses input it does not understand, and its exit codes and JSON
190
+ output are fixed.
191
+
192
+ Four changes are visible to anyone scripting against it:
193
+
194
+ - **Unrecognised input is refused.** An unknown command, an unknown option, an option that
195
+ does not apply to the command, or more than one directory now prints a usage error and
196
+ exits 2 before anything is written. Previously an unknown option was ignored, so
197
+ `religion update --dryrun` performed a real update, and an unknown word became the target,
198
+ so `religion stauts` installed into a new `./stauts`. A bare directory that already exists
199
+ is still accepted, so `npx create-religion ./app` installs into it as before.
200
+ - **`install` and `update` exit 1 when conflicts remain.** A file left alone because it was
201
+ edited locally used to exit 0, which made a partial update look complete. That includes
202
+ an entry-file merge that was declined, and a non-interactive run without `--yes` declines
203
+ it on its own. Exit codes are now `0` for success, `1` for a reported failure, and `2` for
204
+ a usage error, listed in `--help` and the readme.
205
+ - **`doctor --json` is an object, not an array.** It prints
206
+ `{ "schemaVersion": 1, "healthy": ..., "checks": [...] }`. Each check keeps its shape. Read
207
+ `.checks` where you read the array before.
208
+ - **The dashboard refuses requests not addressed to it.** Anything whose `Host` header is not
209
+ its own `127.0.0.1` or `localhost` address and port gets a 403, which closes a DNS
210
+ rebinding path to the project state it serves.
211
+ - 5a7316a: A new `scout` skill proposes features to build next, grounded in what the codebase, the
212
+ plans and the shipped history already contain. Run it as `scout`, `scout ambitious` or
213
+ `scout super-ambitious`: normal suggests five low-risk extensions of what exists, ambitious
214
+ three new capabilities that combine existing pieces or serve a new kind of user, and
215
+ super-ambitious two bets that would change the product's direction, stack or deployment.
216
+ Each idea names the files it builds on, its size and its risks. It writes nothing; the idea
217
+ you pick goes to `feature`, whose intake proposes the plan line.
218
+ - 0787693: `setup` now drafts both plans from a repository that already exists, instead of describing
219
+ the idea of doing so.
220
+
221
+ Its frontmatter has always claimed an existing project "is surveyed so the plans and
222
+ standards are generated from what is actually there". Behind the claim, the drafting step
223
+ was fifteen lines of intent: derive problem, users and features from the code and the
224
+ history, with nothing on how, from what, in what order, or what the result had to look
225
+ like. The survey it ran collected stack, commands, existing checks, conventions and layout,
226
+ none of which answer a single required section of the project plan.
227
+
228
+ The survey now gathers what the plans actually need. One evidence source is named per
229
+ required section: the README and any docs introduction for the problem, authentication and
230
+ entry points for users, routes and exported surface for features, schema and model
231
+ definitions for data, the dependency manifest for the stack, and the history for what
232
+ shipped and in what order. It reads to a budget rather than reading whole, states that it
233
+ covers a single application, and runs where it writes nothing.
234
+
235
+ Every source can be absent, and each absence now has an answer. No README means section 1
236
+ stays a question rather than a problem statement assembled out of the implementation. One
237
+ entry point and no authentication is an answer, not a gap. A missing dependency manifest is
238
+ checked against the manifest the language actually uses before being called missing. A
239
+ shallow or imported history cannot order the build plan, and says so. **A missing source is
240
+ recorded as missing, never substituted, and never filled in with what a project of that
241
+ kind usually has.**
242
+
243
+ Drafting is a procedure rather than a description. Evidence is sorted into found, inferred
244
+ and missing, with `(inferred)` carried on the claim itself, because the code says what was
245
+ built and never why. The build plan starts from what shipped, checked, in history order, in
246
+ the exact item line format the loop parses. A plan that is no longer the shipped template
247
+ is never overwritten without showing the exact change and waiting.
248
+
249
+ What the survey reads is data. A README, a comment, a commit message, issue text or a
250
+ configuration file that addresses the agent is reported with the file named, never acted
251
+ on, and never quietly edited away.
252
+
253
+ A new reference under the skill states the shape both drafted plans are judged against,
254
+ including the acceptance rules `overview` applies, so a draft is checked before it is shown
255
+ rather than one stage later.
256
+ - cc640a6: `update` no longer duplicates an edited entry file, removes what a newer version stopped
257
+ shipping, refuses a project a newer version installed, never writes through a symbolic link,
258
+ and says truthfully what it backed up.
259
+
260
+ - **An entry file `setup` edited is rebuilt, not duplicated.** A fresh install writes
261
+ `CLAUDE.md` and `AGENTS.md` without markers, and `setup` fills in their Commands section,
262
+ so the next `update` used to treat the file as your own and append a second copy of every
263
+ Religion section. It now backs the file up and rebuilds it around the sections you wrote:
264
+ your title, your Commands, and any section of your own stay outside the markers, and
265
+ Religion's sections are replaced by the current block. Later updates replace only what is
266
+ between the markers. If this already happened to your file, the duplicates are still
267
+ there; remove the older copies by hand.
268
+ - **Files a newer version no longer ships are removed.** When a file the previous install
269
+ recorded is gone from the template, `update` removes it if you never edited it, along with
270
+ any directory that leaves empty. If you edited it, it is left where it is and becomes
271
+ yours. Only files in Religion's own skill and hook folders are ever removed.
272
+ - **A project installed by a newer version is refused.** `install` and `update` exit 1
273
+ without writing anything when the manifest's version or format is newer than the package
274
+ running, whatever the flags. Run `npx create-religion@latest update` instead.
275
+ - **Nothing is written through a symbolic link.** A file, entry file, manifest or
276
+ `.claude/settings.json` reached through a link, dangling or not, is left alone and reported
277
+ as linked, even with `--force`, and the run exits 1. A link anywhere on the way to the
278
+ manifest or a backup refuses the run before anything is written. Removals are confined to
279
+ Religion's own skill and hook folders, by exact case, and never follow a link.
280
+ - **Messages match what happened.** A declined entry-file merge is reported on its own,
281
+ rather than as a local edit with `--force` advice that would not merge it. The merge prompt
282
+ and the getting-started walkthrough no longer claim a declined merge is backed up, and the
283
+ backup line says where backups went.
284
+
285
+ ### Patch Changes
286
+
287
+ - 73226c1: Three guides for people who did not build Religion.
288
+
289
+ Everything under `docs/` was written for someone who already knew the system: the state
290
+ model, the enforcement split, the configuration reference, the decision records. They
291
+ explain how it is built. Nothing explained how it is used, and the readme's getting-started
292
+ section was four lines naming four skills.
293
+
294
+ - **Getting started** walks install through to a generated overview, covering both branches
295
+ `setup` takes, what the installer does when you already have a `CLAUDE.md` or `AGENTS.md`,
296
+ what happens when a codebase's readme explains nothing, and the choice between committing
297
+ the workflow files and keeping them local.
298
+ - **What the loop actually feels like** walks one finished work item from spec to commit:
299
+ the spec arriving before any code, the diff and evidence under each step, what the review
300
+ options do, how progress survives a cleared context, what the findings ledger blocks, and
301
+ what completion archives. Every artifact in it is quoted from a real file.
302
+ - **What to do when doctor complains** covers every check, what each failure means, and the
303
+ fix. Every failure was triggered deliberately and every fix was run and shown to clear it,
304
+ which caught two that were wrong: `update` alone does not restore a working entry file,
305
+ and deleting `config.json` makes the project invisible to the command-line tool rather
306
+ than falling back to defaults.
307
+
308
+ The readmes now point at these rather than half-repeating them, and the package readme's
309
+ skill count is correct again.
310
+ - 195db9f: A repeated adapter option, such as `--claude --claude`, is recorded once. It used to be
311
+ listed twice in the install summary and written twice into the manifest.
312
+
313
+ ## 0.5.0
314
+
315
+ ### Minor Changes
316
+
317
+ - 2fe62e1: The shell-command guard hook is removed.
318
+
319
+ It asked before a push, merge, publish, deploy or recursive delete, and it matched how those
320
+ commands are usually written rather than what they do. `bash deploy.sh` pushed and passed
321
+ silently; so did a one-line script that deleted a tree. Meanwhile it asked about throwaway
322
+ directories several times an hour.
323
+
324
+ Adding patterns does not fix that. The next spelling is one substitution away, and a pattern
325
+ broad enough to catch every script would ask about every script. A guard that catches the
326
+ common spelling of a dangerous action and silently misses the rest is worse than no guard,
327
+ because the gap is invisible to whoever is relying on the prompt.
328
+
329
+ **Nothing about the Authority rules changed.** Merging, pushing, deploying, publishing,
330
+ deleting data and rewriting history are still first tier and still need an explicit yes every
331
+ time. That rule is carried by the prose loaded every session, which applies to all four
332
+ supported tools rather than to one way of typing a command.
333
+
334
+ Three hooks remain, all cases where a pattern can describe the thing being protected: a write
335
+ into a rendered tree, content being read, and the end of a turn.
336
+
337
+ ### Patch Changes
338
+
339
+ - 8148887: The first-tier guard hook no longer asks about `rm -rf`.
340
+
341
+ The pattern caught the common spelling of a dangerous action and missed every other one:
342
+ `find -delete`, a one-line script, or the same effect through any other tool all passed
343
+ silently. Meanwhile it asked constantly about throwaway directories, which is most of what
344
+ `rm -rf` is used for.
345
+
346
+ A guard that catches one spelling and invisibly misses the rest is worse than no guard,
347
+ because the person relying on it cannot see the gap. Deleting data is still first tier and
348
+ still requires an explicit yes; that rule lives in the Authority prose, which applies to all
349
+ four supported tools rather than to one way of typing a command.
350
+
351
+ The enforcement reference now states plainly what these patterns match, and what they do
352
+ not, so the hooks are not mistaken for a guarantee.
353
+
354
+ ## 0.4.0
355
+
356
+ ### Minor Changes
357
+
358
+ - 8eeb556: Installing into a repository that already has a `CLAUDE.md` or `AGENTS.md` now offers to merge
359
+ instead of leaving the workflow unwired.
360
+
361
+ Previously those files were reported as conflicts and left alone, which was safe and not much
362
+ use: the skills and state landed on disk, but nothing told the agent that Religion existed.
363
+ Replacing them was never an option, since an entry file someone wrote by hand is often the
364
+ most carefully considered file in the repository.
365
+
366
+ Everything you wrote stays exactly where it is. Religion's sections are appended inside
367
+ markers, and a later `update` replaces only what is between them and never reads what is
368
+ outside. Your own `Commands` section is left alone rather than overwritten with the
369
+ placeholder, and the import lines live inside the block so new context files keep arriving.
370
+
371
+ Decline and the file is untouched and reported as a conflict, exactly as before. The original
372
+ is backed up under `religion/.state/backups/` either way.
373
+
374
+ ## 0.3.0
375
+
376
+ ### Minor Changes
377
+
378
+ - fe84621: Add `git.mode: pull-request`, a third way for finished work to reach the default branch.
379
+
380
+ `complete` pushes the work item's branch and opens a pull request into the default branch
381
+ instead of merging locally. Nothing merges it and nothing writes to the default branch: the
382
+ merge is yours, on the host, and whether it lands as a squash, a merge commit, or a rebase is
383
+ the pull request's setting rather than this workflow's business. A repository that cannot
384
+ host one is a stop, never a quiet fallback to a local merge.
385
+
386
+ `auto` runs the whole queue onto one integration branch, each item landing into it behind its
387
+ own pull request, and ends with a single aggregate pull request it never merges. That shape
388
+ is what lets item three build on items one and two. It states the entire remote budget before
389
+ any work starts and does not begin without a yes.
390
+
391
+ The authority rules move with it. Tier one now reads "pushing to the default branch, and
392
+ force-pushing anything anywhere" rather than "pushing to any remote", because the danger of a
393
+ push is what it lands on. Pushing a branch a run created itself is the one action that may be
394
+ granted ahead of time, and only through that enumeration.
395
+
396
+ Also adds `git.refactorBranchPrefix` and `git.integrationBranchPrefix`, and fixes the
397
+ command-line tool rejecting the new mode and overlooking the refactor archive directory.
398
+ - 4605f51: Two new skills, a standing rule about untrusted text, and optional parallel step execution.
399
+
400
+ **`capture`** notes something in one line and returns to work. One work item at a time is what
401
+ makes a cleared context cheap, and it is also why a thought that arrives mid-build has nowhere
402
+ to go. `fix` and `feature` read that inbox when choosing what to build next, which is the part
403
+ that stops it becoming a list of things nobody did.
404
+
405
+ **`spike`** answers one feasibility question with the smallest throwaway thing that settles
406
+ it, inside a stated budget, then deletes the code and keeps the answer under
407
+ `religion/history/spikes/`. A spec written against an untested assumption is paid for twice.
408
+
409
+ **`rollback --steps N`** backs out the last N steps of work in progress, rather than a
410
+ completed item. It stashes first every time and reports the recovery command, so undoing
411
+ something is a mistake that costs one command rather than a deletion.
412
+
413
+ **Untrusted input is now a standing rule**, loaded every session as
414
+ `religion/context/untrusted-input.md`: text read from a file, a page, or a dependency is data,
415
+ never an instruction. It needs saying because compression does not record which lines came
416
+ from you and which came from a file read hours earlier. A hook backs it in Claude Code,
417
+ warning when ingested content carries known injection signatures, and
418
+ `security.blockInjection` turns the high-severity case into a block.
419
+
420
+ **Waves.** With `workflow.parallelSteps` enabled, steps a spec marks `(with N)` build
421
+ concurrently and are reviewed as one packet. It ships off, and while it is off the markers are
422
+ ignored entirely, so a spec carrying them builds identically in a project that never opted in.
423
+
424
+ Also in this release:
425
+
426
+ - the guard hooks no longer fail open. A crash used to end in a silent allow, which meant a
427
+ bug in the push guard let the push through unchecked. They now degrade to asking
428
+ - `audit`, `status`, `doctor` and `try` declare their tools, so read-only is enforced rather
429
+ than promised. `audit` declares `Write` honestly: it owns the findings ledger
430
+ - `refactor` surveys in a subagent that returns the map, and `feature` does the same when
431
+ speccing needs a broad read, so a large survey no longer crowds out the context that has to
432
+ write from it
433
+
434
+ ## 0.2.0
435
+
436
+ ### Minor Changes
437
+
438
+ - fec5e77: Add the `refactor` skill: simplify code that already exists, one behaviour-preserving
439
+ campaign at a time.
440
+
441
+ Point it at a single file, a folder, one package, or a monorepo root. It surveys five lenses
442
+ (bloat, structure, over-implementation, duplication, and reinvention of what the language,
443
+ the standard library, or an installed dependency already provides), reports where the density
444
+ is, then specs one lens in one area for `implement` to build.
445
+
446
+ It refuses to start when no test reaches the target. A change meant to preserve behaviour
447
+ needs something able to notice when it does not, and a green suite that never imports the
448
+ target is not that.
449
+
450
+ ## 0.1.1
451
+
452
+ ### Patch Changes
453
+
454
+ - c9e7b11: Document the invocation that actually works. The readme and `--help` both showed
455
+ `religion <command>`, which exists only after a global install, so anyone following
456
+ `npx create-religion@latest` found the command missing.
package/README.md CHANGED
@@ -35,6 +35,7 @@ npx create-religion status # where the work stands, and the one thing to do
35
35
  npx create-religion doctor # is the setup healthy
36
36
  npx create-religion dashboard # a local read-only view
37
37
  npx create-religion update # update the workflow files, preserving yours
38
+ npx create-religion uninstall # take it back out, keeping the plans and history
38
39
  ```
39
40
 
40
41
  Installing the package globally shortens these to `religion status` and the rest.
@@ -49,7 +50,7 @@ The same for every command, so a script can rely on them:
49
50
  | Code | Meaning |
50
51
  | --- | --- |
51
52
  | `0` | the command did what it was asked |
52
- | `1` | it ran and reports failure: no project found, a failing `doctor` check, conflicts, declined merges or linked files left by `install` or `update`, a project installed by a newer version, or an unexpected error |
53
+ | `1` | it ran and reports failure: no project found, a failing `doctor` check, conflicts, declined merges or linked files left by `install` or `update`, a file `uninstall` meant to change but left, a project installed by a newer version, or an unexpected error |
53
54
  | `2` | usage error: nothing was written |
54
55
 
55
56
  ## Documentation
@@ -11,11 +11,13 @@ import fsSync from "node:fs";
11
11
  import path from "node:path";
12
12
  import readline from "node:readline/promises";
13
13
  import { fileURLToPath } from "node:url";
14
- import { parseArgs } from "../lib/args.js";
14
+ import { EXIT_CODES, parseArgs } from "../lib/args.js";
15
+ import { changesSince } from "../lib/changelog.js";
16
+ import { applyUninstall, planUninstall, uninstallRoot } from "../lib/uninstall.js";
15
17
  import { startDashboard } from "../lib/dashboard.js";
16
18
  import { doctorReport, renderDoctor, runDoctor } from "../lib/doctor.js";
17
19
  import { ADAPTERS, applyInstall, BACKUPS, manifestRefusal, planInstall, readManifest, wireHooks, writeManifest } from "../lib/install.js";
18
- import { findProjectRoot } from "../lib/paths.js";
20
+ import { findProjectRoot, STATE_DIR } from "../lib/paths.js";
19
21
  import { readProjectState } from "../lib/state.js";
20
22
  import { computeStatus, renderStatus } from "../lib/status.js";
21
23
  const here = path.dirname(fileURLToPath(import.meta.url));
@@ -56,6 +58,16 @@ async function main(argv) {
56
58
  return printHelp();
57
59
  if (options.command === "install" || options.command === "update")
58
60
  return runInstall(options);
61
+ if (options.command === "uninstall") {
62
+ const named = await uninstallRoot(options.target);
63
+ if (!named) {
64
+ console.error(`No Religion project in ${path.resolve(options.target)}. Uninstall acts only on the directory it is given,`);
65
+ console.error("never a parent found by walking up, so run it from the project root or name that directory.");
66
+ process.exitCode = 1;
67
+ return;
68
+ }
69
+ return runUninstall(named, options);
70
+ }
59
71
  const root = await findProjectRoot(options.target);
60
72
  if (!root) {
61
73
  console.error("No Religion project found here or in any parent directory.");
@@ -95,6 +107,8 @@ async function runInstall(options) {
95
107
  if (updating && !previous) {
96
108
  console.log("No manifest found. Files matching the template will be adopted; others are conflicts.");
97
109
  }
110
+ if (updating && previous)
111
+ await printChanges(previous.version, packageVersion);
98
112
  const adapters = options.adapters ?? previous?.adapters ?? (await chooseAdapters(options.yes));
99
113
  const plan = await planInstall(templateRoot, target, adapters, previous);
100
114
  const counts = {
@@ -238,6 +252,73 @@ async function chooseAdapters(assumeYes) {
238
252
  .filter((a) => a !== undefined);
239
253
  return chosen.length > 0 ? chosen : all;
240
254
  }
255
+ const UNINSTALL_LABELS = {
256
+ remove: "remove",
257
+ "remove-manifest": "remove",
258
+ "cut-block": "cut Religion's block from",
259
+ unwire: "take Religion's hooks out of",
260
+ "keep-edited": "keep, edited since install:",
261
+ "keep-linked": "keep, not a plain file:",
262
+ "keep-entry": "keep, cannot be split safely:",
263
+ "keep-settings": "keep, could not be read:"
264
+ };
265
+ /** Show the plan, then carry it out only with `--yes` or a yes at the prompt. */
266
+ async function runUninstall(root, options) {
267
+ const plan = await planUninstall(root);
268
+ if (plan.length === 0) {
269
+ console.error("No install record found, so there is nothing Religion knows it installed here.");
270
+ process.exitCode = 1;
271
+ return;
272
+ }
273
+ console.log(`\nUninstalling Religion from ${root}. The plans, history and the rest of ${STATE_DIR}/ stay.\n`);
274
+ for (const entry of plan) {
275
+ console.log(` ${UNINSTALL_LABELS[entry.action]} ${entry.relative}${entry.why ? ` (${entry.why})` : ""}`);
276
+ }
277
+ if (options.dryRun) {
278
+ console.log("\nDry run. Nothing removed.");
279
+ return;
280
+ }
281
+ if (!(await confirmUninstall(options.yes))) {
282
+ console.log("\nNothing removed. Run with --yes to remove what is listed.");
283
+ return;
284
+ }
285
+ const result = await applyUninstall(root, plan);
286
+ console.log(`\nRemoved ${result.removed.length} file(s).`);
287
+ if (result.cut.length > 0)
288
+ console.log(`Cut Religion's block from ${result.cut.join(", ")}, keeping what you wrote.`);
289
+ if (result.unwired.length > 0)
290
+ console.log(`Took Religion's hooks out of ${result.unwired.join(", ")}, keeping your own settings.`);
291
+ if (result.backups.length > 0)
292
+ console.log(`Backed up ${result.backups.length} file(s) to ${BACKUPS} before changing them.`);
293
+ const kept = result.kept.filter((entry) => entry.action !== "keep-edited");
294
+ if (result.kept.length > 0)
295
+ console.log(`Kept ${result.kept.length} file(s), listed above, for you to remove or keep.`);
296
+ if (kept.length > 0)
297
+ process.exitCode = 1;
298
+ }
299
+ /** Defaults to no: removing files is the one thing this tool does that cannot be redone by running it again. */
300
+ async function confirmUninstall(assumeYes) {
301
+ if (assumeYes || !process.stdin.isTTY)
302
+ return assumeYes;
303
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
304
+ const answer = (await rl.question("\nRemove what is listed? [y/N] ")).trim().toLowerCase();
305
+ rl.close();
306
+ return answer === "y" || answer === "yes";
307
+ }
308
+ /** What changed since the installed version, from the changelog the package ships. */
309
+ async function printChanges(installed, current) {
310
+ const file = path.join(packageRoot, "CHANGELOG.md");
311
+ const releases = changesSince(await fs.readFile(file, "utf8").catch(() => null), installed, current);
312
+ if (releases.length === 0)
313
+ return;
314
+ console.log(`\nWhat changed since ${String(installed)}:`);
315
+ for (const release of releases) {
316
+ console.log(` ${release.version}`);
317
+ for (const change of release.changes)
318
+ console.log(` - ${change}`);
319
+ }
320
+ console.log(` The whole changelog: ${file}`);
321
+ }
241
322
  async function version() {
242
323
  try {
243
324
  const manifest = JSON.parse(await fs.readFile(path.join(packageRoot, "package.json"), "utf8"));
@@ -263,6 +344,7 @@ is installed globally.
263
344
 
264
345
  install [dir] add the workflow to a project
265
346
  update [dir] update the workflow files, preserving your own
347
+ uninstall [dir] take the workflow back out, keeping the plans and history
266
348
  status where the work stands, and what to do next
267
349
  doctor check the setup is healthy
268
350
  dashboard a local read-only view
@@ -275,11 +357,9 @@ Options
275
357
  --yes no prompts
276
358
 
277
359
  Exit codes
278
- 0 the command did what it was asked
279
- 1 it ran and reports failure: no project found, a failing doctor check,
280
- conflicts, declined merges or linked files left by install or update,
281
- a project installed by a newer version, or an unexpected error
282
- 2 usage error: nothing was written
360
+ ${Object.entries(EXIT_CODES)
361
+ .map(([code, meaning]) => ` ${code.padEnd(4)}${meaning.replace(/\n/g, "\n ")}`)
362
+ .join("\n")}
283
363
  `);
284
364
  }
285
365
  main(process.argv.slice(2)).catch((error) => {