@codyswann/lisa 4.37.2 → 4.38.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.
- package/all/copy-contents/.gitattributes +9 -0
- package/all/copy-contents/gitignore +6 -0
- package/dist/core/learnings-merge-driver.d.ts +8 -0
- package/dist/core/learnings-merge-driver.d.ts.map +1 -1
- package/dist/core/learnings-merge-driver.js +17 -0
- package/dist/core/learnings-merge-driver.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +4 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +64 -11
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/package.json +6 -4
- package/plugins/lisa/.claude-plugin/plugin.json +28 -1
- package/plugins/lisa/.codex-plugin/hooks.json +27 -0
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-github-write-issue/SKILL.md +11 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-jira-write-ticket/SKILL.md +11 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-linear-write-issue/SKILL.md +11 -0
- package/plugins/lisa/.codex-plugin/skills/lisa-repair-intake/SKILL.md +30 -2
- package/plugins/lisa/hooks/inject-resolved-config.mjs +26 -7
- package/plugins/lisa/hooks/withdrawn-rulings.mjs +525 -0
- package/plugins/lisa/hooks/withdrawn-rulings.sh +24 -0
- package/plugins/lisa/rules/eager/config-resolution.md +3 -1
- package/plugins/lisa/rules/eager/withdrawn-rulings.md +69 -0
- package/plugins/lisa/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa/rules/reference/withdrawn-rulings.md +114 -0
- package/plugins/lisa/scripts/intake-blocker-reprobe.mjs +120 -3
- package/plugins/lisa/skills/lisa-github-write-issue/SKILL.md +11 -0
- package/plugins/lisa/skills/lisa-jira-write-ticket/SKILL.md +11 -0
- package/plugins/lisa/skills/lisa-linear-write-issue/SKILL.md +11 -0
- package/plugins/lisa/skills/lisa-repair-intake/SKILL.md +30 -2
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/scripts/intake-blocker-reprobe.mjs +120 -3
- package/plugins/lisa-agy/skills/lisa-github-write-issue/SKILL.md +11 -0
- package/plugins/lisa-agy/skills/lisa-jira-write-ticket/SKILL.md +11 -0
- package/plugins/lisa-agy/skills/lisa-linear-write-issue/SKILL.md +11 -0
- package/plugins/lisa-agy/skills/lisa-repair-intake/SKILL.md +30 -2
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +19 -1
- package/plugins/lisa-copilot/hooks/inject-resolved-config.mjs +26 -7
- package/plugins/lisa-copilot/hooks/withdrawn-rulings.mjs +525 -0
- package/plugins/lisa-copilot/hooks/withdrawn-rulings.sh +24 -0
- package/plugins/lisa-copilot/rules/eager/config-resolution.md +3 -1
- package/plugins/lisa-copilot/rules/eager/withdrawn-rulings.md +69 -0
- package/plugins/lisa-copilot/rules/reference/config-resolution.md +1 -1
- package/plugins/lisa-copilot/rules/reference/withdrawn-rulings.md +114 -0
- package/plugins/lisa-copilot/scripts/intake-blocker-reprobe.mjs +120 -3
- package/plugins/lisa-copilot/skills/lisa-github-write-issue/SKILL.md +11 -0
- package/plugins/lisa-copilot/skills/lisa-jira-write-ticket/SKILL.md +11 -0
- package/plugins/lisa-copilot/skills/lisa-linear-write-issue/SKILL.md +11 -0
- package/plugins/lisa-copilot/skills/lisa-repair-intake/SKILL.md +30 -2
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/hooks/hooks.json +10 -0
- package/plugins/lisa-cursor/hooks/inject-resolved-config.mjs +26 -7
- package/plugins/lisa-cursor/hooks/withdrawn-rulings.mjs +525 -0
- package/plugins/lisa-cursor/hooks/withdrawn-rulings.sh +24 -0
- package/plugins/lisa-cursor/rules/config-resolution-reference.mdc +1 -1
- package/plugins/lisa-cursor/rules/config-resolution.mdc +3 -1
- package/plugins/lisa-cursor/rules/withdrawn-rulings-reference.mdc +119 -0
- package/plugins/lisa-cursor/rules/withdrawn-rulings.mdc +74 -0
- package/plugins/lisa-cursor/scripts/intake-blocker-reprobe.mjs +120 -3
- package/plugins/lisa-cursor/skills/lisa-github-write-issue/SKILL.md +11 -0
- package/plugins/lisa-cursor/skills/lisa-jira-write-ticket/SKILL.md +11 -0
- package/plugins/lisa-cursor/skills/lisa-linear-write-issue/SKILL.md +11 -0
- package/plugins/lisa-cursor/skills/lisa-repair-intake/SKILL.md +30 -2
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/.claude-plugin/plugin.json +27 -0
- package/plugins/src/base/hooks/inject-resolved-config.mjs +26 -7
- package/plugins/src/base/hooks/withdrawn-rulings.mjs +525 -0
- package/plugins/src/base/hooks/withdrawn-rulings.sh +24 -0
- package/plugins/src/base/rules/eager/config-resolution.md +3 -1
- package/plugins/src/base/rules/eager/withdrawn-rulings.md +69 -0
- package/plugins/src/base/rules/reference/config-resolution.md +1 -1
- package/plugins/src/base/rules/reference/withdrawn-rulings.md +114 -0
- package/plugins/src/base/scripts/intake-blocker-reprobe.mjs +120 -3
- package/plugins/src/base/skills/lisa-github-write-issue/SKILL.md +11 -0
- package/plugins/src/base/skills/lisa-jira-write-ticket/SKILL.md +11 -0
- package/plugins/src/base/skills/lisa-linear-write-issue/SKILL.md +11 -0
- package/plugins/src/base/skills/lisa-repair-intake/SKILL.md +30 -2
- package/scripts/lib/hook-registration-audit.mjs +612 -0
- package/scripts/measure-tmpdir-growth.mjs +925 -0
- package/typescript/copy-contents/.husky/pre-push +98 -26
package/package.json
CHANGED
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
"check:orphan-processes": "node scripts/check-orphan-test-processes.mjs",
|
|
67
67
|
"check:merge-drivers": "node scripts/check-merge-driver-registration.mjs",
|
|
68
68
|
"check:failure-signatures": "node plugins/src/base/hooks/failure-signature-index.mjs --check",
|
|
69
|
+
"check:withdrawn-rulings": "node plugins/src/base/hooks/withdrawn-rulings.mjs --check",
|
|
69
70
|
"check:template-workflow-refs": "node scripts/check-template-workflow-refs.mjs",
|
|
70
71
|
"check:third-party-action-pins": "node scripts/check-third-party-action-pins.mjs",
|
|
71
72
|
"check:workflow-package-paths": "node scripts/check-workflow-package-paths.mjs",
|
|
@@ -83,6 +84,7 @@
|
|
|
83
84
|
"verify:packed-learnings-contract": "bun run build:dist && node scripts/verify-packed-learnings-contract.mjs",
|
|
84
85
|
"verify:health-agentic": "bun run build:dist && node scripts/verify-health-agentic-built.mjs",
|
|
85
86
|
"verify:health-consumer": "bun run build:dist && node scripts/verify-health-consumer-built.mjs",
|
|
87
|
+
"measure:tmpdir-growth": "node scripts/measure-tmpdir-growth.mjs",
|
|
86
88
|
"lint:staged": "lint-staged --config .lintstagedrc.json"
|
|
87
89
|
},
|
|
88
90
|
"engines": {
|
|
@@ -167,7 +169,7 @@
|
|
|
167
169
|
"zod-validation-error": "^4.0.0"
|
|
168
170
|
},
|
|
169
171
|
"name": "@codyswann/lisa",
|
|
170
|
-
"version": "4.
|
|
172
|
+
"version": "4.38.0",
|
|
171
173
|
"description": "Claude Code governance framework that applies guardrails, guidance, and automated enforcement to projects",
|
|
172
174
|
"main": "dist/index.js",
|
|
173
175
|
"exports": {
|
|
@@ -315,7 +317,7 @@
|
|
|
315
317
|
"test": "tests"
|
|
316
318
|
},
|
|
317
319
|
"types": "./dist/index.d.ts",
|
|
318
|
-
"lisaReleaseCommit": "
|
|
319
|
-
"gitHead": "
|
|
320
|
-
"lisaReleaseTag": "v4.
|
|
320
|
+
"lisaReleaseCommit": "99484f8dc349184afd44f96a890524223c3ea97c",
|
|
321
|
+
"gitHead": "99484f8dc349184afd44f96a890524223c3ea97c",
|
|
322
|
+
"lisaReleaseTag": "v4.38.0"
|
|
321
323
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.38.0",
|
|
4
4
|
"description": "Universal governance — agents, skills, commands, hooks, and rules for all projects",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -89,6 +89,15 @@
|
|
|
89
89
|
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/enforce-team-first.sh"
|
|
90
90
|
}
|
|
91
91
|
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"matcher": "Bash|Edit|Write|Read|Task|Grep|Glob",
|
|
95
|
+
"hooks": [
|
|
96
|
+
{
|
|
97
|
+
"type": "command",
|
|
98
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/withdrawn-rulings.sh --hook"
|
|
99
|
+
}
|
|
100
|
+
]
|
|
92
101
|
}
|
|
93
102
|
],
|
|
94
103
|
"PreToolUse": [
|
|
@@ -201,6 +210,15 @@
|
|
|
201
210
|
}
|
|
202
211
|
]
|
|
203
212
|
},
|
|
213
|
+
{
|
|
214
|
+
"matcher": "",
|
|
215
|
+
"hooks": [
|
|
216
|
+
{
|
|
217
|
+
"type": "command",
|
|
218
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/withdrawn-rulings.sh --session-start"
|
|
219
|
+
}
|
|
220
|
+
]
|
|
221
|
+
},
|
|
204
222
|
{
|
|
205
223
|
"matcher": "",
|
|
206
224
|
"hooks": [
|
|
@@ -248,6 +266,15 @@
|
|
|
248
266
|
}
|
|
249
267
|
]
|
|
250
268
|
},
|
|
269
|
+
{
|
|
270
|
+
"matcher": "",
|
|
271
|
+
"hooks": [
|
|
272
|
+
{
|
|
273
|
+
"type": "command",
|
|
274
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/withdrawn-rulings.sh --session-start"
|
|
275
|
+
}
|
|
276
|
+
]
|
|
277
|
+
},
|
|
251
278
|
{
|
|
252
279
|
"matcher": "",
|
|
253
280
|
"hooks": [
|
|
@@ -38,6 +38,15 @@
|
|
|
38
38
|
"command": "${PLUGIN_ROOT}/hooks/threshold-ratchet.sh"
|
|
39
39
|
}
|
|
40
40
|
]
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"matcher": "Bash|Edit|Write|Read|Task|Grep|Glob",
|
|
44
|
+
"hooks": [
|
|
45
|
+
{
|
|
46
|
+
"type": "command",
|
|
47
|
+
"command": "${PLUGIN_ROOT}/hooks/withdrawn-rulings.sh --hook"
|
|
48
|
+
}
|
|
49
|
+
]
|
|
41
50
|
}
|
|
42
51
|
],
|
|
43
52
|
"PreToolUse": [
|
|
@@ -123,6 +132,15 @@
|
|
|
123
132
|
}
|
|
124
133
|
]
|
|
125
134
|
},
|
|
135
|
+
{
|
|
136
|
+
"matcher": "",
|
|
137
|
+
"hooks": [
|
|
138
|
+
{
|
|
139
|
+
"type": "command",
|
|
140
|
+
"command": "${PLUGIN_ROOT}/hooks/withdrawn-rulings.sh --session-start"
|
|
141
|
+
}
|
|
142
|
+
]
|
|
143
|
+
},
|
|
126
144
|
{
|
|
127
145
|
"matcher": "",
|
|
128
146
|
"hooks": [
|
|
@@ -161,6 +179,15 @@
|
|
|
161
179
|
}
|
|
162
180
|
]
|
|
163
181
|
},
|
|
182
|
+
{
|
|
183
|
+
"matcher": "",
|
|
184
|
+
"hooks": [
|
|
185
|
+
{
|
|
186
|
+
"type": "command",
|
|
187
|
+
"command": "${PLUGIN_ROOT}/hooks/withdrawn-rulings.sh --session-start"
|
|
188
|
+
}
|
|
189
|
+
]
|
|
190
|
+
},
|
|
164
191
|
{
|
|
165
192
|
"matcher": "",
|
|
166
193
|
"hooks": [
|
|
@@ -276,6 +276,17 @@ Held for a human product call: <reason>.
|
|
|
276
276
|
<!-- [lisa-human-gate] reason=<short-slug> -->
|
|
277
277
|
```
|
|
278
278
|
|
|
279
|
+
**Stamp both surfaces, not just the marker.** Also apply the configured `human_needed` marker
|
|
280
|
+
label (`github.labels.build.human_needed`, default `human-needed`) to the issue, via `gh issue edit`/`gh issue create --label`. The marker in the body and the label say the same thing,
|
|
281
|
+
and a filing that carries only one of them is a **half-armed gate**: sweeps that read the body
|
|
282
|
+
honour it, and sweeps that read labels do not. That is not hypothetical — the repair sweep that
|
|
283
|
+
normalizes items carrying no lifecycle label keys on the *absence* of `human_needed`, so a
|
|
284
|
+
marker-only hold was its population by construction and got promoted into the build queue (#3805).
|
|
285
|
+
The marker remains the authoritative declaration; the label is what makes the hold visible to a
|
|
286
|
+
person scanning a board and to any path that has not yet been routed through the shared reader.
|
|
287
|
+
If the label does not exist in the tracker, create it, or record that it could not be applied and
|
|
288
|
+
proceed — the marker still holds. Never file the label *instead of* the marker.
|
|
289
|
+
|
|
279
290
|
If a leaf arrives with `build_ready` omitted or `false` **and** no `human_gate`, do not create it: report the incomplete handoff and name both ways to resolve it (`build_ready: true`, or a `human_gate` reason). Containers are exempt — their state rolls up from children, so they need neither.
|
|
280
291
|
|
|
281
292
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
@@ -261,6 +261,17 @@ Held for a human product call: <reason>.
|
|
|
261
261
|
<!-- [lisa-human-gate] reason=<short-slug> -->
|
|
262
262
|
```
|
|
263
263
|
|
|
264
|
+
**Stamp both surfaces, not just the marker.** Also apply the configured `human_needed` marker
|
|
265
|
+
label (`jira.labels.human_needed`, default `Human Needed`) to the ticket, via the ticket's `labels` field. The marker in the body and the label say the same thing,
|
|
266
|
+
and a filing that carries only one of them is a **half-armed gate**: sweeps that read the body
|
|
267
|
+
honour it, and sweeps that read labels do not. That is not hypothetical — the repair sweep that
|
|
268
|
+
normalizes items carrying no lifecycle label keys on the *absence* of `human_needed`, so a
|
|
269
|
+
marker-only hold was its population by construction and got promoted into the build queue (#3805).
|
|
270
|
+
The marker remains the authoritative declaration; the label is what makes the hold visible to a
|
|
271
|
+
person scanning a board and to any path that has not yet been routed through the shared reader.
|
|
272
|
+
If the label does not exist in the tracker, create it, or record that it could not be applied and
|
|
273
|
+
proceed — the marker still holds. Never file the label *instead of* the marker.
|
|
274
|
+
|
|
264
275
|
If a leaf arrives with `build_ready` omitted or `false` **and** no `human_gate`, do not create it: report the incomplete handoff and name both ways to resolve it (`build_ready: true`, or a `human_gate` reason). Containers are exempt — their status rolls up from children, so they need neither.
|
|
265
276
|
|
|
266
277
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
@@ -280,6 +280,17 @@ Held for a human product call: <reason>.
|
|
|
280
280
|
<!-- [lisa-human-gate] reason=<short-slug> -->
|
|
281
281
|
```
|
|
282
282
|
|
|
283
|
+
**Stamp both surfaces, not just the marker.** Also apply the configured `human_needed` marker
|
|
284
|
+
label (`linear.labels.build.human_needed`, default `human-needed`) to the Issue, via the Issue's labels (create it via `create_issue_label` if absent). The marker in the body and the label say the same thing,
|
|
285
|
+
and a filing that carries only one of them is a **half-armed gate**: sweeps that read the body
|
|
286
|
+
honour it, and sweeps that read labels do not. That is not hypothetical — the repair sweep that
|
|
287
|
+
normalizes items carrying no lifecycle label keys on the *absence* of `human_needed`, so a
|
|
288
|
+
marker-only hold was its population by construction and got promoted into the build queue (#3805).
|
|
289
|
+
The marker remains the authoritative declaration; the label is what makes the hold visible to a
|
|
290
|
+
person scanning a board and to any path that has not yet been routed through the shared reader.
|
|
291
|
+
If the label does not exist in the tracker, create it, or record that it could not be applied and
|
|
292
|
+
proceed — the marker still holds. Never file the label *instead of* the marker.
|
|
293
|
+
|
|
283
294
|
If a leaf arrives with `build_ready` omitted or `false` **and** no `human_gate`, do not create it: report the incomplete handoff and name both ways to resolve it (`build_ready: true`, or a `human_gate` reason). Containers are exempt — their state rolls up from children, so they need neither.
|
|
284
295
|
|
|
285
296
|
## Phase 5.5 — Validate (Pre-write Gate)
|
|
@@ -951,6 +951,23 @@ with labels like `build-ready`, or with no Lisa status label at all, that are in
|
|
|
951
951
|
selected by `intake_mode`. If `intake_mode=prd`, only PRD-classified issues are normalized. If
|
|
952
952
|
`intake_mode=build`, every non-PRD issue is normalized as a build ticket. If `intake_mode=both`,
|
|
953
953
|
classify PRDs first and normalize all remaining issues as build tickets.
|
|
954
|
+
2a. **Ask whether a person is holding it, before anything else.** Call
|
|
955
|
+
`planLabelNormalization({ labels, body, humanNeededLabel, lifecycleLabels, readyLabel })` from
|
|
956
|
+
`scripts/intake-blocker-reprobe.mjs` for every candidate and apply exactly the verdict it
|
|
957
|
+
returns. Do **not** re-implement the test here and do **not** decide held-ness from labels
|
|
958
|
+
alone: the vendor writers stamp the `[lisa-human-gate]` marker into the body of a deliberate
|
|
959
|
+
hold, and `human_needed` is one of the lifecycle labels this sweep keys on the **absence** of —
|
|
960
|
+
so an item held exactly as the filing contract instructs is a member of this swept population by
|
|
961
|
+
construction, and a label-only read promoted it into the build queue (#3805). The
|
|
962
|
+
`[lisa-human-gate]` exclusion already existed in the read-only "Ungated non-ready filing" sweep
|
|
963
|
+
below; the one sweep that writes was the one that could not see it.
|
|
964
|
+
|
|
965
|
+
On `normalize: false` with reason `human-gate`, **stop for that item**: apply no label, do not
|
|
966
|
+
classify it, and report it read-only per step 5. Writing a label here — even the human-needed
|
|
967
|
+
marker — would turn a match into durable state on a second path, and the gate test is a plain
|
|
968
|
+
substring match whose precision is a separate open defect (#3815). Refusing and reporting is
|
|
969
|
+
the safe failure direction without the latch. Count these under `held_for_person`, never under
|
|
970
|
+
`normalized_ready`.
|
|
954
971
|
3. Classify the issue:
|
|
955
972
|
- **PRD** if it has PRD labels/markers (`prd`, `type:PRD`, `kind:prd`), PRD structure
|
|
956
973
|
(`## Problem`, `## Goals`, `## Validation Journey`, generated-work/backlink sections), or
|
|
@@ -964,7 +981,8 @@ with labels like `build-ready`, or with no Lisa status label at all, that are in
|
|
|
964
981
|
- **Ambiguous PRD/build** if strong PRD and build classifications both match. In `intake_mode=prd`
|
|
965
982
|
normalize as PRD; in `intake_mode=build` normalize as build; in `intake_mode=both`, prefer PRD
|
|
966
983
|
only when the body has PRD structure, otherwise build.
|
|
967
|
-
4. Apply exactly one configured ready label for the classified lifecycle
|
|
984
|
+
4. Apply exactly one configured ready label for the classified lifecycle — and only when step
|
|
985
|
+
2a returned `normalize: true`; its `actions.addReadyLabel` is the label to apply, verbatim:
|
|
968
986
|
- PRD → add the configured PRD `ready` label (default `prd-ready`).
|
|
969
987
|
- Build ticket → add the configured build `ready` label (default `status:ready`).
|
|
970
988
|
Keep any unofficial labels for auditability unless the project has explicitly configured one as a
|
|
@@ -972,7 +990,11 @@ with labels like `build-ready`, or with no Lisa status label at all, that are in
|
|
|
972
990
|
normalization makes the next normal `lisa-intake` run pick it up.
|
|
973
991
|
5. Post one idempotent `[lisa-repair-intake]` note naming the classification and the configured label
|
|
974
992
|
applied. Include the normalization result in the loop-prevention fingerprint so repeated repair
|
|
975
|
-
cycles do not spam comments.
|
|
993
|
+
cycles do not spam comments. For an item step 2a held, post `formatNormalizationHoldNote()`
|
|
994
|
+
instead — it says that nothing was changed and how a person resumes the item, which is the
|
|
995
|
+
opposite of what the reconciliation note says and must not be substituted for it. A promotion
|
|
996
|
+
declined silently is invisible, which is the quieter version of the failure this step exists to
|
|
997
|
+
prevent, so name every held item in the cycle summary via `summarizeHumanGateHolds([...])`.
|
|
976
998
|
|
|
977
999
|
### Ungated non-ready filing → surface as an incomplete handoff (read-only)
|
|
978
1000
|
|
|
@@ -1223,6 +1245,8 @@ It MAY:
|
|
|
1223
1245
|
Epic/Story container** from its hierarchy/body-parentage children — so rollup and the GitHub UI can
|
|
1224
1246
|
rely on the native graph. This repairs structure only; it does not ship, transition, or verify the
|
|
1225
1247
|
parent.
|
|
1248
|
+
- Leave a normalization candidate untouched and report it when it is held for a person — the
|
|
1249
|
+
human gate is consulted before classification and its refusal is absolute.
|
|
1226
1250
|
- Normalize a GitHub issue with no configured lifecycle label by adding the configured PRD or build
|
|
1227
1251
|
`ready` label after classifying the issue. This is a visibility repair, not a claim; the item
|
|
1228
1252
|
remains open and unclaimed for normal intake.
|
|
@@ -1305,6 +1329,10 @@ Report outcomes in these buckets:
|
|
|
1305
1329
|
from hierarchy/body-parentage) whose missing native sub-issue links were attached.
|
|
1306
1330
|
- `normalized_ready` — GitHub issues missing official lifecycle labels that were classified and
|
|
1307
1331
|
given the configured PRD/build `ready` label so normal intake can claim them.
|
|
1332
|
+
- `held_for_person` — normalization candidates left exactly as they were because a person is
|
|
1333
|
+
holding them, per the human gate in step 2a of that repair. Nothing was written to them. This
|
|
1334
|
+
bucket is never merged into `normalized_ready` or `errors`: "a person parked this and I honoured
|
|
1335
|
+
it" is a repair outcome, not a failure and not a promotion.
|
|
1308
1336
|
- `still_blocked` — examined and intentionally left `blocked`, with the active reason.
|
|
1309
1337
|
- `reversal_suppressed` — a repair this skill previously made was reversed by a human, so the
|
|
1310
1338
|
classification was **not** re-applied. Name the **reversed transition** (role, direction, and
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
* @module inject-resolved-config
|
|
52
52
|
*/
|
|
53
53
|
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
54
|
-
import { join } from "node:path";
|
|
54
|
+
import { basename, join } from "node:path";
|
|
55
55
|
import { fileURLToPath } from "node:url";
|
|
56
56
|
|
|
57
57
|
/** Committed, project-wide configuration. */
|
|
@@ -799,13 +799,32 @@ export function buildContext(projectDir) {
|
|
|
799
799
|
? `${MAIN_CONFIG} + ${LOCAL_CONFIG} (local wins where they overlap)`
|
|
800
800
|
: `${MAIN_CONFIG} (no local override file)`;
|
|
801
801
|
|
|
802
|
+
// The block used to say "this project's" — a possessive with no referent
|
|
803
|
+
// anywhere in its text, so two repositories emitted blocks that were
|
|
804
|
+
// character-identical except for the values. An agent standing in one
|
|
805
|
+
// directory while doing work governed by another read something perfectly
|
|
806
|
+
// true about the directory and wrong about the work, and the next sentence
|
|
807
|
+
// told it not to open the files that would have shown the difference. Six
|
|
808
|
+
// independent agent cycles reached the same false conclusion from one such
|
|
809
|
+
// block (CodySwannGT/lisa#3765).
|
|
810
|
+
//
|
|
811
|
+
// `basename` rather than the git remote: naming the subject must not cost a
|
|
812
|
+
// subprocess on a hook that runs at every session and subagent start, and it
|
|
813
|
+
// must not fail in a directory that is not a git checkout. The absolute path
|
|
814
|
+
// beside it is the unambiguous identifier; the basename is the short name a
|
|
815
|
+
// reader actually compares against the work in front of them.
|
|
816
|
+
const subject = basename(projectDir) || projectDir;
|
|
817
|
+
|
|
802
818
|
return block(
|
|
803
|
-
`These are
|
|
804
|
-
`
|
|
805
|
-
`
|
|
806
|
-
`
|
|
807
|
-
`
|
|
808
|
-
`
|
|
819
|
+
`These are the EFFECTIVE Lisa configuration values for ${subject}, resolved from ${sources} ` +
|
|
820
|
+
`at ${projectDir}.\n` +
|
|
821
|
+
`Act on them directly and do not act against them. They describe THAT directory: if your ` +
|
|
822
|
+
`work targets a different repository, read that repository's config rather than these. For ` +
|
|
823
|
+
`work in ${subject}, do not re-read the config files to learn these values. A line marked ` +
|
|
824
|
+
`[Lisa built-in default] is NOT something ${subject} declared. A key whose NAME is identity- ` +
|
|
825
|
+
`or credential-shaped is withheld and counted, and a VALUE matching a known credential shape ` +
|
|
826
|
+
`is replaced with ${REDACTED}: a best-effort filter, not proof that anything it left alone ` +
|
|
827
|
+
`is safe to repeat.\n\n` +
|
|
809
828
|
renderBody(resolved)
|
|
810
829
|
);
|
|
811
830
|
}
|