@junghanacs/entwurf 0.23.1 → 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/BASELINE.md +1 -0
  2. package/CHANGELOG.md +628 -0
  3. package/DELIVERY.md +24 -1
  4. package/FAQ.md +47 -0
  5. package/README.md +5 -3
  6. package/VERIFY.md +20 -2
  7. package/demo/README.md +5 -2
  8. package/docs/acp-backend-rail.md +49 -2
  9. package/docs/setup-clean-host.md +8 -7
  10. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +38 -5
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/context.js +19 -5
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/callback-env.js +68 -0
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/control-send-receipt.js +101 -0
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +6 -2
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +17 -1
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-runner.js +4 -0
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send.js +53 -6
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +38 -3
  19. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +54 -22
  20. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +20 -6
  21. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-placement.js +24 -4
  22. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +19 -10
  23. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-omp.js +35 -42
  24. package/mcp/entwurf-bridge/dist/protocol.js +0 -7
  25. package/mcp/entwurf-bridge/dist/scripts/doctor-pi-provider.js +40 -3
  26. package/mcp/entwurf-bridge/dist/scripts/herdr-rails.mjs +72 -0
  27. package/mcp/entwurf-bridge/dist/scripts/probe-bridge-command.js +1 -0
  28. package/mcp/entwurf-bridge/src/index.ts +46 -5
  29. package/mcp/entwurf-bridge/test.sh +2 -2
  30. package/package.json +11 -9
  31. package/pi-extensions/entwurf-control.ts +83 -154
  32. package/pi-extensions/lib/acp/backend.ts +16 -6
  33. package/pi-extensions/lib/acp/context.ts +30 -10
  34. package/pi-extensions/lib/acp/session-store.ts +2 -2
  35. package/pi-extensions/lib/callback-env.ts +78 -0
  36. package/pi-extensions/lib/compaction-send-guard.ts +6 -1
  37. package/pi-extensions/lib/control-send-receipt.ts +108 -0
  38. package/pi-extensions/lib/entwurf-v2-contract-schema.ts +1 -1
  39. package/pi-extensions/lib/entwurf-v2-contract.ts +6 -2
  40. package/pi-extensions/lib/entwurf-v2-production.ts +19 -1
  41. package/pi-extensions/lib/entwurf-v2-runner.ts +23 -1
  42. package/pi-extensions/lib/entwurf-v2-send.ts +82 -6
  43. package/pi-extensions/lib/entwurf-v2-surface.ts +42 -3
  44. package/pi-extensions/lib/fresh-call-composition.ts +56 -22
  45. package/pi-extensions/lib/herdr-fresh-call.ts +25 -7
  46. package/pi-extensions/lib/herdr-placement.ts +24 -4
  47. package/pi-extensions/lib/mux-fresh-call.ts +23 -8
  48. package/pi-extensions/meta-bridge-omp.ts +35 -48
  49. package/protocol.js +0 -8
  50. package/run.sh +306 -53
  51. package/scripts/check-acp-backend-preflight.ts +117 -9
  52. package/scripts/check-acp-carrier-augment.ts +6 -4
  53. package/scripts/check-acp-event-mapper.ts +17 -6
  54. package/scripts/check-acp-prompt-builder.ts +17 -9
  55. package/scripts/check-acp-prompt-lifecycle.ts +23 -6
  56. package/scripts/check-acp-session-reuse.ts +64 -51
  57. package/scripts/check-acp-session-store.ts +31 -8
  58. package/scripts/check-acp-stop-reason.ts +20 -2
  59. package/scripts/check-acp-stream-hooks.ts +22 -5
  60. package/scripts/check-acp-usage-accounting.ts +33 -9
  61. package/scripts/check-entwurf-bridge-boot.ts +16 -1
  62. package/scripts/check-entwurf-v2-surface.ts +289 -10
  63. package/scripts/check-fresh-call-dispatch.ts +4 -5
  64. package/scripts/check-gate-qualification.ts +51 -9
  65. package/scripts/check-herdr-activation.ts +73 -0
  66. package/scripts/check-herdr-fresh-call.ts +30 -6
  67. package/scripts/check-herdr-placement.ts +51 -0
  68. package/scripts/check-herdr-plugin-build.ts +11 -4
  69. package/scripts/check-herdr-plugin.ts +745 -38
  70. package/scripts/check-herdr-sandbox.ts +14 -2
  71. package/scripts/check-install-container.sh +1 -1
  72. package/scripts/check-mux-launcher-fence.ts +37 -0
  73. package/scripts/check-pi-launch.ts +8 -2
  74. package/scripts/check-release-gate-outcomes.ts +165 -0
  75. package/scripts/doctor-pi-provider.ts +44 -4
  76. package/scripts/herdr-rails.mjs +75 -0
  77. package/scripts/lib/mutation-qualify.ts +1 -1
  78. package/scripts/meta-bridge-state.py +18 -1
  79. package/scripts/mutants/acp-backend-preflight.json +20 -0
  80. package/scripts/mutants/bridge-boot-resume.json +26 -0
  81. package/scripts/mutants/bridge-command-boot.json +38 -0
  82. package/scripts/mutants/control-send-receipt.json +235 -0
  83. package/scripts/mutants/herdr-activation.json +16 -0
  84. package/scripts/mutants/herdr-fresh-call.json +15 -4
  85. package/scripts/mutants/herdr-plugin-build.json +7 -11
  86. package/scripts/mutants/herdr-plugin.json +177 -9
  87. package/scripts/mutants/meta-retire.json +22 -0
  88. package/scripts/mutants/mux-fresh-call.json +21 -8
  89. package/scripts/mutants/omp-fresh.json +5 -9
  90. package/scripts/mutants/pack-install.json +4 -4
  91. package/scripts/mutants/pi-floor.json +17 -0
  92. package/scripts/mutants/release-gate.json +48 -0
  93. package/scripts/mutants/retired-sent-surface.json +32 -0
  94. package/scripts/mutants/v2-surface.json +7 -7
  95. package/scripts/probe-bridge-command.ts +1 -0
  96. package/scripts/smoke-acp-session-reuse-live.ts +23 -5
  97. package/scripts/smoke-agy-install-state.sh +2 -2
  98. package/scripts/smoke-codex-fresh-live.ts +94 -13
  99. package/scripts/smoke-copilot-mcp-state.sh +1 -1
  100. package/scripts/smoke-herdr-fresh-call-live.ts +71 -36
  101. package/scripts/smoke-herdr-raw-install-live.sh +90 -5
  102. package/scripts/smoke-meta-install-state.sh +107 -1
  103. package/scripts/smoke-mux-lifecycle-live.ts +9 -2
  104. package/scripts/smoke-omp-fresh-live.ts +4 -2
  105. package/scripts/smoke-omp-mcp-state.sh +1 -1
  106. package/scripts/smoke-pi-provider-state.sh +108 -2
  107. package/scripts/smoke-setup-verdict.sh +18 -2
@@ -0,0 +1,235 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "lane": "control-send-receipt",
4
+ "mutants": [
5
+ {
6
+ "claim": "SEND-RECEIPT-IDLE-IS-SENT",
7
+ "title": "an idle receiver's DIRECT trigger is reported as a queue it never touched, so the one boundary that actually started a turn becomes indistinguishable from the two that did not",
8
+ "subject": "pi-extensions/lib/control-send-receipt.ts",
9
+ "find": ["\tif (input.idle) return \"sent\";"],
10
+ "replace": ["\tif (false) return \"sent\";"],
11
+ "gate": ["bash", "run.sh", "check-control-send-receipt"],
12
+ "timeoutSeconds": 600,
13
+ "signature": "[QK:SEND-RECEIPT-IDLE-IS-SENT]",
14
+ "signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
15
+ },
16
+ {
17
+ "claim": "SEND-RECEIPT-BUSY-STEER-IS-QUEUED",
18
+ "title": "a busy receiver's steering queue is reported as `sent`, which is the exact false claim #120 was opened about: the sender is told the message landed while it lies in volatile process memory behind whatever else is there",
19
+ "subject": "pi-extensions/lib/control-send-receipt.ts",
20
+ "find": ["\treturn input.mode === \"follow_up\" ? \"queued-follow-up\" : \"queued-steer\";"],
21
+ "replace": ["\treturn input.mode === \"follow_up\" ? \"queued-follow-up\" : \"sent\";"],
22
+ "gate": ["bash", "run.sh", "check-control-send-receipt"],
23
+ "timeoutSeconds": 600,
24
+ "signature": "[QK:SEND-RECEIPT-BUSY-STEER-IS-QUEUED]",
25
+ "signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
26
+ },
27
+ {
28
+ "claim": "SEND-RECEIPT-BUSY-FOLLOWUP-IS-QUEUED",
29
+ "title": "the follow-up queue is reported under the steering queue's name, collapsing the only fact that explains a reorder after it happens — a later steer overtakes every earlier follow_up, and one name for both makes that unaccountable",
30
+ "subject": "pi-extensions/lib/control-send-receipt.ts",
31
+ "find": ["? \"queued-follow-up\" : \"queued-steer\";"],
32
+ "replace": ["? \"queued-steer\" : \"queued-steer\";"],
33
+ "gate": ["bash", "run.sh", "check-control-send-receipt"],
34
+ "timeoutSeconds": 600,
35
+ "signature": "[QK:SEND-RECEIPT-BUSY-FOLLOWUP-IS-QUEUED]",
36
+ "signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
37
+ },
38
+ {
39
+ "claim": "SEND-RECEIPT-UNKNOWN-IS-ACCEPTED-NOT-SENT",
40
+ "title": "an answer this build cannot classify is reported as `sent`, so a version-skewed peer's acceptance is dressed as a direct injection nobody observed",
41
+ "subject": "pi-extensions/lib/control-send-receipt.ts",
42
+ "find": ["\treturn isObservedBoundary(value) ? value : \"accepted-unknown-boundary\";"],
43
+ "replace": ["\treturn isObservedBoundary(value) ? value : \"sent\";"],
44
+ "gate": ["bash", "run.sh", "check-control-send-receipt"],
45
+ "timeoutSeconds": 600,
46
+ "signature": "[QK:SEND-RECEIPT-UNKNOWN-IS-ACCEPTED-NOT-SENT]",
47
+ "signatureSource": "pi-extensions/lib/control-send-receipt.test.ts"
48
+ },
49
+ {
50
+ "claim": "SEND-BOUNDARY-CARRIED",
51
+ "title": "the primary leg reports a fixed `sent` instead of the boundary the receiver actually named, so every busy acceptance reads as a direct trigger again",
52
+ "subject": "pi-extensions/lib/entwurf-v2-send.ts",
53
+ "find": [
54
+ "\treturn result.success ? { outcome: \"sent\", boundary: requireBoundary(result) } : inBandRejected(result);"
55
+ ],
56
+ "replace": ["\treturn result.success ? { outcome: \"sent\", boundary: \"sent\" } : inBandRejected(result);"],
57
+ "gate": ["bash", "run.sh", "check-entwurf-v2-send"],
58
+ "timeoutSeconds": 600,
59
+ "signature": "[QK:SEND-BOUNDARY-CARRIED]",
60
+ "signatureSource": "pi-extensions/lib/entwurf-v2-send.test.ts"
61
+ },
62
+ {
63
+ "claim": "SEND-FALLBACK-KEEPS-BOUNDARY",
64
+ "title": "a re-resolved socket drops the boundary it was handed, so a first socket that died and a second that was BUSY come out reading as a delivery — the route axis erasing the receipt axis",
65
+ "subject": "pi-extensions/lib/entwurf-v2-send.ts",
66
+ "find": [
67
+ "\t\t\t\treturn r.success ? { outcome: \"fallback-sent\", boundary: requireBoundary(r) } : inBandRejected(r);"
68
+ ],
69
+ "replace": ["\t\t\t\treturn r.success ? { outcome: \"fallback-sent\", boundary: \"sent\" } : inBandRejected(r);"],
70
+ "gate": ["bash", "run.sh", "check-entwurf-v2-send"],
71
+ "timeoutSeconds": 600,
72
+ "signature": "[QK:SEND-FALLBACK-KEEPS-BOUNDARY]",
73
+ "signatureSource": "pi-extensions/lib/entwurf-v2-send.test.ts"
74
+ },
75
+ {
76
+ "claim": "SEND-SOCKET-SUCCESS-NEEDS-BOUNDARY",
77
+ "title": "a successful socket answer with no boundary is accepted silently, so a bypassed wire seam — the one shape that must never pass for a direct trigger — reads exactly like one",
78
+ "subject": "pi-extensions/lib/entwurf-v2-send.ts",
79
+ "find": ["\tif (result.boundary === undefined) {"],
80
+ "replace": ["\tif (false) {"],
81
+ "gate": ["bash", "run.sh", "check-entwurf-v2-send"],
82
+ "timeoutSeconds": 600,
83
+ "signature": "[QK:SEND-SOCKET-SUCCESS-NEEDS-BOUNDARY]",
84
+ "signatureSource": "pi-extensions/lib/entwurf-v2-send.test.ts"
85
+ },
86
+ {
87
+ "claim": "SEND-RECEIVER-EMITS-BOUNDARY",
88
+ "title": "the receiver goes back to answering with a bare `delivered:true`, which was equally true of a direct trigger and of a message rotting in a queue — the bare `delivered` DELIVERY.md refuses by name, and the sender is left with nothing to render",
89
+ "subject": "pi-extensions/entwurf-control.ts",
90
+ "find": ["\t\t\tboundary: sendReceiptBoundary({ idle: isIdle, mode }),"],
91
+ "replace": ["\t\t\tdelivered: true,"],
92
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
93
+ "timeoutSeconds": 300,
94
+ "signature": "[QK:SEND-RECEIVER-EMITS-BOUNDARY]",
95
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
96
+ },
97
+ {
98
+ "claim": "SEND-SURFACE-RENDERS-BOUNDARY",
99
+ "title": "the sender surface renders the internal route word again instead of the receiver's boundary, putting `control-socket → sent` back on a message that is sitting in a queue",
100
+ "subject": "pi-extensions/lib/entwurf-v2-surface.ts",
101
+ "find": [
102
+ "\t\t\t\t\treturn { text: `entwurf_v2 control-socket → ${boundary}${route}${enqueued}`, isError: false };"
103
+ ],
104
+ "replace": [
105
+ "\t\t\t\t\treturn { text: `entwurf_v2 control-socket → ${o.outcome}${route}${enqueued}`, isError: false };"
106
+ ],
107
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
108
+ "timeoutSeconds": 300,
109
+ "signature": "[QK:SEND-SURFACE-RENDERS-BOUNDARY]",
110
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
111
+ },
112
+ {
113
+ "claim": "SEND-SURFACE-UNKNOWN-NOT-SENT",
114
+ "title": "an unclassifiable acceptance is rendered with the word `sent`, which is the claim the whole axis exists to stop making — it was accepted, and nobody observed a direct injection",
115
+ "subject": "pi-extensions/lib/entwurf-v2-surface.ts",
116
+ "find": [
117
+ "\t\t\t\t\t\to.boundary ?? (o.outcome === \"fallback-sent\" ? \"mailbox-enqueued\" : \"accepted-unknown-boundary\");"
118
+ ],
119
+ "replace": [
120
+ "\t\t\t\t\t\to.boundary === \"accepted-unknown-boundary\" ? \"sent\" : (o.boundary ?? \"mailbox-enqueued\");"
121
+ ],
122
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
123
+ "timeoutSeconds": 300,
124
+ "signature": "[QK:SEND-SURFACE-UNKNOWN-NOT-SENT]",
125
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
126
+ },
127
+ {
128
+ "claim": "SEND-SURFACE-FALLBACK-KEEPS-BOUNDARY",
129
+ "title": "the re-resolved route annotation is dropped, so a caller cannot tell that its first socket was dead — the two legs render identically and a dead-socket host looks healthy",
130
+ "subject": "pi-extensions/lib/entwurf-v2-surface.ts",
131
+ "find": ["\t\t\t\t\tconst route = o.outcome === \"fallback-sent\" ? \" (via a re-resolved route)\" : \"\";"],
132
+ "replace": ["\t\t\t\t\tconst route = \"\";"],
133
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
134
+ "timeoutSeconds": 300,
135
+ "signature": "[QK:SEND-SURFACE-FALLBACK-KEEPS-BOUNDARY]",
136
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
137
+ },
138
+ {
139
+ "claim": "SEND-PROSE-NO-INTERRUPT",
140
+ "title": "the caller-facing description of `mode` goes back to promising that steer interrupts the current turn — a caller picks it for urgency and gets a queue drained only after the turn ends, with no order against the other queue",
141
+ "subject": "pi-extensions/lib/entwurf-v2-contract-schema.ts",
142
+ "find": ["\t\t\t\t\"delivery mode — NOT the ownership axis (F1) nor liveness routing."],
143
+ "replace": [
144
+ "\t\t\t\t\"delivery mode (steer = interrupt current turn, follow_up = queue) — NOT the ownership axis (F1) nor liveness routing."
145
+ ],
146
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
147
+ "timeoutSeconds": 300,
148
+ "signature": "[QK:SEND-PROSE-NO-INTERRUPT]",
149
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
150
+ },
151
+ {
152
+ "claim": "SEND-DIRTY-LOCK-NAMES-ACCEPTANCE",
153
+ "title": "the dirty-lock line goes back to `DELIVERED (<route>)` for all three shapes that reach it — a refusal that delivered nothing, a message lying in a volatile queue, and a durable mailbox file all read as one word, at the exact moment an operator is deciding BY HAND whether anything still needs sending",
154
+ "subject": "pi-extensions/lib/entwurf-v2-surface.ts",
155
+ "find": [
156
+ "\t\t\t\t\t\t? `rejected${result.finalizedRejectReason ? ` (${result.finalizedRejectReason})` : \"\"} — the receiver refused it; nothing was accepted`"
157
+ ],
158
+ "replace": ["\t\t\t\t\t\t? `DELIVERED (${result.finalizedOutcome})`"],
159
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
160
+ "timeoutSeconds": 300,
161
+ "signature": "[QK:SEND-DIRTY-LOCK-NAMES-ACCEPTANCE]",
162
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
163
+ },
164
+ {
165
+ "claim": "VITEST-TEST-DIR-ON-THE-FLOOR",
166
+ "title": "the pi queue oracle's public coordinate is dropped from `check:vitest`, so the file that proves every claim the receipt makes about a receiver's queues is green only when somebody runs `pnpm test` by hand — the discovery door deliberately does not select `test/**`, so nothing else would notice",
167
+ "subject": "package.json",
168
+ "find": [
169
+ "\"check:vitest\": \"./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-pi-queue-oracle && ./run.sh check-tests-beside-behavior\""
170
+ ],
171
+ "replace": [
172
+ "\"check:vitest\": \"./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-tests-beside-behavior\""
173
+ ],
174
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
175
+ "timeoutSeconds": 600,
176
+ "signature": "[QK:VITEST-TEST-DIR-ON-THE-FLOOR]",
177
+ "signatureSource": "run.sh"
178
+ },
179
+ {
180
+ "claim": "PI-CORE-PIN-TRACKS-FLOOR",
181
+ "title": "the queue oracle's pi-agent-core pin drifts off the floor the rest of the pi runtime is pinned to, so the oracle keeps answering honestly — about a pi nobody in this repo runs",
182
+ "subject": "package.json",
183
+ "find": ["\"@earendil-works/pi-agent-core\": \"0.87.1\","],
184
+ "replace": ["\"@earendil-works/pi-agent-core\": \"0.86.0\","],
185
+ "gate": ["bash", "run.sh", "check-dep-versions"],
186
+ "timeoutSeconds": 300,
187
+ "signature": "[QK:PI-CORE-PIN-TRACKS-FLOOR]",
188
+ "signatureSource": "run.sh"
189
+ },
190
+ {
191
+ "claim": "SEND-DIRTY-LOCK-ERROR-CARRIES-ACCEPTANCE",
192
+ "title": "the structured dirty-lock error stops carrying the refusal's reason, so a receiver that said WHY it refused loses that word at the one moment an operator is deciding by hand whether the message still needs sending — the render cell cannot see this, because it builds its own result object",
193
+ "subject": "pi-extensions/lib/entwurf-v2-send.ts",
194
+ "find": ["\t\t\t\trejectReason: drive.rejectReason,"],
195
+ "replace": ["\t\t\t\trejectReason: undefined,"],
196
+ "gate": ["bash", "run.sh", "check-entwurf-v2-send"],
197
+ "timeoutSeconds": 600,
198
+ "signature": "[QK:SEND-DIRTY-LOCK-ERROR-CARRIES-ACCEPTANCE]",
199
+ "signatureSource": "pi-extensions/lib/entwurf-v2-send.test.ts"
200
+ },
201
+ {
202
+ "claim": "SEND-DIRTY-LOCK-RUNNER-MOVES-ACCEPTANCE",
203
+ "title": "the runner drops the acceptance fields on the way from the thrown error to the result, so the hand proves it fills them and the surface proves it renders them while the operator still sees nothing — the classic middle-seam hole two端 tests cannot cover",
204
+ "subject": "pi-extensions/lib/entwurf-v2-runner.ts",
205
+ "find": ["\t\t\t\t\t\tfinalizedRejectReason: err.finalizedRejectReason,"],
206
+ "replace": ["\t\t\t\t\t\tfinalizedRejectReason: undefined,"],
207
+ "gate": ["bash", "run.sh", "check-entwurf-v2-runner"],
208
+ "timeoutSeconds": 600,
209
+ "signature": "[QK:SEND-DIRTY-LOCK-RUNNER-MOVES-ACCEPTANCE]",
210
+ "signatureSource": "pi-extensions/lib/entwurf-v2-runner.test.ts"
211
+ },
212
+ {
213
+ "claim": "VITEST-TEST-DIR-HAS-COORDINATE",
214
+ "title": "the only line that EXECUTES the pi queue oracle is deleted while its verb and its explanatory comment stay, so the file is run by nothing at all — and a checker that accepted a mention instead of a call would keep reporting the floor as complete",
215
+ "subject": "run.sh",
216
+ "find": [" run_vitest test/pi-queue.oracle.test.ts"],
217
+ "replace": [" : # the oracle is no longer executed here"],
218
+ "gate": ["bash", "run.sh", "check-tests-beside-behavior"],
219
+ "timeoutSeconds": 600,
220
+ "signature": "[QK:VITEST-TEST-DIR-HAS-COORDINATE]",
221
+ "signatureSource": "run.sh"
222
+ },
223
+ {
224
+ "claim": "SEND-OUTCOME-LIST-NAMES-EVERY-RAIL",
225
+ "title": "the caller-facing outcome list drops the native-push rail, so a caller reading the one blurb it reads before dispatching is told the control rail's vocabulary covers a rail that answers with a direct injection instead",
226
+ "subject": "mcp/entwurf-bridge/src/index.ts",
227
+ "find": ["\t\t\"native-push INJECTION, a rejection, or lock-dirty. EXISTING targets only; discover with \" +"],
228
+ "replace": ["\t\t\"a rejection, or lock-dirty. EXISTING targets only; discover with \" +"],
229
+ "gate": ["bash", "run.sh", "check-entwurf-v2-surface"],
230
+ "timeoutSeconds": 300,
231
+ "signature": "[QK:SEND-OUTCOME-LIST-NAMES-EVERY-RAIL]",
232
+ "signatureSource": "scripts/check-entwurf-v2-surface.ts"
233
+ }
234
+ ]
235
+ }
@@ -13,6 +13,22 @@
13
13
  "signature": "[QK:HAC-PI-USER-SCOPE-ONLY]",
14
14
  "signatureSource": "scripts/check-herdr-activation.ts"
15
15
  },
16
+ {
17
+ "claim": "HAC-PI-FLOOR-BOTH-DOORS",
18
+ "title": "dropping the pi range check from install-user-scope re-opens the door asymmetry: setup refuses a below-floor pi by name while the herdr activation door writes the same registration in silence, so one host reports two verdicts for one citizen",
19
+ "subject": "run.sh",
20
+ "find": [
21
+ " if ! pi_version_in_range \"${pi_ver:-0}\" \"$pi_range\"; then",
22
+ " echo \"[install-user-scope] pi: FAIL — detected pi ${pi_ver:-<unreadable version>} is outside the supported range $pi_range; nothing was written. Align pi, then re-run.\" >&2",
23
+ " exit 1",
24
+ " fi"
25
+ ],
26
+ "replace": [" : \"$pi_range\""],
27
+ "gate": ["bash", "run.sh", "check-herdr-activation"],
28
+ "timeoutSeconds": 300,
29
+ "signature": "[QK:HAC-PI-FLOOR-BOTH-DOORS]",
30
+ "signatureSource": "scripts/check-herdr-activation.ts"
31
+ },
16
32
  {
17
33
  "claim": "HAC-COMMAND-IS-DERIVED",
18
34
  "title": "accepting any absolute directory as 'the plugin runtime' is a way to point every pi session at an executable of the caller's choosing — 'absolute' was never the contract, 'this host's stable runtime' was",
@@ -15,10 +15,10 @@
15
15
  },
16
16
  {
17
17
  "claim": "HFC-PILOT-CLOSED",
18
- "title": "a backend nobody measured on herdr is admitted to the pilot, so a caller gets a pane running something this rail never proved it can open",
19
- "subject": "pi-extensions/lib/herdr-fresh-call.ts",
20
- "find": ["export const HERDR_FRESH_CALL_BACKENDS = [\"pi\", \"claude-code\"] as const;"],
21
- "replace": ["export const HERDR_FRESH_CALL_BACKENDS = [\"pi\", \"claude-code\", \"codex\"] as const;"],
18
+ "title": "a backend nobody measured on herdr is admitted to the pilot, so a caller gets a pane running something this rail never proved it can open (#116 A7: the tuple moved to the shared rails leaf, so the mutant follows its subject — widening the pilot set is still the mutation, it is simply written in one place now)",
19
+ "subject": "scripts/herdr-rails.mjs",
20
+ "find": ["export const HERDR_FRESH_CALL_BACKENDS = Object.freeze([\"pi\", \"claude-code\"]);"],
21
+ "replace": ["export const HERDR_FRESH_CALL_BACKENDS = Object.freeze([\"pi\", \"claude-code\", \"codex\"]);"],
22
22
  "gate": ["bash", "run.sh", "check-herdr-fresh-call"],
23
23
  "timeoutSeconds": 120,
24
24
  "signature": "[QK:HFC-PILOT-CLOSED]",
@@ -443,6 +443,17 @@
443
443
  "timeoutSeconds": 120,
444
444
  "signature": "[QK:HFC-WITNESS-BINDING-COMPLETE]",
445
445
  "signatureSource": "scripts/check-herdr-fresh-call.ts"
446
+ },
447
+ {
448
+ "claim": "HFC-CALLBACK-ENV",
449
+ "title": "the launcher-computed callback pair is dropped from herdr --env, so a herdr sibling's first action has to retype a garden id out of prose",
450
+ "subject": "pi-extensions/lib/herdr-fresh-call.ts",
451
+ "find": ["\t\t...callbackEnvAssignments(params.callback).flatMap((assignment) => [\"--env\", assignment]),"],
452
+ "replace": [""],
453
+ "gate": ["bash", "run.sh", "check-herdr-fresh-call"],
454
+ "timeoutSeconds": 120,
455
+ "signature": "[QK:HFC-CALLBACK-ENV]",
456
+ "signatureSource": "scripts/check-herdr-fresh-call.ts"
446
457
  }
447
458
  ]
448
459
  }
@@ -132,14 +132,10 @@
132
132
  },
133
133
  {
134
134
  "claim": "HPB-USAGE-NOTE-NAMES-A-MODEL",
135
- "title": "the install names a model id in the wrong harness's grammar, so the first fresh call an operator copies is refused",
136
- "subject": "plugins/herdr/lib/build.mjs",
137
- "find": [
138
- "\t\tnotes.push(\"claude-code: a model id looks like `claude-sonnet-5` — the vendor id, not a provider path.\");"
139
- ],
140
- "replace": [
141
- "\t\tnotes.push(\"claude-code: a model id looks like `anthropic/claude-sonnet-5` — provider-qualified.\");"
142
- ],
135
+ "title": "the install names a model id in the wrong harness's grammar, so the first fresh call an operator copies is refused (#116 A7: the example moved to the shared rails leaf; the mutation still gives claude-code a provider-qualified id, which is the grammar confusion this claim exists to catch)",
136
+ "subject": "scripts/herdr-rails.mjs",
137
+ "find": ["\t\"claude-code\": \"claude-sonnet-5\","],
138
+ "replace": ["\t\"claude-code\": \"anthropic/claude-sonnet-5\","],
143
139
  "gate": ["bash", "run.sh", "check-herdr-plugin-build"],
144
140
  "timeoutSeconds": 180,
145
141
  "signature": "[QK:HPB-USAGE-NOTE-NAMES-A-MODEL]",
@@ -147,10 +143,10 @@
147
143
  },
148
144
  {
149
145
  "claim": "HPB-INSTALL-USAGE-NOTE",
150
- "title": "dropping the pi line leaves the one backend whose wiring is invisible from the operator's chair unexplained: claude-code picks the tools up through MCP with nothing added, while a plain pi loads the extension on every session of the host and is still not a citizen — a green install followed by a silent, tool-less pi is indistinguishable from an install that did nothing",
146
+ "title": "dropping the pi line leaves the one backend whose wiring is invisible from the operator's chair unexplained: claude-code picks the tools up through MCP with nothing added, while a plain pi loads the extension on every session of the host and is still not a citizen — a green install followed by a silent, tool-less pi is indistinguishable from an install that did nothing (#116 A7: usageNotes now loops the shared backend tuple instead of a literal pair, so the mutation suppresses pi's notes at the loop guard rather than at a per-backend `if`)",
151
147
  "subject": "plugins/herdr/lib/build.mjs",
152
- "find": ["\tif (activated.includes(\"pi\")) {"],
153
- "replace": ["\tif (false && activated.includes(\"pi\")) {"],
148
+ "find": ["\t\tif (!activated.includes(backend)) continue;"],
149
+ "replace": ["\t\tif (backend === \"pi\" || !activated.includes(backend)) continue;"],
154
150
  "gate": ["bash", "run.sh", "check-herdr-plugin-build"],
155
151
  "timeoutSeconds": 300,
156
152
  "signature": "[QK:HPB-INSTALL-USAGE-NOTE]",
@@ -6,9 +6,9 @@
6
6
  "claim": "HPL-ONE-OPEN-ONE-READ",
7
7
  "title": "re-reading either listing turns one answered question into a poll — peer-facts observes every citizen unbounded (measured 4.1s on a 1,150-record store) and herdr publishes no 'the session reference landed' event, so a second read is both the slow path and the discovery watcher docs/mux-launch-rail.md §7 refuses by name (#116 M2-b)",
8
8
  "subject": "plugins/herdr/lib/status.mjs",
9
- "find": ["\t\t\tconst agents = readJson(herdrBin, [\"agent\", \"list\"], {"],
9
+ "find": ["\tconst agents = readJson(herdrBin, [\"agent\", \"list\"], {"],
10
10
  "replace": [
11
- "\t\t\treadJson(herdrBin, [\"agent\", \"list\"], { failed: \"x\", unparsable: \"y\" });\n\t\t\tconst agents = readJson(herdrBin, [\"agent\", \"list\"], {"
11
+ "\treadJson(herdrBin, [\"agent\", \"list\"], { failed: \"x\", unparsable: \"y\" });\n\tconst agents = readJson(herdrBin, [\"agent\", \"list\"], {"
12
12
  ],
13
13
  "gate": ["bash", "run.sh", "check-herdr-plugin"],
14
14
  "timeoutSeconds": 180,
@@ -19,8 +19,8 @@
19
19
  "claim": "HPL-SKIP-NOT-FAILURE",
20
20
  "title": "turning a missing Entwurf into a red makes every host that simply has not installed it look broken, and invites the plugin to 'fix' it — installing Entwurf is not a plugin's business (AGENTS.md Hard Rule 17, #116 M2-b)",
21
21
  "subject": "plugins/herdr/lib/status.mjs",
22
- "find": ["\tfinish([\"entwurf-not-found\"], OK);"],
23
- "replace": ["\tfinish([\"entwurf-not-found\"], RED);"],
22
+ "find": ["\t\t\t\t\tcode: \"entwurf-not-found\","],
23
+ "replace": ["\t\t\t\t\tcode: \"quietly-nothing\","],
24
24
  "gate": ["bash", "run.sh", "check-herdr-plugin"],
25
25
  "timeoutSeconds": 180,
26
26
  "signature": "[QK:HPL-SKIP-NOT-FAILURE]",
@@ -28,12 +28,12 @@
28
28
  },
29
29
  {
30
30
  "claim": "HPL-FAILED-READ-IS-RED",
31
- "title": "treating a nonzero listing exit as success renders an empty table for a listing that was never read — a host whose store could not be opened becomes indistinguishable from a host with no citizens (#116 M2-b)",
31
+ "title": "treating a nonzero listing exit as success renders an empty table for a listing that was never read — a host whose store could not be opened becomes indistinguishable from a host with no citizens (#116 M2-b) (#116 P1: the non-zero check moved into the single `spawnOnce` call site, so the mutation follows its subject — both listings now lose their exit check at once, which is the same defect stated in one place)",
32
32
  "subject": "plugins/herdr/lib/status.mjs",
33
33
  "find": [
34
- "\tif (run.status !== 0) return { error: names.failed, detail: `exit ${run.status}: ${(run.stderr ?? \"\").trim()}` };"
34
+ "\tif (run.status !== 0) return { error: failedCode, detail: `exit ${run.status}: ${(run.stderr ?? \"\").trim()}` };"
35
35
  ],
36
- "replace": ["\tif (false) return { error: names.failed, detail: `exit ${run.status}` };"],
36
+ "replace": ["\tif (false) return { error: failedCode, detail: `exit ${run.status}` };"],
37
37
  "gate": ["bash", "run.sh", "check-herdr-plugin"],
38
38
  "timeoutSeconds": 180,
39
39
  "signature": "[QK:HPL-FAILED-READ-IS-RED]",
@@ -65,8 +65,12 @@
65
65
  "claim": "HPL-DIAGNOSTICS-SHOWN",
66
66
  "title": "dropping the provider's diagnostics shows a store carrying hazards as a clean listing — the one lie a status pane can tell while looking green (#116 M2-b)",
67
67
  "subject": "plugins/herdr/lib/status.mjs",
68
- "find": ["\t\t\t\t\t\t...renderDiagnostics(diagnostics),"],
69
- "replace": ["\t\t\t\t\t\t...renderDiagnostics([]),"],
68
+ "find": [
69
+ "\t\tlines: [...renderTable(peers, indexActivityByPane(agentRows)), \"\", ...renderDiagnostics(diagnostics)],"
70
+ ],
71
+ "replace": [
72
+ "\t\tlines: [...renderTable(peers, indexActivityByPane(agentRows)), \"\", ...renderDiagnostics([])],"
73
+ ],
70
74
  "gate": ["bash", "run.sh", "check-herdr-plugin"],
71
75
  "timeoutSeconds": 180,
72
76
  "signature": "[QK:HPL-DIAGNOSTICS-SHOWN]",
@@ -128,6 +132,170 @@
128
132
  "timeoutSeconds": 180,
129
133
  "signature": "[QK:HPL-DIAGNOSTIC-SUBJECTS]",
130
134
  "signatureSource": "scripts/check-herdr-plugin.ts"
135
+ },
136
+ {
137
+ "claim": "HPL-BLOCK-PROVENANCE",
138
+ "title": "the activation block stops saying it is an install-time receipt and claims it was read now — the one sentence that keeps an add-only ledger from being mistaken for a live probe, and the moment it goes the four blocks collapse into one implied 'as of now'",
139
+ "subject": "plugins/herdr/lib/capability-report.mjs",
140
+ "find": ["\tactivation: \"install-time\","],
141
+ "replace": ["\tactivation: \"now\","],
142
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
143
+ "timeoutSeconds": 180,
144
+ "signature": "[QK:HPL-BLOCK-PROVENANCE]",
145
+ "signatureSource": "scripts/check-herdr-plugin.ts"
146
+ },
147
+ {
148
+ "claim": "HPL-NO-AGGREGATE-VERDICT",
149
+ "title": "a summary line is added over the four blocks, which is exactly the merged green this surface exists to refuse: one word has to pick one observation time and be wrong about the other two",
150
+ "subject": "plugins/herdr/lib/capability-report.mjs",
151
+ "find": ["\tconst out = [];"],
152
+ "replace": ["\tconst out = [\"Overall: all ready.\"];"],
153
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
154
+ "timeoutSeconds": 180,
155
+ "signature": "[QK:HPL-NO-AGGREGATE-VERDICT]",
156
+ "signatureSource": "scripts/check-herdr-plugin.ts"
157
+ },
158
+ {
159
+ "claim": "HPL-RAILS-SHARED-SOURCE",
160
+ "title": "the RAILS block stops reading the shared declaration leaf and renders a hardcoded model string, re-opening the third-copy drift that leaf was created to close",
161
+ "subject": "plugins/herdr/lib/capability-report.mjs",
162
+ "find": [
163
+ "\t\t\t` ${backend}: ${railEntryNote[backend]}\\n model string syntax, one example only: \\`${modelSyntaxExample[backend]}\\``,"
164
+ ],
165
+ "replace": [
166
+ "\t\t\t` ${backend}: ${railEntryNote[backend]}\\n model string syntax, one example only: \\`some-provider/some-model\\``,"
167
+ ],
168
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
169
+ "timeoutSeconds": 180,
170
+ "signature": "[QK:HPL-RAILS-SHARED-SOURCE]",
171
+ "signatureSource": "scripts/check-herdr-plugin.ts"
172
+ },
173
+ {
174
+ "claim": "HPL-LEDGER-FALLBACK-READS-CITIZENS",
175
+ "title": "the D3=C fallback is removed, so a correct plugin install — which puts nothing on PATH — closes its own first screen with entwurf-not-found again, and the operator is back to setting ENTWURF_BIN by hand",
176
+ "subject": "plugins/herdr/lib/status.mjs",
177
+ "find": ["\tif (evidence.kind === \"ledger\" && evidence.runtimeBin !== null) {"],
178
+ "replace": ["\tif (false) {"],
179
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
180
+ "timeoutSeconds": 180,
181
+ "signature": "[QK:HPL-LEDGER-FALLBACK-READS-CITIZENS]",
182
+ "signatureSource": "scripts/check-herdr-plugin.ts"
183
+ },
184
+ {
185
+ "claim": "HPL-OVERRIDE-BEATS-LEDGER",
186
+ "title": "the ledger is consulted BEFORE the operator's own ENTWURF_BIN and PATH, so a receipt silently out-votes the person at the keyboard — the failure mode a fallback is most likely to grow",
187
+ "subject": "plugins/herdr/lib/status.mjs",
188
+ "find": ["\tconst declared = process.env.ENTWURF_BIN;\n\tif (declared !== undefined && declared !== \"\") {"],
189
+ "replace": [
190
+ "\tconst declared = process.env.ENTWURF_BIN;\n\tif (evidence.kind !== \"ledger\" && declared !== undefined && declared !== \"\") {"
191
+ ],
192
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
193
+ "timeoutSeconds": 180,
194
+ "signature": "[QK:HPL-OVERRIDE-BEATS-LEDGER]",
195
+ "signatureSource": "scripts/check-herdr-plugin.ts"
196
+ },
197
+ {
198
+ "claim": "HPL-ACTIVATION-NAMED-REDS",
199
+ "title": "every broken activation state collapses into one generic code, so `we cannot import the reader`, `the body is not certifiable`, `this receipt is about another root` and `the promised binary is gone` become indistinguishable — four different repairs behind one word",
200
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
201
+ "find": ["\t\t\tcode: \"activation-runtime-root-mismatch\","],
202
+ "replace": ["\t\t\tcode: \"activation-reader-unavailable\","],
203
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
204
+ "timeoutSeconds": 180,
205
+ "signature": "[QK:HPL-ACTIVATION-NAMED-REDS]",
206
+ "signatureSource": "scripts/check-herdr-plugin.ts"
207
+ },
208
+ {
209
+ "claim": "HPL-LEDGER-AT-WRITER-PATH",
210
+ "title": "the ledger is addressed at the RUNTIME's data root again instead of the writer's XDG state root, so on every correctly activated host the pane finds no ledger where one certainly exists — and because the writer's reader answers a missing file with `null`, the original of this mutation did not merely lose the D3=C fallback, it killed the pane before a single block was drawn",
211
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
212
+ "find": ["\t\tledgerPath: activation.ledgerPath,"],
213
+ "replace": ["\t\tledgerPath: path.join(layout.pluginRoot, \"activation.json\"),"],
214
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
215
+ "timeoutSeconds": 180,
216
+ "signature": "[QK:HPL-LEDGER-AT-WRITER-PATH]",
217
+ "signatureSource": "scripts/check-herdr-plugin.ts"
218
+ },
219
+ {
220
+ "claim": "HPL-LEDGER-MISSING-IS-NAMED",
221
+ "title": "a missing ledger is only noticed AFTER the installed reader has been located, so a host whose single real fact is that nothing ever wrote a receipt is told its runtime is broken instead — two different repairs behind one name, and the ledger's address needed no installed artifact to resolve in the first place",
222
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
223
+ "find": ["\tif (!ledgerPresent) {"],
224
+ "replace": ["\tif (false) {"],
225
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
226
+ "timeoutSeconds": 180,
227
+ "signature": "[QK:HPL-LEDGER-MISSING-IS-NAMED]",
228
+ "signatureSource": "scripts/check-herdr-plugin.ts"
229
+ },
230
+ {
231
+ "claim": "HPL-ENV-ROOT-IS-NAMED",
232
+ "title": "the layout resolvers are called outside any guard, so a host with neither HOME nor an XDG root takes the pane down on an unhandled rejection instead of being told, in the activation block, that we cannot even say where its ledger would live — the other three blocks never needed that root",
233
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
234
+ "find": [
235
+ "\tlet roots;\n\ttry {\n\t\troots = deriveRoots(env, { runtimeModule, activationModule });\n\t} catch (err) {"
236
+ ],
237
+ "replace": [
238
+ "\tlet roots;\n\troots = deriveRoots(env, { runtimeModule, activationModule });\n\ttry {\n\t\tif (roots === undefined) throw new Error(\"unreachable\");\n\t} catch (err) {"
239
+ ],
240
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
241
+ "timeoutSeconds": 180,
242
+ "signature": "[QK:HPL-ENV-ROOT-IS-NAMED]",
243
+ "signatureSource": "scripts/check-herdr-plugin.ts"
244
+ },
245
+ {
246
+ "claim": "HPL-PHASE-GATES-FALLBACK",
247
+ "title": "any certified ledger grants the runtime fallback, including one written mid-teardown, so an add-only install-time receipt is spent as if it were a live probe — `deactivating` says what was wired, not what is standing there now, and merging those two is how this pane would start answering a runtime question with an install-time answer",
248
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
249
+ "find": ["\tif (ledger.phase !== \"active\") {"],
250
+ "replace": ["\tif (false) {"],
251
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
252
+ "timeoutSeconds": 180,
253
+ "signature": "[QK:HPL-PHASE-GATES-FALLBACK]",
254
+ "signatureSource": "scripts/check-herdr-plugin.ts"
255
+ },
256
+ {
257
+ "claim": "HPL-INTEGRATION-NONCURRENT-IS-RED",
258
+ "title": "a selected atom herdr reports as outdated or needs-repair leaves block [1] a neutral `reported` and the pane at exit 0, so a surface that has ALREADY classified those two into `profile.fail` — and whose build runner refuses them — reports them as if nothing were wrong. `no aggregate green` keeps each axis's own receipt; it never meant an axis that failed leaves at zero",
259
+ "subject": "plugins/herdr/lib/capability-report.mjs",
260
+ "find": ["\tif (failing.length > 0) {"],
261
+ "replace": ["\tif (false) {"],
262
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
263
+ "timeoutSeconds": 180,
264
+ "signature": "[QK:HPL-INTEGRATION-NONCURRENT-IS-RED]",
265
+ "signatureSource": "scripts/check-herdr-plugin.ts"
266
+ },
267
+ {
268
+ "claim": "HPL-READER-EXPORT-IS-REQUIRED",
269
+ "title": "the export check is dropped, so an installed reader that loads without `readCertifiedLedger` raises its TypeError inside the certification try and is filed as `activation-ledger-uncertified` — the operator is sent to inspect a ledger that is fine instead of to the install that is not, and no body was ever read",
270
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
271
+ "find": ["\tif (typeof reader.readCertifiedLedger !== \"function\") {"],
272
+ "replace": ["\tif (false) {"],
273
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
274
+ "timeoutSeconds": 180,
275
+ "signature": "[QK:HPL-READER-EXPORT-IS-REQUIRED]",
276
+ "signatureSource": "scripts/check-herdr-plugin.ts"
277
+ },
278
+ {
279
+ "claim": "HPL-LEDGER-VANISHED-IS-NAMED",
280
+ "title": "the LATE null guard is dropped, so a ledger that passed the presence check and is gone by the time the installed reader reads it is dereferenced — the early branch cannot cover that race because it already answered while the file existed, and the pane dies with a TypeError before drawing a block",
281
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
282
+ "find": ["\tif (ledger === null) {"],
283
+ "replace": ["\tif (false) {"],
284
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
285
+ "timeoutSeconds": 180,
286
+ "signature": "[QK:HPL-LEDGER-VANISHED-IS-NAMED]",
287
+ "signatureSource": "scripts/check-herdr-plugin.ts"
288
+ },
289
+ {
290
+ "claim": "HPL-PACKAGE-NAME-FROM-MANIFEST",
291
+ "title": "reading the installed package's directory name off `runtime-lock.json` works only on the `npm` arm — the `herdr-checkout` arm is `{source, repository}` and carries no `name`, so this drift yields `undefined`, `path.join` answers that with a TypeError past every named refusal, and the status pane dies before drawing one block on exactly the carrier every candidate window rides (#120; born in 79391fb)",
292
+ "subject": "plugins/herdr/lib/activation-evidence.mjs",
293
+ "find": ["\t\tconst packageName = runtimeModule.readCheckoutPackageSpec(checkoutRoot).name;"],
294
+ "replace": ["\t\tconst packageName = runtimeModule.readRuntimeLock(checkoutRoot).name;"],
295
+ "gate": ["bash", "run.sh", "check-herdr-plugin"],
296
+ "timeoutSeconds": 180,
297
+ "signature": "[QK:HPL-PACKAGE-NAME-FROM-MANIFEST]",
298
+ "signatureSource": "scripts/check-herdr-plugin.ts"
131
299
  }
132
300
  ]
133
301
  }
@@ -42,6 +42,28 @@
42
42
  "timeoutSeconds": 300,
43
43
  "signature": "[QK:META-RETIRE-FRESH-TOUCH]",
44
44
  "signatureSource": "scripts/smoke-meta-install-state.sh"
45
+ },
46
+ {
47
+ "claim": "META-RETIRE-TURN-DURATION-OPERATOR-OWNED",
48
+ "title": "putting showTurnDuration back under management makes entwurf force the operator's own turn-duration display to false, and re-collides the cross-repo managed-keys contract with the operator's own settings fragment",
49
+ "subject": "scripts/meta-bridge-state.py",
50
+ "find": [
51
+ " (\"showTurnDuration\", [\"showTurnDuration\"], False),",
52
+ "]",
53
+ "",
54
+ "_managed_scalar_names = {name for name, _path, _desired in MANAGED_SETTINGS_SCALARS}"
55
+ ],
56
+ "replace": [
57
+ "]",
58
+ "",
59
+ "MANAGED_SETTINGS_SCALARS.append((\"showTurnDuration\", [\"showTurnDuration\"], False))",
60
+ "",
61
+ "_managed_scalar_names = {name for name, _path, _desired in MANAGED_SETTINGS_SCALARS}"
62
+ ],
63
+ "gate": ["bash", "run.sh", "smoke-meta-install-state"],
64
+ "timeoutSeconds": 300,
65
+ "signature": "[QK:META-RETIRE-TURN-DURATION-OPERATOR-OWNED]",
66
+ "signatureSource": "scripts/smoke-meta-install-state.sh"
45
67
  }
46
68
  ]
47
69
  }