@codyswann/lisa 4.53.1 → 4.53.2

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 (67) hide show
  1. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  2. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  3. package/dist/core/upstream-evidence-manifest.js +4 -3
  4. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  5. package/package.json +4 -4
  6. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  7. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  8. package/plugins/lisa/hooks/withdrawn-rulings.mjs +76 -1
  9. package/plugins/lisa/rules/eager/withdrawn-rulings.md +22 -0
  10. package/plugins/lisa/rules/reference/withdrawn-rulings.md +34 -0
  11. package/plugins/lisa-agy/plugin.json +1 -1
  12. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  13. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  14. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  15. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  17. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  18. package/plugins/lisa-copilot/hooks/withdrawn-rulings.mjs +76 -1
  19. package/plugins/lisa-copilot/rules/eager/withdrawn-rulings.md +22 -0
  20. package/plugins/lisa-copilot/rules/reference/withdrawn-rulings.md +34 -0
  21. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  22. package/plugins/lisa-cursor/hooks/withdrawn-rulings.mjs +76 -1
  23. package/plugins/lisa-cursor/rules/withdrawn-rulings-reference.mdc +34 -0
  24. package/plugins/lisa-cursor/rules/withdrawn-rulings.mdc +22 -0
  25. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  26. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  27. package/plugins/lisa-expo-agy/plugin.json +1 -1
  28. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  29. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  30. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  32. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  33. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  34. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  38. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  42. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  43. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  44. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  47. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  48. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  51. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  52. package/plugins/lisa-rails-agy/plugin.json +1 -1
  53. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  58. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  62. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  63. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  65. package/plugins/src/base/hooks/withdrawn-rulings.mjs +76 -1
  66. package/plugins/src/base/rules/eager/withdrawn-rulings.md +22 -0
  67. package/plugins/src/base/rules/reference/withdrawn-rulings.md +34 -0
@@ -80,6 +80,40 @@ JSONL rather than prose: each line is independent, so concurrent appends from ma
80
80
  collide and `merge=union` reconstructs the union exactly. A prose ledger would need a bespoke merge
81
81
  driver to survive the same traffic.
82
82
 
83
+ ## The re-audit field, and why it is required (CodySwannGT/lisa#3489)
84
+
85
+ A tombstone answers "this claim is dead". It does not answer **"what did I build while it was
86
+ alive?"** — and that is the half that reached other agents and the human. Correcting a premise
87
+ removes the belief and leaves every inference standing.
88
+
89
+ The observed instance: a session spent part of a day believing a readiness preflight's false claim
90
+ that a credential CLI was unavailable. A delegate probed the binary and disproved it, the session
91
+ updated the fact, and carried on. It never asked what it had concluded while believing the false
92
+ thing. Two hours later it relayed to its human that a work item was blocked because an SSO session
93
+ had expired and a deployed template could not be read — relayed unexamined, while already knowing
94
+ the vault worked, and while its own config had listed the relevant bootstrap secret the whole time.
95
+ Three facts sat in one context and were never joined.
96
+
97
+ So `--derived` is a required field on every withdrawal, and `--derived none` is the explicit empty
98
+ answer. The record always carries the key: an empty list means *audited, nothing survives*, and an
99
+ absent key means *never audited*. Distinguishing those two is the entire purpose, which is why the
100
+ push gate refuses a ledger entry that omits it — otherwise the write-time refusal would be a
101
+ formality anyone could route around by editing the file.
102
+
103
+ **Why it cannot be a scanner instead.** Re-auditing after the fact would require asking "which
104
+ artifacts rest on premise P". Nothing can answer that. Learnings-ledger entries carry `provenance`
105
+ refs and are genuinely queryable that way, but they are the only artifact class that is: a tracker
106
+ item marked blocked, a sentence relayed to an operator, a message to a peer session, an evidence
107
+ file — none record the premise they rest on. **Re-auditing those is not merely unenforced; for
108
+ anyone but the session still holding the context, it is impossible.** The obligation therefore has
109
+ to bind at the one moment that knowledge is both present and being written down.
110
+
111
+ Note the division of labour with `--reached`, which is a different question. `--reached` records the
112
+ **audience** — who received the claim, which is #3752's problem of delivery. `--derived` records the
113
+ **derivation** — what now stands on it, which is #3489's problem. A tombstone can reach every holder
114
+ and still leave a wrong tracker state behind, and it can enumerate its inferences while reaching
115
+ nobody. Both fields, or neither half is covered.
116
+
83
117
  ## How a running session is reached
84
118
 
85
119
  `--session-start` stamps a per-session mark recording the ids the session was born already knowing.
@@ -34,12 +34,34 @@ The result is one-directional propagation. **New guidance travels; corrections d
34
34
  node "$CLAUDE_PLUGIN_ROOT/hooks/withdrawn-rulings.mjs" --withdraw <id> \
35
35
  --claim "<the withdrawn claim, verbatim>" \
36
36
  --because "<what disproved it>" \
37
+ --derived "<an artifact you left standing on it>" ... | --derived none \
37
38
  [--superseded-by <id>] [--reached <channel> ...]
38
39
  ```
39
40
 
40
41
  The verbatim claim is required and the command refuses without it: **a tombstone the holder of the
41
42
  claim cannot recognise reaches them without reaching them.**
42
43
 
44
+ - **`--derived` is required too, because correcting a premise leaves every inference standing.**
45
+ Updating the fact is the easy half. The conclusions you already drew from it are the half that
46
+ reached other agents and the human, and they do not retract themselves. Before you can record the
47
+ withdrawal you must name what you asserted, filed, or relayed while you believed the claim —
48
+ tracker state you set, a statement you made to your operator, a message you sent a peer session.
49
+
50
+ **The obligation is to produce the list, not to find something wrong in it.** `--derived none` is
51
+ a complete answer when you checked and nothing survives, and the record keeps it as an empty list
52
+ so a later reader can tell "audited, nothing standing" from "never audited". An absent answer is
53
+ refused; an empty one is not.
54
+
55
+ Measured instance: a session disproved a false claim that a credential CLI was unavailable,
56
+ updated the fact, and **two hours later still relayed to its human that a work item was blocked**
57
+ for a reason resting on the retracted claim. Three facts sat in one context and were never joined.
58
+
59
+ It binds here because nowhere else can carry it. Outside the learnings ledger's `provenance` refs,
60
+ **no artifact Lisa writes records the premise it rests on** — a blocked label, a relayed sentence,
61
+ a peer message carry no back-pointer. Nothing can go looking afterwards for what rested on a
62
+ retracted claim. You are the only party still holding that, at the only moment it is being
63
+ written down.
64
+
43
65
  - **The ledger is the retraction path, precisely because it is cheap.** Writing a finding feels
44
66
  productive; writing a retraction is a chore produced mid-task, after being corrected, when
45
67
  attention has moved on. A rule saying "always record retractions durably" is a discipline, and
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Expo and React Native-specific skills, agents, rules, and MCP servers.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-expo",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Expo/React Native-specific skills, agents, rules, and MCP servers",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Harper/Fabric-specific Lisa rules for TypeScript component apps.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-harper-fabric",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Harper/Fabric-specific rules for TypeScript component apps",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "NestJS-specific skills and migration write-protection hooks.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-nestjs",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "NestJS-specific skills (GraphQL, TypeORM) and hooks (migration write-protection)",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-openclaw",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-phaser",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Phaser 4 game-development rules for TypeScript projects",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Ruby on Rails-specific skills and hooks for RuboCop and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-rails",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Ruby on Rails-specific hooks — RuboCop linting/formatting and ast-grep scanning on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "TypeScript-specific hooks for formatting, linting, and ast-grep scanning on edit.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-typescript",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "TypeScript-specific hooks — Prettier formatting, ESLint linting, ast-grep scanning, and error-suppression blocking on edit",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "Distributable LLM Wiki kernel — ingest, query, lint, and maintain a git-native markdown knowledge base across Claude and Codex.",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lisa-wiki",
3
- "version": "4.53.1",
3
+ "version": "4.53.2",
4
4
  "description": "LLM Wiki — a distributable, git-native markdown knowledge base for Claude Code and Codex",
5
5
  "author": {
6
6
  "name": "Cody Swann"
@@ -62,9 +62,35 @@
62
62
  * chore produced mid-task, after being corrected, when attention has moved on.
63
63
  * A rule of the form "always record retractions durably" is a discipline, and
64
64
  * this repository's own measurement is that prose rules land at roughly zero
65
- * adoption. `--withdraw` is therefore one command with three required fields,
65
+ * adoption. `--withdraw` is therefore one command with four required fields,
66
66
  * and it refuses without the verbatim claim: a tombstone the holder of the
67
67
  * claim cannot recognise reaches them without reaching them.
68
+ *
69
+ * ## Why the re-audit is a required FIELD and not a reminder
70
+ *
71
+ * Correcting a premise removes the belief and leaves every inference standing
72
+ * (CodySwannGT/lisa#3489). The observed instance: a session disproved a false
73
+ * claim that a credential CLI was unavailable, updated the fact, and two hours
74
+ * later still relayed to its human that a work item was blocked for a reason
75
+ * that rested on the retracted claim. Three facts sat in one context and were
76
+ * never joined. The retraction was recorded; the artifacts it invalidated were
77
+ * not revisited.
78
+ *
79
+ * This file already carried the obligation as prose — "if you already relayed
80
+ * or recorded one, correct it on the same surface" — which is the discipline
81
+ * shape this module exists to distrust. So `--derived` is required, and
82
+ * `--derived none` is the explicit empty answer. The obligation is to PRODUCE
83
+ * the list, not to find something wrong in it: an empty answer is fine, an
84
+ * absent one is not, and the difference between them is the whole control.
85
+ *
86
+ * It has to bind here because there is nowhere else it could. A scanner that
87
+ * went looking for artifacts resting on a retracted premise would find nothing
88
+ * to read: outside the learnings ledger's `provenance` refs, no artifact Lisa
89
+ * writes records the premise it rests on. A tracker item marked blocked, a
90
+ * statement relayed to a human, a message to a peer session — none carry a
91
+ * back-pointer. The retracting session is the only party that still holds the
92
+ * derivation, and the moment it runs this command is the only moment that
93
+ * knowledge is both present and being written down.
68
94
  * @module withdrawn-rulings
69
95
  */
70
96
  import * as fs from "node:fs";
@@ -220,6 +246,15 @@ export function formatNotice(entries, headline) {
220
246
  lines.push(` superseded by: ${entry.supersededBy}`);
221
247
  if (Array.isArray(entry.reached) && entry.reached.length > 0)
222
248
  lines.push(` originally reached: ${entry.reached.join(", ")}`);
249
+ // Printed even when empty, and that is the useful case: it tells a reader
250
+ // the withdrawer looked, so nobody repeats the audit and nobody assumes it
251
+ // happened. An entry with no `derived` key at all says neither.
252
+ if (Array.isArray(entry.derived))
253
+ lines.push(
254
+ entry.derived.length > 0
255
+ ? ` still standing on it: ${entry.derived.join(", ")}`
256
+ : ` still standing on it: nothing (audited by the withdrawer)`
257
+ );
223
258
  return lines.join("\n");
224
259
  });
225
260
  return [
@@ -362,6 +397,24 @@ export function normalizeSuperseded(value) {
362
397
  return trimmed === "" || trimmed.toLowerCase() === "none" ? null : trimmed;
363
398
  }
364
399
 
400
+ /**
401
+ * Normalise `--derived` values into the re-audit list.
402
+ *
403
+ * `none` is a real answer and must survive as one. A withdrawer who checked and
404
+ * found nothing standing has discharged the obligation exactly as fully as one
405
+ * who lists five artifacts, and the record has to be able to say so — otherwise
406
+ * the only way to satisfy the field is to invent an entry, which is worse than
407
+ * the gap it closes. Absent is refused elsewhere; `none` resolves here to an
408
+ * empty list, which reads back as "audited, nothing survives".
409
+ * @param {readonly string[]} values Raw `--derived` values, in order given.
410
+ * @returns {string[]} The artifacts still standing, possibly none.
411
+ */
412
+ export function normalizeDerived(values) {
413
+ return values
414
+ .map(value => value.trim())
415
+ .filter(value => value !== "" && value.toLowerCase() !== "none");
416
+ }
417
+
365
418
  /**
366
419
  * Build the record `--withdraw` appends, refusing an unrecognisable tombstone.
367
420
  * @param {readonly string[]} argv Arguments.
@@ -380,12 +433,25 @@ export function buildWithdrawal(argv, now) {
380
433
  };
381
434
  if (because === "")
382
435
  return { error: "--because is required: say what disproved it" };
436
+ const derived = flagValues(argv, "--derived");
437
+ if (derived.length === 0)
438
+ return {
439
+ error:
440
+ "--derived is required: name what you asserted, filed or relayed while you " +
441
+ "believed this, so the retraction reaches those artifacts too. Correcting a " +
442
+ "premise leaves every inference standing. Pass `--derived none` if you checked " +
443
+ "and nothing survives — an empty answer is fine, an absent one is not.",
444
+ };
383
445
  return {
384
446
  record: {
385
447
  id,
386
448
  withdrawnAt: now,
387
449
  claim,
388
450
  because,
451
+ // Present even when empty: the difference between "audited, nothing
452
+ // survives" and "never audited" is the whole point of the field, and an
453
+ // omitted key cannot express the first.
454
+ derived: normalizeDerived(derived),
389
455
  // "none" is what a person types when nothing replaced the claim, and a
390
456
  // string "none" in the record would print as a superseding id that does
391
457
  // not exist. Normalised here rather than at every reader.
@@ -452,6 +518,15 @@ export function runCheck(root) {
452
518
  for (const entry of entries) {
453
519
  if (typeof entry.claim !== "string" || entry.claim === "")
454
520
  problems.push(`${entry.id}: no verbatim claim recorded`);
521
+ // An absent `derived` is a tombstone whose writer never said what rested on
522
+ // the claim. That is the CodySwannGT/lisa#3489 failure written into the
523
+ // ledger, and letting it through here would make the write-time refusal a
524
+ // formality anything could route around by editing the file.
525
+ if (!Array.isArray(entry.derived))
526
+ problems.push(
527
+ `${entry.id}: no re-audit recorded — say what was asserted, filed or relayed ` +
528
+ `while the claim was believed, or record an empty list to say nothing survives`
529
+ );
455
530
  if (
456
531
  typeof entry.withdrawnAt !== "string" ||
457
532
  Number.isNaN(Date.parse(entry.withdrawnAt))
@@ -29,12 +29,34 @@ The result is one-directional propagation. **New guidance travels; corrections d
29
29
  node "$CLAUDE_PLUGIN_ROOT/hooks/withdrawn-rulings.mjs" --withdraw <id> \
30
30
  --claim "<the withdrawn claim, verbatim>" \
31
31
  --because "<what disproved it>" \
32
+ --derived "<an artifact you left standing on it>" ... | --derived none \
32
33
  [--superseded-by <id>] [--reached <channel> ...]
33
34
  ```
34
35
 
35
36
  The verbatim claim is required and the command refuses without it: **a tombstone the holder of the
36
37
  claim cannot recognise reaches them without reaching them.**
37
38
 
39
+ - **`--derived` is required too, because correcting a premise leaves every inference standing.**
40
+ Updating the fact is the easy half. The conclusions you already drew from it are the half that
41
+ reached other agents and the human, and they do not retract themselves. Before you can record the
42
+ withdrawal you must name what you asserted, filed, or relayed while you believed the claim —
43
+ tracker state you set, a statement you made to your operator, a message you sent a peer session.
44
+
45
+ **The obligation is to produce the list, not to find something wrong in it.** `--derived none` is
46
+ a complete answer when you checked and nothing survives, and the record keeps it as an empty list
47
+ so a later reader can tell "audited, nothing standing" from "never audited". An absent answer is
48
+ refused; an empty one is not.
49
+
50
+ Measured instance: a session disproved a false claim that a credential CLI was unavailable,
51
+ updated the fact, and **two hours later still relayed to its human that a work item was blocked**
52
+ for a reason resting on the retracted claim. Three facts sat in one context and were never joined.
53
+
54
+ It binds here because nowhere else can carry it. Outside the learnings ledger's `provenance` refs,
55
+ **no artifact Lisa writes records the premise it rests on** — a blocked label, a relayed sentence,
56
+ a peer message carry no back-pointer. Nothing can go looking afterwards for what rested on a
57
+ retracted claim. You are the only party still holding that, at the only moment it is being
58
+ written down.
59
+
38
60
  - **The ledger is the retraction path, precisely because it is cheap.** Writing a finding feels
39
61
  productive; writing a retraction is a chore produced mid-task, after being corrected, when
40
62
  attention has moved on. A rule saying "always record retractions durably" is a discipline, and