@codyswann/lisa 3.26.2 → 3.26.3

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 (60) hide show
  1. package/all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh +54 -38
  2. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  3. package/dist/core/lisa-owned-hash-ledger.js +1 -0
  4. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  5. package/dist/core/upstream-evidence-manifest.js +2 -2
  6. package/package.json +1 -1
  7. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  8. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  9. package/plugins/lisa/hooks/block-managed-file-edits.sh +54 -38
  10. package/plugins/lisa-agy/plugin.json +1 -1
  11. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  12. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  13. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  14. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  15. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-copilot/hooks/block-managed-file-edits.sh +54 -38
  18. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-cursor/hooks/block-managed-file-edits.sh +54 -38
  20. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  22. package/plugins/lisa-expo-agy/plugin.json +1 -1
  23. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  24. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  25. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  28. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  33. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  38. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  43. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-rails-agy/plugin.json +1 -1
  48. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  53. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  58. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/src/base/hooks/block-managed-file-edits.sh +54 -38
@@ -14,20 +14,29 @@
14
14
  # would stop agents editing files they are supposed to own, which is worse than
15
15
  # the problem being solved.
16
16
  #
17
- # WITHIN copy-overwrite there are two populations with OPPOSITE consequences,
18
- # and an earlier version of this guard described only one of them:
17
+ # The name `copy-overwrite` is misleading, and two successive versions of this
18
+ # guard got the consequence wrong by trusting it. MEASURED, by mutating four
19
+ # files in a scratch project and running a real `lisa apply` against them:
19
20
  #
20
- # hash-tracked guards (the `.mjs` scripts, listed in the Lisa-owned ledger)
21
- # an edit classifies as `host-modified` and `lisa apply` PRESERVES it.
22
- # The file silently forks and stops receiving upstream fixes while looking
23
- # current. Nothing is deleted; that is what makes it hard to notice.
24
- # everything else (`.json` configs and friends)
25
- # — replaced wholesale on the next apply, which runs on every install.
26
- # The edit vanishes.
21
+ # scripts/lisa-gates.mjs (ledger-tracked) → SURVIVED
22
+ # .lintstagedrc.json (untracked, JSON) SURVIVED
23
+ # .prettierignore (untracked, text) SURVIVED
24
+ # .yamllint (untracked, text) SURVIVED
27
25
  #
28
- # The refusal branches on ledger membership so it states the consequence that
29
- # actually applies, rather than describing both and leaving the reader to work
30
- # out which they are in.
26
+ # Summary line: `Overwritten: 0 files` / `Out of date: 3 files (managed
27
+ # templates changed; NOT updated)`.
28
+ #
29
+ # copy-overwrite overwrites an UNMODIFIED copy — it refreshes. It does not
30
+ # overwrite a host-edited one, in any population tested. So the harm is the same
31
+ # for both, and it is not deletion:
32
+ #
33
+ # THE FILE SILENTLY FORKS. It keeps looking current while every upstream fix
34
+ # stops reaching it. Nothing is lost, which is exactly what makes it invisible.
35
+ #
36
+ # Ledger membership changes the MESSAGE apply prints, not the outcome — tracked
37
+ # files get a provenance verdict naming the fork and offering
38
+ # `lisa-guard-capabilities:`; untracked ones get a bare "Out of date" warning.
39
+ # The refusal branches on that so the reader sees the words apply will use.
31
40
  #
32
41
  # Measured, not hypothetical. Nothing enforced this, so downstream copies were
33
42
  # edited and then silently diverged: `classify-maestro-failures.mjs` reached
@@ -177,12 +186,12 @@ managed_source() {
177
186
 
178
187
  # Whether a destination is a ledger-tracked Lisa-owned guard.
179
188
  #
180
- # The two populations behind this guard have OPPOSITE consequences, so the
181
- # refusal has to know which one it is looking at rather than describing both and
182
- # leaving the reader to guess. A guard in the content-hash ledger classifies as
183
- # `host-modified` once edited and `lisa apply` PRESERVES it; anything else is
184
- # replaced wholesale. Both are bad, for different reasons, and the right next
185
- # step differs too.
189
+ # Both populations are PRESERVED once edited (measured see the header). What
190
+ # membership changes is what apply prints and what the escape hatch is: a tracked
191
+ # guard gets a provenance verdict and can declare `lisa-guard-capabilities:`,
192
+ # while an untracked template gets a bare "Out of date" line and `.lisaignore`.
193
+ # The refusal quotes the words the reader will actually see, so it has to know
194
+ # which side it is on.
186
195
  ledger_tracked() {
187
196
  local rel="$1"
188
197
  local ledger="$package_root/dist/core/lisa-owned-hash-ledger.js"
@@ -196,15 +205,21 @@ refuse() {
196
205
  local rel="$3"
197
206
  local consequence
198
207
  if ledger_tracked "$rel"; then
199
- consequence="This is a Lisa-owned guard, tracked by content hash. \`lisa apply\`
200
- will PRESERVE your edit rather than overwrite it and that is the trap. The
201
- file silently forks: it keeps looking current while every upstream fix stops
202
- reaching it. One repository in this fleet is carrying 243 lines of divergence
203
- nobody knew about, in a guard that had quietly stopped receiving fixes."
208
+ consequence="\`lisa apply\` will KEEP your edit — this is a Lisa-owned guard,
209
+ and apply says so: \"its contents match no Lisa release, so Lisa cannot tell
210
+ whether it is out of date or deliberately stronger. Kept yours.\"
211
+
212
+ That is the trap. Nothing is deleted; the file silently FORKS. It keeps looking
213
+ current while every upstream fix stops reaching it. One repository in this fleet
214
+ carries 243 lines of divergence nobody knew about, in a guard that had quietly
215
+ stopped receiving fixes."
204
216
  else
205
- consequence="This template is not hash-tracked, so \`lisa apply\` REPLACES it
206
- wholesale and apply runs on every \`bun install\`. Your edit survives until the
207
- next install and then vanishes, with nothing reporting that it had."
217
+ consequence="\`lisa apply\` will KEEP your edit and report the file as
218
+ \"Out of date, not updated\" on every run from now on.
219
+
220
+ That is the trap. Nothing is deleted; the file silently FORKS, stops receiving
221
+ upstream changes, and adds a permanent warning line that the next person learns
222
+ to scroll past."
208
223
  fi
209
224
  cat >&2 <<EOF
210
225
  BLOCKED: refusing to write \`$target\`.
@@ -231,20 +246,21 @@ WHERE IT GOES INSTEAD — take the first one that fits:
231
246
  shipped file.
232
247
 
233
248
  4. This project has deliberately FORKED this file and means to keep its own
234
- version. What to do depends on which population it is, and \`.lisaignore\` is
235
- the WRONG answer for a hash-tracked guard:
249
+ version. Apply already preserves the edit either way, so what is left to
250
+ choose is whether the fork stays VISIBLE. Keeping it visible is the point:
236
251
 
237
- - **A Lisa-owned guard (hash-tracked).** Do NOT add it to \`.lisaignore\`. The
238
- ledger already preserves your version, so ignoring it buys nothing — and it
239
- silences the standoff \`lisa doctor\` reports on every run, replacing a true
240
- warning with the line "Enforcement guards match the installed Lisa
252
+ - **A Lisa-owned guard (hash-tracked).** Do NOT add it to \`.lisaignore\`.
253
+ Apply preserves your version regardless, so ignoring it buys nothing — and
254
+ it silences the standoff \`lisa doctor\` reports on every run, replacing a
255
+ true warning with the line "Enforcement guards match the installed Lisa
241
256
  version", which is then false. A visible, resolvable fork becomes a silent
242
- permanent one. Keep the warning and resolve the fork: upstream what is
243
- general, or accept the standoff knowingly. To make this one edit, use the
244
- override below.
245
- - **Any other template.** \`.lisaignore\` is the right answer. Nothing else
246
- preserves it, and the entry declares the divergence where the next person
247
- can see it.
257
+ permanent one. Instead declare what your version defends with a
258
+ \`lisa-guard-capabilities:\` line; apply then classifies it \`host-ahead\`
259
+ and says so by name, rather than reporting that it cannot tell.
260
+ - **Any other template.** \`.lisaignore\` records the divergence where the
261
+ next person can see it and stops the recurring "Out of date" line. It does
262
+ not preserve the file — apply already does — so use it to DECLARE a fork
263
+ you have decided on, never to quiet one you have not.
248
264
 
249
265
  5. You believe this file should not be Lisa-managed at all. That is a real
250
266
  argument and it belongs upstream, not in a local edit that will be erased.
@@ -1 +1 @@
1
- {"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAgVjC,CAAC"}
1
+ {"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAiVjC,CAAC"}
@@ -222,6 +222,7 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
222
222
  "133acf329582c5d4df9deb6a297df13216993c1bfec0b7df0663c69a1e2bb0db",
223
223
  "18aebaef5ea9bf6af220dc9beef80a5cfb37282c6a53047783b4cc96d8daa4e3",
224
224
  "3882bd338e65b9db9e97aa9e70426f0f7a0d191539df51636e1a5e93a2501137",
225
+ "92e0ff52fcb29bc112ddcf1c3d85432032596572a84f3c5806a5b0c286ae55b3",
225
226
  "c1b2abf324269c0248136500eb37d7c43559552f152a7c5d07a23c219fdc70b2",
226
227
  ]),
227
228
  "scripts/lisa-hooks/block-no-verify.sh": Object.freeze([
@@ -1 +1 @@
1
- {"version":3,"file":"lisa-owned-hash-ledger.js","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lisa-owned-hash-ledger.js","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"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"}
@@ -12,7 +12,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
12
12
  "all/copy-overwrite/scripts/lisa-gates.mjs": "98652623c7451d05e48239e1678ad7977a323eaf7ff5ca4b4f3bbc0798396859",
13
13
  "all/copy-overwrite/scripts/lisa-hooks/block-direct-issue-create.sh": "8d1f04ef5c5da9db9190e22b37a435e118e39d6e7deafc5402b4593c8e9db2b2",
14
14
  "all/copy-overwrite/scripts/lisa-hooks/block-instruction-file-edits.sh": "3e709e1ec8a5843c00684bc477ad32ddab2c5fdb11f71d5aeec0c49609eaf025",
15
- "all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh": "c1b2abf324269c0248136500eb37d7c43559552f152a7c5d07a23c219fdc70b2",
15
+ "all/copy-overwrite/scripts/lisa-hooks/block-managed-file-edits.sh": "92e0ff52fcb29bc112ddcf1c3d85432032596572a84f3c5806a5b0c286ae55b3",
16
16
  "all/copy-overwrite/scripts/lisa-hooks/block-no-verify.sh": "83a8b8108654086afb6a6f23a8f09f9f041eb2cd4094c5531fa7ab1f75e873dc",
17
17
  "all/copy-overwrite/scripts/lisa-hooks/block-shell-json-parsing.sh": "234cb82cc9033bd04940a553d4ddc95b078e585e41777d6529d887676edc40b1",
18
18
  "all/copy-overwrite/scripts/lisa-hooks/parity-safety-net.sh": "1d4fbe135f1bb4e861d286a6512ed201d4522250dfe3f9eba6584bc5ff166a95",
@@ -339,7 +339,7 @@ export const UPSTREAM_EVIDENCE_MANIFEST = Object.freeze({
339
339
  "plugins/src/base/hooks/block-direct-issue-create.sh": "22184f1dd1b96e818741bd4ae659446299535d7ce594817155edebac4172a7ba",
340
340
  "plugins/src/base/hooks/block-instruction-file-edits.agy.sh": "aa249cae53caeb3e0fb6d6af114e2756084f45a2896332fb063a9f20e4902125",
341
341
  "plugins/src/base/hooks/block-instruction-file-edits.sh": "d47314b66d6ce85f77d6e058f861eede4462b2b0a33d54e82ff1c931167ec3f7",
342
- "plugins/src/base/hooks/block-managed-file-edits.sh": "c363505f94d3716e51972bbff33845b0bf41c92b4e909288d02b2d7c3e87fa61",
342
+ "plugins/src/base/hooks/block-managed-file-edits.sh": "b0156d4b4e7fe3b28c6d0798db67af62b7fbc8247e6f1cc5092adf4c94e417af",
343
343
  "plugins/src/base/hooks/block-no-verify.agy.sh": "81c51041f8cb47bf79692c485c4f42ac7ed0a5a830821dc514cb468bc7a06b83",
344
344
  "plugins/src/base/hooks/block-no-verify.sh": "3ff7255f395a9552366faaac34d383f4c95fecfb39882cd1d57854356422fe61",
345
345
  "plugins/src/base/hooks/block-shell-json-parsing.agy.sh": "dc688efe382e7b8fe6f6c88bb0fde851527128cae778599559f23a93f1c9ec86",
package/package.json CHANGED
@@ -129,7 +129,7 @@
129
129
  }
130
130
  },
131
131
  "name": "@codyswann/lisa",
132
- "version": "3.26.2",
132
+ "version": "3.26.3",
133
133
  "description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
134
134
  "main": "dist/index.js",
135
135
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "Universal governance: agents, skills, commands, hooks, and rules for all projects.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -11,20 +11,29 @@
11
11
  # would stop agents editing files they are supposed to own, which is worse than
12
12
  # the problem being solved.
13
13
  #
14
- # WITHIN copy-overwrite there are two populations with OPPOSITE consequences,
15
- # and an earlier version of this guard described only one of them:
14
+ # The name `copy-overwrite` is misleading, and two successive versions of this
15
+ # guard got the consequence wrong by trusting it. MEASURED, by mutating four
16
+ # files in a scratch project and running a real `lisa apply` against them:
16
17
  #
17
- # hash-tracked guards (the `.mjs` scripts, listed in the Lisa-owned ledger)
18
- # an edit classifies as `host-modified` and `lisa apply` PRESERVES it.
19
- # The file silently forks and stops receiving upstream fixes while looking
20
- # current. Nothing is deleted; that is what makes it hard to notice.
21
- # everything else (`.json` configs and friends)
22
- # — replaced wholesale on the next apply, which runs on every install.
23
- # The edit vanishes.
18
+ # scripts/lisa-gates.mjs (ledger-tracked) → SURVIVED
19
+ # .lintstagedrc.json (untracked, JSON) SURVIVED
20
+ # .prettierignore (untracked, text) SURVIVED
21
+ # .yamllint (untracked, text) SURVIVED
24
22
  #
25
- # The refusal branches on ledger membership so it states the consequence that
26
- # actually applies, rather than describing both and leaving the reader to work
27
- # out which they are in.
23
+ # Summary line: `Overwritten: 0 files` / `Out of date: 3 files (managed
24
+ # templates changed; NOT updated)`.
25
+ #
26
+ # copy-overwrite overwrites an UNMODIFIED copy — it refreshes. It does not
27
+ # overwrite a host-edited one, in any population tested. So the harm is the same
28
+ # for both, and it is not deletion:
29
+ #
30
+ # THE FILE SILENTLY FORKS. It keeps looking current while every upstream fix
31
+ # stops reaching it. Nothing is lost, which is exactly what makes it invisible.
32
+ #
33
+ # Ledger membership changes the MESSAGE apply prints, not the outcome — tracked
34
+ # files get a provenance verdict naming the fork and offering
35
+ # `lisa-guard-capabilities:`; untracked ones get a bare "Out of date" warning.
36
+ # The refusal branches on that so the reader sees the words apply will use.
28
37
  #
29
38
  # Measured, not hypothetical. Nothing enforced this, so downstream copies were
30
39
  # edited and then silently diverged: `classify-maestro-failures.mjs` reached
@@ -174,12 +183,12 @@ managed_source() {
174
183
 
175
184
  # Whether a destination is a ledger-tracked Lisa-owned guard.
176
185
  #
177
- # The two populations behind this guard have OPPOSITE consequences, so the
178
- # refusal has to know which one it is looking at rather than describing both and
179
- # leaving the reader to guess. A guard in the content-hash ledger classifies as
180
- # `host-modified` once edited and `lisa apply` PRESERVES it; anything else is
181
- # replaced wholesale. Both are bad, for different reasons, and the right next
182
- # step differs too.
186
+ # Both populations are PRESERVED once edited (measured see the header). What
187
+ # membership changes is what apply prints and what the escape hatch is: a tracked
188
+ # guard gets a provenance verdict and can declare `lisa-guard-capabilities:`,
189
+ # while an untracked template gets a bare "Out of date" line and `.lisaignore`.
190
+ # The refusal quotes the words the reader will actually see, so it has to know
191
+ # which side it is on.
183
192
  ledger_tracked() {
184
193
  local rel="$1"
185
194
  local ledger="$package_root/dist/core/lisa-owned-hash-ledger.js"
@@ -193,15 +202,21 @@ refuse() {
193
202
  local rel="$3"
194
203
  local consequence
195
204
  if ledger_tracked "$rel"; then
196
- consequence="This is a Lisa-owned guard, tracked by content hash. \`lisa apply\`
197
- will PRESERVE your edit rather than overwrite it and that is the trap. The
198
- file silently forks: it keeps looking current while every upstream fix stops
199
- reaching it. One repository in this fleet is carrying 243 lines of divergence
200
- nobody knew about, in a guard that had quietly stopped receiving fixes."
205
+ consequence="\`lisa apply\` will KEEP your edit — this is a Lisa-owned guard,
206
+ and apply says so: \"its contents match no Lisa release, so Lisa cannot tell
207
+ whether it is out of date or deliberately stronger. Kept yours.\"
208
+
209
+ That is the trap. Nothing is deleted; the file silently FORKS. It keeps looking
210
+ current while every upstream fix stops reaching it. One repository in this fleet
211
+ carries 243 lines of divergence nobody knew about, in a guard that had quietly
212
+ stopped receiving fixes."
201
213
  else
202
- consequence="This template is not hash-tracked, so \`lisa apply\` REPLACES it
203
- wholesale and apply runs on every \`bun install\`. Your edit survives until the
204
- next install and then vanishes, with nothing reporting that it had."
214
+ consequence="\`lisa apply\` will KEEP your edit and report the file as
215
+ \"Out of date, not updated\" on every run from now on.
216
+
217
+ That is the trap. Nothing is deleted; the file silently FORKS, stops receiving
218
+ upstream changes, and adds a permanent warning line that the next person learns
219
+ to scroll past."
205
220
  fi
206
221
  cat >&2 <<EOF
207
222
  BLOCKED: refusing to write \`$target\`.
@@ -228,20 +243,21 @@ WHERE IT GOES INSTEAD — take the first one that fits:
228
243
  shipped file.
229
244
 
230
245
  4. This project has deliberately FORKED this file and means to keep its own
231
- version. What to do depends on which population it is, and \`.lisaignore\` is
232
- the WRONG answer for a hash-tracked guard:
246
+ version. Apply already preserves the edit either way, so what is left to
247
+ choose is whether the fork stays VISIBLE. Keeping it visible is the point:
233
248
 
234
- - **A Lisa-owned guard (hash-tracked).** Do NOT add it to \`.lisaignore\`. The
235
- ledger already preserves your version, so ignoring it buys nothing — and it
236
- silences the standoff \`lisa doctor\` reports on every run, replacing a true
237
- warning with the line "Enforcement guards match the installed Lisa
249
+ - **A Lisa-owned guard (hash-tracked).** Do NOT add it to \`.lisaignore\`.
250
+ Apply preserves your version regardless, so ignoring it buys nothing — and
251
+ it silences the standoff \`lisa doctor\` reports on every run, replacing a
252
+ true warning with the line "Enforcement guards match the installed Lisa
238
253
  version", which is then false. A visible, resolvable fork becomes a silent
239
- permanent one. Keep the warning and resolve the fork: upstream what is
240
- general, or accept the standoff knowingly. To make this one edit, use the
241
- override below.
242
- - **Any other template.** \`.lisaignore\` is the right answer. Nothing else
243
- preserves it, and the entry declares the divergence where the next person
244
- can see it.
254
+ permanent one. Instead declare what your version defends with a
255
+ \`lisa-guard-capabilities:\` line; apply then classifies it \`host-ahead\`
256
+ and says so by name, rather than reporting that it cannot tell.
257
+ - **Any other template.** \`.lisaignore\` records the divergence where the
258
+ next person can see it and stops the recurring "Out of date" line. It does
259
+ not preserve the file — apply already does — so use it to DECLARE a fork
260
+ you have decided on, never to quiet one you have not.
245
261
 
246
262
  5. You believe this file should not be Lisa-managed at all. That is a real
247
263
  argument and it belongs upstream, not in a local edit that will be erased.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "AWS CDK-specific Lisa plugin.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-cdk",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "AWS CDK-specific plugin",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -11,20 +11,29 @@
11
11
  # would stop agents editing files they are supposed to own, which is worse than
12
12
  # the problem being solved.
13
13
  #
14
- # WITHIN copy-overwrite there are two populations with OPPOSITE consequences,
15
- # and an earlier version of this guard described only one of them:
14
+ # The name `copy-overwrite` is misleading, and two successive versions of this
15
+ # guard got the consequence wrong by trusting it. MEASURED, by mutating four
16
+ # files in a scratch project and running a real `lisa apply` against them:
16
17
  #
17
- # hash-tracked guards (the `.mjs` scripts, listed in the Lisa-owned ledger)
18
- # an edit classifies as `host-modified` and `lisa apply` PRESERVES it.
19
- # The file silently forks and stops receiving upstream fixes while looking
20
- # current. Nothing is deleted; that is what makes it hard to notice.
21
- # everything else (`.json` configs and friends)
22
- # — replaced wholesale on the next apply, which runs on every install.
23
- # The edit vanishes.
18
+ # scripts/lisa-gates.mjs (ledger-tracked) → SURVIVED
19
+ # .lintstagedrc.json (untracked, JSON) SURVIVED
20
+ # .prettierignore (untracked, text) SURVIVED
21
+ # .yamllint (untracked, text) SURVIVED
24
22
  #
25
- # The refusal branches on ledger membership so it states the consequence that
26
- # actually applies, rather than describing both and leaving the reader to work
27
- # out which they are in.
23
+ # Summary line: `Overwritten: 0 files` / `Out of date: 3 files (managed
24
+ # templates changed; NOT updated)`.
25
+ #
26
+ # copy-overwrite overwrites an UNMODIFIED copy — it refreshes. It does not
27
+ # overwrite a host-edited one, in any population tested. So the harm is the same
28
+ # for both, and it is not deletion:
29
+ #
30
+ # THE FILE SILENTLY FORKS. It keeps looking current while every upstream fix
31
+ # stops reaching it. Nothing is lost, which is exactly what makes it invisible.
32
+ #
33
+ # Ledger membership changes the MESSAGE apply prints, not the outcome — tracked
34
+ # files get a provenance verdict naming the fork and offering
35
+ # `lisa-guard-capabilities:`; untracked ones get a bare "Out of date" warning.
36
+ # The refusal branches on that so the reader sees the words apply will use.
28
37
  #
29
38
  # Measured, not hypothetical. Nothing enforced this, so downstream copies were
30
39
  # edited and then silently diverged: `classify-maestro-failures.mjs` reached
@@ -174,12 +183,12 @@ managed_source() {
174
183
 
175
184
  # Whether a destination is a ledger-tracked Lisa-owned guard.
176
185
  #
177
- # The two populations behind this guard have OPPOSITE consequences, so the
178
- # refusal has to know which one it is looking at rather than describing both and
179
- # leaving the reader to guess. A guard in the content-hash ledger classifies as
180
- # `host-modified` once edited and `lisa apply` PRESERVES it; anything else is
181
- # replaced wholesale. Both are bad, for different reasons, and the right next
182
- # step differs too.
186
+ # Both populations are PRESERVED once edited (measured see the header). What
187
+ # membership changes is what apply prints and what the escape hatch is: a tracked
188
+ # guard gets a provenance verdict and can declare `lisa-guard-capabilities:`,
189
+ # while an untracked template gets a bare "Out of date" line and `.lisaignore`.
190
+ # The refusal quotes the words the reader will actually see, so it has to know
191
+ # which side it is on.
183
192
  ledger_tracked() {
184
193
  local rel="$1"
185
194
  local ledger="$package_root/dist/core/lisa-owned-hash-ledger.js"
@@ -193,15 +202,21 @@ refuse() {
193
202
  local rel="$3"
194
203
  local consequence
195
204
  if ledger_tracked "$rel"; then
196
- consequence="This is a Lisa-owned guard, tracked by content hash. \`lisa apply\`
197
- will PRESERVE your edit rather than overwrite it and that is the trap. The
198
- file silently forks: it keeps looking current while every upstream fix stops
199
- reaching it. One repository in this fleet is carrying 243 lines of divergence
200
- nobody knew about, in a guard that had quietly stopped receiving fixes."
205
+ consequence="\`lisa apply\` will KEEP your edit — this is a Lisa-owned guard,
206
+ and apply says so: \"its contents match no Lisa release, so Lisa cannot tell
207
+ whether it is out of date or deliberately stronger. Kept yours.\"
208
+
209
+ That is the trap. Nothing is deleted; the file silently FORKS. It keeps looking
210
+ current while every upstream fix stops reaching it. One repository in this fleet
211
+ carries 243 lines of divergence nobody knew about, in a guard that had quietly
212
+ stopped receiving fixes."
201
213
  else
202
- consequence="This template is not hash-tracked, so \`lisa apply\` REPLACES it
203
- wholesale and apply runs on every \`bun install\`. Your edit survives until the
204
- next install and then vanishes, with nothing reporting that it had."
214
+ consequence="\`lisa apply\` will KEEP your edit and report the file as
215
+ \"Out of date, not updated\" on every run from now on.
216
+
217
+ That is the trap. Nothing is deleted; the file silently FORKS, stops receiving
218
+ upstream changes, and adds a permanent warning line that the next person learns
219
+ to scroll past."
205
220
  fi
206
221
  cat >&2 <<EOF
207
222
  BLOCKED: refusing to write \`$target\`.
@@ -228,20 +243,21 @@ WHERE IT GOES INSTEAD — take the first one that fits:
228
243
  shipped file.
229
244
 
230
245
  4. This project has deliberately FORKED this file and means to keep its own
231
- version. What to do depends on which population it is, and \`.lisaignore\` is
232
- the WRONG answer for a hash-tracked guard:
246
+ version. Apply already preserves the edit either way, so what is left to
247
+ choose is whether the fork stays VISIBLE. Keeping it visible is the point:
233
248
 
234
- - **A Lisa-owned guard (hash-tracked).** Do NOT add it to \`.lisaignore\`. The
235
- ledger already preserves your version, so ignoring it buys nothing — and it
236
- silences the standoff \`lisa doctor\` reports on every run, replacing a true
237
- warning with the line "Enforcement guards match the installed Lisa
249
+ - **A Lisa-owned guard (hash-tracked).** Do NOT add it to \`.lisaignore\`.
250
+ Apply preserves your version regardless, so ignoring it buys nothing — and
251
+ it silences the standoff \`lisa doctor\` reports on every run, replacing a
252
+ true warning with the line "Enforcement guards match the installed Lisa
238
253
  version", which is then false. A visible, resolvable fork becomes a silent
239
- permanent one. Keep the warning and resolve the fork: upstream what is
240
- general, or accept the standoff knowingly. To make this one edit, use the
241
- override below.
242
- - **Any other template.** \`.lisaignore\` is the right answer. Nothing else
243
- preserves it, and the entry declares the divergence where the next person
244
- can see it.
254
+ permanent one. Instead declare what your version defends with a
255
+ \`lisa-guard-capabilities:\` line; apply then classifies it \`host-ahead\`
256
+ and says so by name, rather than reporting that it cannot tell.
257
+ - **Any other template.** \`.lisaignore\` records the divergence where the
258
+ next person can see it and stops the recurring "Out of date" line. It does
259
+ not preserve the file — apply already does — so use it to DECLARE a fork
260
+ you have decided on, never to quiet one you have not.
245
261
 
246
262
  5. You believe this file should not be Lisa-managed at all. That is a real
247
263
  argument and it belongs upstream, not in a local edit that will be erased.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa",
3
- "version": "3.26.2",
3
+ "version": "3.26.3",
4
4
  "description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"