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