@codyswann/lisa 4.84.5 → 4.84.7

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 (100) 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 +21 -4
  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/block-host-name-leak.mjs +130 -40
  9. package/plugins/lisa/hooks/block-host-name-leak.sh +5 -0
  10. package/plugins/lisa/hooks/host-name-command-context.mjs +409 -0
  11. package/plugins/lisa-agy/hooks/block-host-name-leak.mjs +130 -40
  12. package/plugins/lisa-agy/hooks/block-host-name-leak.sh +5 -0
  13. package/plugins/lisa-agy/hooks/host-name-command-context.mjs +409 -0
  14. package/plugins/lisa-agy/plugin.json +1 -1
  15. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  16. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  17. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  18. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  19. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  20. package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
  21. package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
  22. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa-copilot/hooks/block-host-name-leak.mjs +130 -40
  24. package/plugins/lisa-copilot/hooks/block-host-name-leak.sh +5 -0
  25. package/plugins/lisa-copilot/hooks/host-name-command-context.mjs +409 -0
  26. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  27. package/plugins/lisa-cursor/hooks/block-host-name-leak.mjs +130 -40
  28. package/plugins/lisa-cursor/hooks/block-host-name-leak.sh +5 -0
  29. package/plugins/lisa-cursor/hooks/host-name-command-context.mjs +409 -0
  30. package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
  31. package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
  32. package/plugins/lisa-devin/hooks/block-host-name-leak.mjs +130 -40
  33. package/plugins/lisa-devin/hooks/block-host-name-leak.sh +5 -0
  34. package/plugins/lisa-devin/hooks/host-name-command-context.mjs +409 -0
  35. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  37. package/plugins/lisa-expo-agy/plugin.json +1 -1
  38. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  40. package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
  41. package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
  42. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  43. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  44. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  45. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  46. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  47. package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
  48. package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
  49. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  50. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  51. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  52. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
  55. package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
  56. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  57. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  58. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  59. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
  62. package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
  63. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  64. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  65. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  66. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
  70. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  71. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  72. package/plugins/lisa-rails-agy/plugin.json +1 -1
  73. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
  76. package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
  77. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  79. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  80. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
  83. package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
  84. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  86. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  87. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
  90. package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
  91. package/plugins/src/base/hooks/block-host-name-leak.mjs +130 -40
  92. package/plugins/src/base/hooks/block-host-name-leak.sh +5 -0
  93. package/plugins/src/base/hooks/host-name-command-context.mjs +409 -0
  94. package/scripts/generate-agy-plugin-artifacts.mjs +7 -3
  95. package/scripts/lib/host-name-expanded-command-cases.mjs +286 -0
  96. package/scripts/lib/host-name-field-occurrence-cases.mjs +60 -0
  97. package/scripts/lib/host-name-review-cases.mjs +354 -0
  98. package/scripts/lib/host-name-target-cases.mjs +298 -0
  99. package/scripts/two-channel-couplings.json +29 -6
  100. package/scripts/verify-host-name-target-scope.mjs +373 -0
@@ -0,0 +1,298 @@
1
+ /** Named real-wrapper cases; only synthetic identities are used. */
2
+ export function hostNameTargetCases({
3
+ hostCwd,
4
+ lisaCwd,
5
+ unknownCwd,
6
+ body,
7
+ selectedLisa,
8
+ selectedHost,
9
+ relative,
10
+ quotedHost,
11
+ ambiguous,
12
+ fixtureName,
13
+ lisa,
14
+ host,
15
+ }) {
16
+ return [
17
+ [
18
+ "host explicit --repo allowed",
19
+ hostCwd,
20
+ `gh pr create --repo ${host} --title t --body-file ${body}`,
21
+ 0,
22
+ ],
23
+ [
24
+ "host explicit -R allowed",
25
+ hostCwd,
26
+ `gh issue create -R ${host} --title t --body-file ${body}`,
27
+ 0,
28
+ ],
29
+ [
30
+ "host explicit --repo= allowed",
31
+ hostCwd,
32
+ `gh issue create --repo=${host} --title t --body-file ${body}`,
33
+ 0,
34
+ ],
35
+ [
36
+ "host API endpoint allowed",
37
+ hostCwd,
38
+ `gh api repos/${host}/issues -X POST -f body=${fixtureName}`,
39
+ 0,
40
+ ],
41
+ [
42
+ "host origin allowed",
43
+ hostCwd,
44
+ `gh issue create --title t --body-file ${body}`,
45
+ 0,
46
+ ],
47
+ [
48
+ "protected explicit target blocked from host checkout",
49
+ hostCwd,
50
+ `gh issue create --repo ${lisa} --title t --body-file ${body}`,
51
+ 2,
52
+ ],
53
+ [
54
+ "protected origin blocked",
55
+ lisaCwd,
56
+ `gh issue create --title t --body-file ${body}`,
57
+ 2,
58
+ ],
59
+ [
60
+ "unknown target remains blocked",
61
+ unknownCwd,
62
+ `gh issue create --title t --body-file ${body}`,
63
+ 2,
64
+ ],
65
+ [
66
+ "protected clean body allowed",
67
+ lisaCwd,
68
+ `gh pr create --repo ${lisa} --title t --body 'A clean report.'`,
69
+ 0,
70
+ ],
71
+ [
72
+ "protected read-only request allowed",
73
+ lisaCwd,
74
+ `gh api repos/${lisa}/issues -X GET -F body=@${body}`,
75
+ 0,
76
+ ],
77
+ [
78
+ "API explicit POST field-file control blocked",
79
+ hostCwd,
80
+ `gh api repos/${lisa}/issues -X POST -F body=@${body}`,
81
+ 2,
82
+ ],
83
+ [
84
+ "review's See-repos body example remains blocked control",
85
+ lisaCwd,
86
+ `gh pr create --title t --body 'See repos/${host}/issues: ${fixtureName}'`,
87
+ 2,
88
+ ],
89
+ [
90
+ "API-path-leading body cannot exempt protected write",
91
+ lisaCwd,
92
+ `gh pr create --title t --body 'repos/${host}/issues: ${fixtureName}'`,
93
+ 2,
94
+ ],
95
+ [
96
+ "API unresolved placeholders retain protection",
97
+ lisaCwd,
98
+ `gh api 'repos/{owner}/{repo}/issues' -f body=${fixtureName}`,
99
+ 2,
100
+ ],
101
+ [
102
+ "API -F default POST is inspected",
103
+ hostCwd,
104
+ `gh api repos/${lisa}/issues -F body=@${body}`,
105
+ 2,
106
+ ],
107
+ [
108
+ "effective cd into protected checkout retains protection",
109
+ hostCwd,
110
+ `cd '${lisaCwd}' && gh issue create --title t --body '${fixtureName}'`,
111
+ 2,
112
+ ],
113
+ [
114
+ "effective cd into host checkout permits host naming itself",
115
+ lisaCwd,
116
+ `cd '${hostCwd}' && gh issue create --title t --body '${fixtureName}'`,
117
+ 0,
118
+ ],
119
+ [
120
+ "relative body file follows effective command cwd",
121
+ lisaCwd,
122
+ `cd '${relative}' && gh pr create --repo ${lisa} --title t --body-file body.md`,
123
+ 2,
124
+ ],
125
+ [
126
+ "GH_REPO protected override outranks host origin",
127
+ hostCwd,
128
+ `gh issue create --title t --body-file ${body}`,
129
+ 2,
130
+ { GH_REPO: lisa },
131
+ ],
132
+ [
133
+ "GH_REPO host override outranks protected origin",
134
+ lisaCwd,
135
+ `gh issue create --title t --body-file ${body}`,
136
+ 0,
137
+ { GH_REPO: host },
138
+ ],
139
+ [
140
+ "selected protected default outranks host origin",
141
+ selectedLisa,
142
+ `gh issue create --title t --body-file ${body}`,
143
+ 2,
144
+ ],
145
+ [
146
+ "selected host default outranks protected origin",
147
+ selectedHost,
148
+ `gh issue create --title t --body-file ${body}`,
149
+ 0,
150
+ ],
151
+
152
+ [
153
+ "literal GH_REPO assignment protects Lisa",
154
+ hostCwd,
155
+ `GH_REPO=${lisa} gh issue create --title t --body-file ${body}`,
156
+ 2,
157
+ ],
158
+ [
159
+ "literal assignment overrides inherited GH_REPO",
160
+ lisaCwd,
161
+ `GH_REPO=${host} gh issue create --title t --body-file ${body}`,
162
+ 0,
163
+ { GH_REPO: lisa },
164
+ ],
165
+ [
166
+ "env GH_REPO assignment protects Lisa",
167
+ hostCwd,
168
+ `env GH_REPO=${lisa} gh issue create --title t --body-file ${body}`,
169
+ 2,
170
+ ],
171
+ [
172
+ "env GH_REPO assignment permits host",
173
+ lisaCwd,
174
+ `env GH_REPO=${host} gh issue create --title t --body-file ${body}`,
175
+ 0,
176
+ ],
177
+ [
178
+ "explicit host flag outranks GH_REPO",
179
+ lisaCwd,
180
+ `gh issue create --repo ${host} --title t --body-file ${body}`,
181
+ 0,
182
+ { GH_REPO: lisa },
183
+ ],
184
+ [
185
+ "quoted directory separator stays literal",
186
+ lisaCwd,
187
+ `cd '${quotedHost}' && gh issue create --title t --body-file ${body}`,
188
+ 0,
189
+ ],
190
+ [
191
+ "quoted body separators cannot redirect target",
192
+ lisaCwd,
193
+ `gh pr create --title t --body '${fixtureName}; cd ${hostCwd} && gh issue create'`,
194
+ 2,
195
+ ],
196
+ [
197
+ "quoted repository-flag body stays prose",
198
+ lisaCwd,
199
+ `gh issue create --body '--repo=${host}'`,
200
+ 2,
201
+ ],
202
+ [
203
+ "last repository alias selects protected target",
204
+ hostCwd,
205
+ `gh issue create --repo ${host} -R ${lisa} --body-file ${body}`,
206
+ 2,
207
+ ],
208
+ [
209
+ "last repository alias selects host target",
210
+ lisaCwd,
211
+ `gh issue create --repo ${lisa} -R ${host} --body-file ${body}`,
212
+ 0,
213
+ ],
214
+ [
215
+ "last method alias makes a POST",
216
+ hostCwd,
217
+ `gh api repos/${lisa}/issues -X GET --method POST -F body=@${body}`,
218
+ 2,
219
+ ],
220
+ [
221
+ "last method alias keeps explicit GET read-only",
222
+ hostCwd,
223
+ `gh api repos/${lisa}/issues -X POST --method GET -F body=@${body}`,
224
+ 0,
225
+ ],
226
+ [
227
+ "attached -F defaults to POST",
228
+ hostCwd,
229
+ `gh api repos/${lisa}/issues -Fbody=@${body}`,
230
+ 2,
231
+ ],
232
+ [
233
+ "attached -R permits host target",
234
+ lisaCwd,
235
+ `gh issue create -R${host} --body-file ${body}`,
236
+ 0,
237
+ ],
238
+ [
239
+ "unsupported cwd prefix retains protection",
240
+ hostCwd,
241
+ `pushd '${lisaCwd}' && gh issue create --body ${fixtureName}`,
242
+ 2,
243
+ ],
244
+ [
245
+ "unresolved cwd retains protection",
246
+ hostCwd,
247
+ `cd "$UNKNOWN_DIRECTORY" && gh issue create --body ${fixtureName}`,
248
+ 2,
249
+ ],
250
+ [
251
+ "ambiguous unselected remotes retain protection",
252
+ ambiguous,
253
+ `gh issue create --body-file ${body}`,
254
+ 2,
255
+ ],
256
+ [
257
+ "host API placeholders resolve safely",
258
+ hostCwd,
259
+ `gh api 'repos/{owner}/{repo}/issues' -f body=${fixtureName}`,
260
+ 0,
261
+ ],
262
+ [
263
+ "unresolved repository flag retains protection",
264
+ hostCwd,
265
+ `gh issue create --repo '$UNKNOWN_REPOSITORY' --body ${fixtureName}`,
266
+ 2,
267
+ ],
268
+ [
269
+ "each command in a list retains protection",
270
+ hostCwd,
271
+ `gh issue create --repo ${host} --body ${fixtureName}; gh issue create --repo ${lisa} --body ${fixtureName}`,
272
+ 2,
273
+ ],
274
+ [
275
+ "actual cwd is separate from detector root",
276
+ relative,
277
+ `gh issue create --repo ${lisa} --body-file body.md`,
278
+ 2,
279
+ { CLAUDE_PROJECT_DIR: lisaCwd },
280
+ ],
281
+ [
282
+ "unknown cwd cannot silently inspect a relative body file elsewhere",
283
+ lisaCwd,
284
+ 'cd "$UNKNOWN_DIRECTORY" && gh issue create --repo CodySwannGT/lisa --body-file body.md',
285
+ 2,
286
+ {},
287
+ "BLOCKED: the working directory",
288
+ ],
289
+ [
290
+ "unknown cwd cannot silently inspect a relative API field elsewhere",
291
+ lisaCwd,
292
+ 'cd "$UNKNOWN_DIRECTORY" && gh api repos/CodySwannGT/lisa/issues --field body=@body.md',
293
+ 2,
294
+ {},
295
+ "BLOCKED: the working directory",
296
+ ],
297
+ ];
298
+ }
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "ratified": {
3
3
  "quality.yml::scripts/check-learnings-budget.ts": "Lisa-source-only branch, and the else arm is the delivery. The step tests for BOTH scripts/check-learnings-budget.ts and src/core/learnings-budget-check.ts, which co-exist only in this repository; every consumer takes the else arm and runs the prover as `bunx @codyswann/lisa@<their own declared version>`, which is the PACKAGE channel and not a caller-tree read at all. A trailing `grep -qE \"learnings budget (passed|saturated)|no learnings file\"` then refuses a run that printed no verdict, so the arm cannot pass vacuously. Ratified because the caller-tree read is unreachable outside this repository, not because the gap is tolerated.",
4
- "quality.yml::scripts/generate-nightly-e2e-guard-certificate.mjs": "Lisa-source-only branch. Both reusable jobs require `github.repository == 'CodySwannGT/lisa'` before the step can start, and the run body repeats that exact repository guard before checking this artifact path. Ordinary and private host callers therefore skip the step without reading or fetching from their own tree. The scoped branch fetches only the immutable refs needed to behavior-test Lisa's own retained certificate inputs. Ratified because the caller-tree read is unreachable outside this repository, not because an undelivered host dependency is tolerated."
4
+ "quality.yml::scripts/generate-nightly-e2e-guard-certificate.mjs": "Lisa-source-only branch. Both reusable jobs require `github.repository == 'CodySwannGT/lisa'` before the step can start, and the run body repeats that exact repository guard before checking this artifact path. Ordinary and private host callers therefore skip the step without reading or fetching from their own tree. The scoped branch fetches only the immutable refs needed to behavior-test Lisa's own retained certificate inputs. Ratified because the caller-tree read is unreachable outside this repository, not because an undelivered host dependency is tolerated.",
5
+ "quality.yml::scripts/verify-host-name-target-scope.mjs": "Lisa-source-only regression proof. The step requires `github.repository == 'CodySwannGT/lisa' && steps.gate_run.outcome == 'success'` before executing this driver. Every host caller skips the step without reading this path. Ratified because the caller-tree read is unreachable outside this repository; no host dependency is introduced."
5
6
  },
6
7
  "staleness": {
7
8
  "npm-updater.yml::scripts/lisa-npm-updater.mjs": {
@@ -99,30 +100,34 @@
99
100
  },
100
101
  "quality.yml::scripts/lisa-work-item.mjs": {
101
102
  "decision": "handshake"
103
+ },
104
+ "quality.yml::scripts/verify-host-name-target-scope.mjs": {
105
+ "decision": "not-needed",
106
+ "reason": "Unreachable outside this repository under the exact step-level repository guard ratified above. The driver and its cases run from the same Lisa checkout as the hooks under test. No consuming caller reads its installed or caller-tree copy through this workflow step, so no independently versioned consumer copy participates in this coupling."
102
107
  }
103
108
  },
104
109
  "inspected": {
105
110
  "workflows": 26,
106
- "steps": 786,
107
- "couplings": 36,
111
+ "steps": 787,
112
+ "couplings": 37,
108
113
  "inventory": 186
109
114
  },
110
115
  "counts": {
111
116
  "package-backed": 11,
112
117
  "apply-lagged": 23,
113
118
  "never-delivered": 0,
114
- "undelivered": 2
119
+ "undelivered": 3
115
120
  },
116
121
  "detectionCounts": {
117
122
  "version-handshake": 4,
118
123
  "capability-probe": 0,
119
124
  "existence-only": 5,
120
125
  "no-probe": 14,
121
- "unchecked": 2
126
+ "unchecked": 3
122
127
  },
123
128
  "decisionCounts": {
124
129
  "handshake": 4,
125
- "not-needed": 11,
130
+ "not-needed": 12,
126
131
  "warranted": 10
127
132
  },
128
133
  "couplings": [
@@ -675,6 +680,24 @@
675
680
  "all/copy-overwrite"
676
681
  ],
677
682
  "detail": "`quality.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/lisa-work-item.mjs` from the CALLER's tree with no package-relative candidate, and Lisa delivers that path on the `lisa apply` channel (all/copy-overwrite). The two halves land in the wrong order: this step is live everywhere immediately, the file it needs is live only where somebody applied. The read sits behind an existence test, which is ALL this scan examined of the step's control flow: it did not read the test's other branch, any fallback, any explicit `exit`, or any verification of the step's output. Whether an absent path skips quietly, falls back, or fails loudly is therefore NOT MEASURED — read the step before concluding it proves nothing. The shape worth ruling out is the silent one, where a skip posts no context and an absent required context is not a red one. The step's text does carry `else-branch`, `exit-zero`, `exit-nonzero`, `error-annotation`, `notice-annotation` — located in the step, deliberately NOT related to this read, and enough to make \"it skips silently\" a claim to check rather than assume. STALENESS (a separate dimension from the delivery verdict above): `version-handshake`. The delivered artifact answers a contract version and the workflow asks for one, so a copy too old to speak the same contract is NAMED rather than silently run. Tokens found: `artifact-declares-version`, `artifact-answers-version`, `step-requests-version`, `workflow-requests-version`. `workflow-requests-version` is workflow-scoped — it does not say THIS step asks."
683
+ },
684
+ {
685
+ "key": "quality.yml::scripts/verify-host-name-target-scope.mjs",
686
+ "workflow": "quality.yml",
687
+ "path": "scripts/verify-host-name-target-scope.mjs",
688
+ "channel": "undelivered",
689
+ "verdict": "undelivered",
690
+ "remedy": "author-the-artifact",
691
+ "guarded": false,
692
+ "handling": [],
693
+ "detection": "unchecked",
694
+ "stalenessSignals": [
695
+ "workflow-requests-version"
696
+ ],
697
+ "decision": "not-needed",
698
+ "reason": "Unreachable outside this repository under the exact step-level repository guard ratified above. The driver and its cases run from the same Lisa checkout as the hooks under test. No consuming caller reads its installed or caller-tree copy through this workflow step, so no independently versioned consumer copy participates in this coupling.",
699
+ "lanes": [],
700
+ "detail": "`quality.yml` is delivered at `@main`, so this step is live in every consumer on their next run. It reads `scripts/verify-host-name-target-scope.mjs` from the CALLER's tree, and Lisa ships no such path in any delivery lane — no apply and no bump ever produces it. Either the consumer authors it, or whatever the step does where the path is missing runs instead — and that branch is the part this scan does not read. No existence test guards the read, which is ALL this scan examined of the step's control flow: it did not read anything that could absorb the failure. An absent path most likely fails the job loudly — the better of the two failures, because it is visible — but that is inferred from the missing guard, NOT MEASURED. The step's text carries none of the tokens this scan can see (`else-branch`, `exit-zero`, `exit-nonzero`, `error-annotation`, `notice-annotation`, `failure-suppression`), which is a statement about those names and not about the step's behaviour. STALENESS (a separate dimension from the delivery verdict above): `unchecked`. Lisa delivers nothing at this path, so there is no artifact to ask whether it could answer a version. The staleness half is UNKNOWN here — not current, and not probe-less. Tokens found: `workflow-requests-version`. `workflow-requests-version` is workflow-scoped — it does not say THIS step asks."
678
701
  }
679
702
  ]
680
703
  }