@junghanacs/entwurf 0.37.0 → 0.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/AGENTS.md CHANGED
@@ -91,10 +91,10 @@ implement → affected focused gates → independent review → one amendment bu
91
91
  → affected qualification PARTIAL once if gate/mutant/matrix changed → full floor once on frozen candidate → commit
92
92
  ```
93
93
 
94
- - GLG-requested branch checkpoint commits keep completed subject/proof bundles small: scoped review, affected focused checks and normal hooks/shared scanner before each checkpoint, with known RED/unmeasured boundaries recorded. A checkpoint is not frozen-candidate acceptance. The sequence above owns final candidate acceptance: the affected qualification PARTIAL, frozen FULL and native/LIVE/release floors remain mandatory before landing, and the prepared SHA's CI qualification body before shipment, never inherited from an interim commit.
94
+ - GLG-requested branch checkpoint commits keep completed subject/proof bundles small: scoped review, affected focused checks and normal hooks/shared scanner before each checkpoint, with known RED/unmeasured boundaries recorded. A checkpoint is not frozen-candidate acceptance. The sequence above owns final candidate acceptance: the affected qualification PARTIAL, frozen FULL and native/LIVE/release floors remain mandatory before landing, and the prepared SHA's exact-SHA CI push run (its four required jobs; the qualification body is no longer a release axis, #144) before shipment, never inherited from an interim commit.
95
95
  - Inner loop runs only affected gates; review and its corrections finish before the full floor.
96
96
  - A changed contract names a production subject and independent oracle; its focused assertion has a stable QK and exact-once mutant. Matrices change by their declared axes/cells, not appended anecdotes.
97
- - Development never runs the whole qualification body. A changed gate/mutant/matrix runs its affected exact-argv groups once, after review and amendment, as PARTIAL receipts (`./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`); the manifest head stays in the deterministic floor. The whole body runs once per cut, in the prepared SHA's CI: a prepared state awaits it and is never presumed PASS, and a release requires the exact-SHA evidence VERIFY names, never a nearby green run or a PARTIAL.
97
+ - Development never runs the whole qualification body. A changed gate/mutant/matrix runs its affected exact-argv groups once, after review and amendment, as PARTIAL receipts (`./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`); the manifest head stays in the deterministic floor. Since #144 (GLG, 2026-10-16) the whole body is not a release axis: it runs only on the weekly schedule or a manual `qualify=true` dispatch, as a drift diagnostic no cut waits for, and no cut owes a local whole body either. A release states that kill-power was not re-measured at its SHA and lists any earlier-candidate PARTIAL with its own candidate; a PARTIAL never stands for the release, and the release still requires the exact-SHA evidence VERIFY names, never a nearby green run.
98
98
  - Freeze the candidate while the full floor runs; any worktree/index movement voids that receipt. Pre-commit is not the full floor.
99
99
  - LIVE/release floors are not lowered by a shorter inner loop. Failed gate or evidence downgrade blocks the relevant commit/release decision.
100
100
 
package/CHANGELOG.md CHANGED
@@ -4,6 +4,294 @@ All notable changes to this project will be documented here. Format follows [Kee
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.38.0 - 2026-10-16
8
+
9
+ ### Pi SDK 1.3.0
10
+
11
+ - **Accept the coherent nine-member Pi SDK 1.3.0 set (#145).** Upgrade exact pins,
12
+ lockfile, release-age allowlist, upstream constellation metadata and matching fixtures.
13
+ The supported PATH Pi range is now `>=1.3.0 <1.4`. Owned durable app source and emitted
14
+ carrier bytes are unchanged; execution, storage, compaction and provider/auth engines
15
+ remain upstream-owned. Stage2 shell changes and #142 thinking/default/ACP effort are not
16
+ included.
17
+ - **Known upstream behavior, not an app-level LIVE claim.** SDK 1.3.0 sends Haiku 5.5 /
18
+ Opus 5 thinking `off` as disabled; Opus 5.5 still does not support `off`. The app's
19
+ current level-less default reaches the SDK as `off`, so Haiku 5.5 / Opus 5 thinking is
20
+ EXPECTED to be disabled under 1.3.0. That is an inference inherited from the #142 source
21
+ reading, not measured in a vendor LIVE turn; the default selection is unchanged here and
22
+ remains #142's subject. Upstream also changes malformed tool-argument validation and
23
+ compaction baseline placement; no cross-version prompt-loss or universal compatibility
24
+ claim is made here.
25
+
26
+ ### Release boundary and verification
27
+
28
+ - **Implementation checkpoint.** `d25b71e6f320462e67827d71265811de7cd89db1`, reviewed
29
+ 19-file SDK bundle. Its branch push CI run 38843056373 passed all four required jobs
30
+ (620 s wall, static FULL 571 s). This is checkpoint evidence, not the prepared 0.38.0
31
+ SHA's CI.
32
+ - **Kill-power re-measured at this shipped SHA: none (all 979 committed claims not
33
+ re-proved, #144).**
34
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 2fa0d8210e98 surface
35
+ 79f961d6d2fa -- `check-dep-versions` 4/4 receipt 5e787c54c298
36
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 2fa0d8210e98 surface
37
+ 79f961d6d2fa -- `check-pack-pin-matcher` 2/2 receipt dc1abd661323
38
+ - Both PARTIAL candidates are head 2fa0d82 plus the then-uncommitted SDK diff (patch
39
+ 6f01d8dc), measured before d25b71e existed; they are not the shipped 0.37.1 bytes and
40
+ not this SHA.
41
+ - **Bounded forward-open proof.** One synthetic 1.2 SDK-written conversation was selected
42
+ by exact id, resumed by the 1.3 checkout reader under the same carrier, given one faux
43
+ turn, and reopened with history and identity preserved. Negative 2/2, writer 17/17,
44
+ reader 16/16; vendor wire counters 0 and final seals stable; independent review B0/D0. This is not a
45
+ universal migration/rollback/compaction or cross-version MCP schema certificate. The
46
+ first fixture attempt was RED and remains preserved. Source and limitations are in
47
+ [#145](https://github.com/junghan0611/entwurf/issues/145#issuecomment-6208532928); no operational DB was opened for this test.
48
+ - **Host alignment and continuity.** GLG authorized exact global Pi 1.3.0 installation and
49
+ manually restarted harnesses. Actual host and checkout SDK versions were 1.3.0. The same
50
+ coordinator garden id/cwd resumed, then exchanged real v2 replies with two existing
51
+ Claude citizens. After GLG reported SDK compaction complete, self identity and bookmark
52
+ continuity were observed; SDK internals/vendor prompt ordering were not inspected.
53
+ - **Static/LIVE split, newly approved for this cut.** GLG explicitly approved local LIVE
54
+ and whole static FULL in the prepared SHA's exact push CI. Local P4/P5-static/M0 FULL
55
+ are deferred, not passed: the FULL includes Herdr checks prohibited on this operator
56
+ host. The mutation whole BODY remains a weekly/manual diagnostic, never a release axis.
57
+ - **Local LIVE r1: MUST (non-static 23) PASS=23 FAIL=0 SKIP=0 UNRUN=0; BEHAVIOR PASS=1
58
+ FAIL=0.** The unchanged release aggregate's non-static MUST steps and its advisory
59
+ BEHAVIOR step ran once, 2026-10-16 14:00:43–14:05:43 KST, through a one-off stepwise
60
+ driver whose 24 step lines equal `release_gate`'s at d25b71e (source order, argv, env,
61
+ cwd and classifiers), stopping on the first MUST red. Candidate: d25b71e plus the four
62
+ release-metadata files, fingerprint `12fca42c` equal at freeze, before and after.
63
+ `smoke-codex-fresh-live` ran against an owned app-server in its own session A, separate
64
+ from the gate session S, with `gpt-5.6-luna` / `openai-codex/gpt-5.6-luna`;
65
+ `smoke-pi-durable-fresh-live` ran on the host's Pi 1.3.0 and is not repeated as a
66
+ separate smoke. Receipts: `.tmp-verify/release-0.38.0/live-r1/` (`live.log` b676817c,
67
+ `steps.SHA256SUMS` c7868c81). This is not a local `release-gate --cut` PASS: the
68
+ static step did not run locally.
69
+ - **Post-LIVE delta: evidence records and prose docs only.** After the LIVE run,
70
+ `CHANGELOG.md` and `NEXT.md` took the evidence records, and a separate docs-only commit
71
+ corrected stale prose in `DELIVERY.md`, `ROADMAP.md`, `VERIFY.md`,
72
+ `docs/acp-backend-rail.md` and `docs/external-mcp-host.md`. `package.json`,
73
+ `plugins/herdr/runtime-lock.json`, the lockfile, `run.sh` and all source/carrier bytes
74
+ equal the LIVE candidate; GLG waived a LIVE re-run for prose-only changes, and the
75
+ prepared SHA's push CI runs the whole static floor over the final bytes.
76
+ - **Native Claude host doctor:** the operator's `entwurf` bin in clone mode (resolving to
77
+ this checkout) ran `doctor-meta-bridge` and exited 0 (`meta-bridge doctor: PASS`) after
78
+ the host transition, with two live record-backed Claude MCP owners and a writer at v3
79
+ parity. This is not a doctor proof of the 0.38.0 tarball or an installed consumer.
80
+ Receipt: `.tmp-verify/release-0.38.0/doctor-meta-bridge.txt`.
81
+ - **Prepared exact-SHA CI is owed by this SHA's push run.** All four required jobs
82
+ (`check`, `install-surface`, `artifact-consumer`, `macos-install-surface`) and the
83
+ preserved post-CI tarball consumer acceptance remain owed; no tag or publication yet.
84
+ - **Herdr follows core.** The closed `herdr-checkout` verification carrier stays unchanged
85
+ apart from its dated comment. No plugin manifest version, registry pin or production
86
+ acquisition authority changes here. Re-pin and real Herdr installation/update/use proof
87
+ follow the published core 0.38.0 bytes as a separate plugin snapshot; this core LIVE is
88
+ not that proof.
89
+
90
+ ## 0.37.1 - 2026-10-16
91
+
92
+ ### Verification
93
+
94
+ - **The native-module ingress claims get their own mutant coordinate (#144).** The 13
95
+ `PI-DURABLE-MODULE-*` claims carry their QKs only in `pi-durable-native-module.test.ts`, and a
96
+ kill is attributed from the mutant's own QK, yet each of them re-ran all six pi-durable beside
97
+ tests. `./run.sh check-pi-durable-native-module` runs that one file and is now their gate argv;
98
+ `check-pi-durable-beside` no longer runs it. No claim, find/replace, signature or build changes.
99
+ - **The carrier claims get their own mutant coordinate too (#144).** The 30 claims whose QKs live
100
+ only in `pi-durable-carrier.test.ts` move to `./run.sh check-pi-durable-carrier`, which runs that
101
+ file alone; `check-pi-durable-beside` keeps the adapter, verifier, preflight and owner-join files
102
+ and their 39 claims. All three coordinates stay in `check:contracts`, and every claim keeps its
103
+ subject, find/replace, signature and bridge build (the carrier test reaches the bridge through the
104
+ bootstrap). Measured once on one host, on an isolated copy of `5e1e629` (M1, a composition
105
+ measurement, not a kill run): the six files together took 24.5s, the carrier file alone 17.6s and
106
+ the native-module file alone 1.7s, so before the split every mutant of the former six-file
107
+ `check-pi-durable-beside` group (82; the two `check-node-floor-coherence` claims were never in it)
108
+ paid the carrier's time. Those seconds are local, not CI timing. A moved mutant no longer runs beside the other
109
+ files; that was incidental exposure, never the ground of a kill, which is attributed only from the
110
+ mutant's own QK.
111
+ - **The whole qualification body is no longer a release axis (#144).** By GLG's decision of
112
+ 2026-10-16 (split local gates from CI; a named loss of verification is accepted to stop paying for
113
+ the same proof twice), no push runs the body any more and no cut waits for it. Measured from the
114
+ GitHub API over one cut window (v0.36.1 push `cab1b9f` through the Herdr 0.37.0 snapshot `5e1e629`,
115
+ six `ci.yml` runs): the body ran five times on five SHAs for 506.3 minutes of `check`-step time,
116
+ once as a dispatch that re-bought it for a SHA whose push had skipped it, while a push run without
117
+ it took 10.9 minutes wall. That is the cost before this change, not a measured saving. The body now
118
+ runs only on the weekly schedule or a manual `qualify=true` dispatch, as a drift diagnostic. The
119
+ push-range filter that decided when it ran (`scripts/ci-qualify-decide.sh`, its replay fixture, and
120
+ the five `QUALIFY-FILTER-*` claims) is retired with it, and the release skill no longer dispatches
121
+ the body.
122
+ - **The release oracle takes the push run as its only witness, and no longer reads the body
123
+ (#144).** `verify-exact-ci.sh` asks for push runs of the exact SHA (`--event push`, and a jq that
124
+ keeps only push runs) and judges the four required jobs. Its fourth axis, the body step, is
125
+ removed with `RELEASE-SHA-QUALIFIED-IN-CI`, and its PASS prints that the body is not a release
126
+ axis instead of a body success line. `check-release-gate-outcomes` drives the shipped script
127
+ through a fake `gh`: `RELEASE-WITNESS-IS-PUSH-RUN` pins the one `run list` call it sends (the
128
+ fake evaluates no jq, and GitHub's own filtering is not observed), `RELEASE-ORACLE-REFUSES-NON-SUCCESS-JOB`
129
+ refuses each required job that is absent, failed, skipped, cancelled or unconcluded, and
130
+ `RELEASE-ORACLE-CLAIMS-NO-BODY` passes the four jobs whether the body step is skipped, absent or
131
+ green without ever naming it. The `release-gate` lane is 21 claims.
132
+ - **Named loss.** A release no longer re-measures the kill-power of the committed claims at its SHA.
133
+ Its section says so (`Kill-power re-measured at this shipped SHA: none`), and lists a PARTIAL
134
+ receipt only with its own candidate, never summed into a count for the release. The weekly run is
135
+ a drift window, not a guarantee for any commit.
136
+ - **The mux lifecycle LIVE runs on a different native model, and before the ACP tier.** In 0.37.0's
137
+ first LIVE run and in this cut's first one, `smoke-mux-lifecycle-live` went red the same way: its
138
+ pi-native sibling (`openai-codex/gpt-6-luna`) was alive, ran shell no-ops, answered "ACK" and never
139
+ called the callback tool within 300 s. The cause is not determined; one instrumented diagnostic run
140
+ saw the callback declared in the first request and called back in about 4 s, so the failure did
141
+ not reproduce. The test's native model is now `openai-codex/gpt-6.1-sol:low` (`VERIFY.md` names it), and
142
+ `release-gate` runs this step right after the v2 matrix, before the ACP tier, so a red answer comes
143
+ before the ACP turns are spent. This is a test-model and order change, not a fix: the `gpt-6-luna`
144
+ cause stays undetermined. In this cut's second and third LIVE runs the step passed on the new
145
+ model and order; those are two observations, and neither proves the earlier cause.
146
+ - **The Codex first-admission LIVE now says the id prefixes are part of the ids.** In this cut's
147
+ second LIVE run the moved mux step passed, and `smoke-codex-fresh-live` failed on its last check:
148
+ the Codex sibling's final `entwurf_v2` arguments carried `PI_SESSION_ID=485` and
149
+ `PI_WINDOW_ID=1130` where the launch receipt printed `$485` and `@1130`, with every other field
150
+ exact. Its instruction named the `$` and `@` only inside the placeholder text; it now tells the
151
+ sibling to copy both ids byte for byte from the receipt's `window:` line, keeping each leading
152
+ prefix. The exact-argument comparison is unchanged and nothing is stripped. That the wording
153
+ invited the drop is a hypothesis: the same code and model passed in 0.37.0. In this cut's third
154
+ LIVE run the step passed with both prefixes exact (`$488`, `@1136`); that is one run, and it does
155
+ not prove that the wording caused the earlier drop or rule out model variation.
156
+
157
+
158
+ ### Release boundary and verification
159
+
160
+ - **Scope.** A core patch over `v0.37.0` for #144: `1df7926` (the pi-durable native-module and
161
+ carrier mutant coordinates, and the release oracle's job refusal driven through a fake `gh`) and
162
+ `c208d37` (the whole qualification body retired as a release axis). The Herdr plugin snapshot
163
+ `v2026.10.15-herdr.0.37.0` at `5e1e629` is unchanged; pi 1.3.0 (#145) is not in this cut.
164
+ - **Kill-power re-measured at this shipped SHA: none (all 979 committed claims not re-proved,
165
+ #144).**
166
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
167
+ e907429b9c00 -- `check-pi-durable-native-module` 13/13 receipt e0f96c3374de
168
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
169
+ e907429b9c00 -- `check-pi-durable-beside` 69/69 receipt 36e46bdd4cf0
170
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
171
+ ea26d369b1af -- `check-pi-durable-carrier` 30/30 receipt 01f9096a8eb5
172
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
173
+ ea26d369b1af -- `check-pi-durable-beside` 39/39 receipt 93d9f5cdf699
174
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
175
+ 980384f2532f -- `check-release-gate-outcomes` 25/25 receipt eedfb075bf07
176
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
177
+ 980384f2532f -- `check-gate-manifests` 52/52 receipt 8a976415c566
178
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
179
+ 980384f2532f -- `check-gate-qualification.ts --attribution-self-test` 1/1 receipt 3edfa0af9d3a
180
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 1df7926257a9 surface
181
+ 106c59c5cb99 -- `check-release-gate-outcomes` 21/21 receipt c869965b8dbc
182
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 1df7926257a9 surface
183
+ 106c59c5cb99 -- `check-gate-manifests` 52/52 receipt 08eae97d65b0
184
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head 1df7926257a9 surface
185
+ 106c59c5cb99 -- `check-gate-qualification.ts --attribution-self-test` 1/1 receipt 276118d0ba9b
186
+ - Earlier-candidate PARTIAL (operator-attested, not this SHA): head c208d37f1442 surface
187
+ d941509e2e9e -- `check-release-gate-outcomes` 21/21 receipt cd0a59e12569 (taken after the
188
+ mux model/order change and before the Codex id-prefix sentence; kept locally under
189
+ `.tmp-verify/release-0.37.1/fix-mux-first/partial-evidence/`)
190
+ - **Not re-measured for the Codex id-prefix sentence.** The five mutants whose subject is
191
+ `scripts/lib/codex-fresh-live-protocol.ts` were reviewed as lying outside the changed bytes, and
192
+ their `check-mux-fresh-call` group (150 mutants over 18 subjects) was not run, so those five
193
+ kills are not re-measured on the new bytes. The new sentence has no deterministic assertion of
194
+ its own: deleting it would leave the deterministic suite green, and only a LIVE run would see it.
195
+ - **Where those receipts are published.** Each receipt above except the newest (`cd0a59e12569`) is
196
+ listed with its candidate in a #144 checkpoint comment, so another host can trace it without this
197
+ operator's paths; the newest is local and operator-attested only, in no #144 comment. A′
198
+ ([#144 comment 6195663856](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6195663856)),
199
+ B ([6196318282](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6196318282)),
200
+ RO-1 ([6200017214](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6200017214)) and
201
+ P1 ([6202638853](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6202638853)).
202
+ The links add location only; they prove nothing new.
203
+ - **Branch CI, not this SHA.** The pushed branch head `c208d37` ran the new policy's first push CI
204
+ (run 38811304369): the four required jobs green, the body step skipped, created to last required
205
+ job 645 s. That run is evidence for `c208d37`; the prepared SHA owes its own.
206
+ - **Unpublished candidate carrier.** As in 0.37.0, `plugins/herdr/runtime-lock.json` names the
207
+ closed `herdr-checkout` source, because 0.37.1 has no published integrity yet and the runtime
208
+ refuses an npm lock whose version is not the checkout's (`scripts/herdr-runtime.mjs:355-358`).
209
+ The npm 0.37.0 bytes and every existing tag are unchanged; re-pinning registry bytes is a later,
210
+ separate Herdr snapshot.
211
+ - **No local static floor; it is the exact CI's.** `check:hermetic` carries
212
+ `check-herdr-plugin-build` and `check-herdr-sandbox`, which must not run on the operator host,
213
+ and `release-gate`'s first MUST step is `pnpm run check:full`. By GLG's decision of 2026-10-16
214
+ for this cut (a new approval, not inherited from 0.37.0), `check:full` is not run locally at P4,
215
+ at P5's first step or at M0, and is owed whole to the prepared SHA's CI.
216
+ - **LIVE, taken step by step, not as `release-gate --cut`.** The gate's 23 non-static MUST steps
217
+ and its BEHAVIOR step ran in the gate's own order, command, environment and working directory,
218
+ stopping at the first red, with each run's candidate fingerprint the same at freeze, before and
219
+ after. The first run (`c208d37` with this preparation's first edits) passed 18 MUST steps and
220
+ failed `smoke-mux-lifecycle-live` at its old position; the second (with the model and order
221
+ change) passed 21 and failed `smoke-codex-fresh-live` on the dropped id prefixes. Both red
222
+ receipts are kept. The third ran on the tested bytes, `c208d37` with this cut's source and package
223
+ edits; after it only `CHANGELOG.md` and `NEXT.md` changed, to record these results. It ran every
224
+ step itself, none reused: **MUST 23/23 PASS, FAIL 0, SKIP 0;
225
+ BEHAVIOR 1/1 PASS.** `smoke-mux-lifecycle-live` passed 81 checks as step 5,
226
+ `smoke-codex-fresh-live` 66 assertions against one owned app-server in its own tmux session
227
+ (named pane pid with its recorded start time, `gpt-5.6-luna` and `openai-codex/gpt-5.6-luna`,
228
+ stopped by one TERM after the run with its subtree, listener and control alias gone), and
229
+ `smoke-pi-durable-fresh-live` 36 assertions. Receipts on the operator host, under
230
+ `.tmp-verify/release-0.37.1/`: the third run's freeze fingerprint `3a90e3f1f2a2`, gate log
231
+ `94d14b3d42af` and step-log manifest `ded0d693c3ff` (24 logs); the red runs' gate logs
232
+ `3e16e8964f9e` and `da9622fb5312`. This is local LIVE evidence, not a release-gate verdict, and
233
+ no static CI result is claimed by it.
234
+ - **Publication boundary.** The LIVE and PARTIAL lines above are local preparation evidence.
235
+ Shipping this version separately requires the prepared SHA's exact CI (the four required jobs), a
236
+ preserved accepted candidate made from that SHA, and the tag and GitHub Release cut from it; npm
237
+ publication is the operator's.
238
+
239
+ ## v2026.10.15-herdr.0.37.0 — Herdr Entwurf plugin 0.37.0
240
+
241
+ A separate Herdr plugin snapshot, not another core release: core package 0.37.0 and
242
+ its `v0.37.0` tag remain unchanged. The operator has published the core to npm.
243
+
244
+ ### Herdr plugin
245
+
246
+ - **Re-pin the published core 0.37.0 and close the checkout window.**
247
+ `plugins/herdr/runtime-lock.json` returns from the `herdr-checkout` carrier that 0.36.1 and
248
+ 0.37.0 rode to production npm source `@junghanacs/entwurf@0.37.0` with the registry's
249
+ measured sha512 (`sha512-ETVgzMWf…7964A==`). The plugin manifest moves 0.36.0 → 0.37.0;
250
+ admission remains Herdr >= 0.9.0 and the one-build/one-pane/Linux shape is unchanged.
251
+ - **The same core capability through Herdr.** The runtime this snapshot acquires carries core
252
+ 0.36.1 and 0.37.0: the Claude ACP driver on 0.90.0, Codex app-server socket ownership read
253
+ from the kernel, the durable app's transport and compaction tuning (#143) and its project
254
+ skill list (`4968ffd`). The measured Herdr is the 0.9.5 pin that landed in core 0.37.0
255
+ (`d8cd8f3`). This snapshot changes no rail, gate or mutant, and Pi's accepted range is the
256
+ same as 0.36.0's.
257
+ - **Upgrade by acquisition source, not just version.** A settled npm-source 0.36.0 installation
258
+ can rebind under the plugin README's ownership conditions. A host that installed an
259
+ intervening `herdr-checkout` candidate must explicitly deactivate by its own absolute runtime
260
+ path before reinstalling the npm-source snapshot. No operator installation or active session
261
+ is rewired by this release work.
262
+
263
+ ### Source-specific verification
264
+
265
+ - Registry metadata reports version/latest 0.37.0, repair 0.12.8-repair.1. The downloaded
266
+ tarball is 11144951 bytes, SHA256
267
+ `d127a927e6a9f9c6561f86975dc30697aebaa5eeb2de463e8f0d765ff12035ee`, byte-identical to the
268
+ preserved accepted core candidate; independently computed sha512 equals `dist.integrity`, and
269
+ the registry-shipped runtime helper is byte-equal to this checkout's.
270
+ - The exact registry tarball passed the required Docker consumer without repacking
271
+ (`node:24-bookworm`, repoDigest `node@sha256:6dac556d…`).
272
+ - **The npm runtime swap against the real registry**, by the registry-shipped helper in sandboxed
273
+ user roots, 20/20 checks. The 0.36.0 runtime was seeded from its own committed lock; the swap
274
+ to 0.37.0 took one acquisition, the cached tarball's sha512 equals the lock and its sha256
275
+ equals the ready journal's observed digest and the accepted candidate. The `installing`
276
+ journal carried the 0.36.0 identity as `previousRuntime` and the `runtime-ready` journal
277
+ carries `null`; when acquisition began the 0.36.0 tree was still at the active address. A
278
+ manually seeded torn swap (the active tree moved to the backup address with a half candidate
279
+ in staging; not a killed process) was restored before acquisition and reported
280
+ `recovered: torn-swap-with-candidate`. An exact re-request acquired nothing and left journal
281
+ and tree byte-identical, and the owned removal reclaimed cache, runtime and journal. Not
282
+ certified by these cells: Herdr's install/update relocation, harness wiring, the installed
283
+ CLI's deactivate path, a model turn, or recovery from a real kill.
284
+ - **Focused gates on the branch**, with HEAD, index and work surface unchanged across them:
285
+ `check-herdr-supply` (11 assertions), `check-herdr-plugin` (49),
286
+ `check-herdr-plugin-profile` (14), `check-herdr-runtime-bootstrap` (31),
287
+ `check-herdr-activation` (33), `check-herdr-placement` (25), `check-herdr-fresh-call` (45)
288
+ and `check-gate-manifests` (982 committed mutants across 72 lanes validated, none executed).
289
+ `check-herdr-plugin-build` and `check-herdr-sandbox` were not run locally because they run
290
+ the operator's own herdr; they ride the pushed SHA's FULL floor in CI.
291
+ - Pending, and not claimed here: the pushed SHA's four-job CI with the qualification body, and
292
+ the public-ref install/use/deactivate journey on Herdr 0.9.5. Earlier npm or checkout-carrier
293
+ receipts cannot certify these source-specific axes.
294
+
7
295
  ## 0.37.0 - 2026-10-15
8
296
 
9
297
  ### pi-durable
package/CONTRIBUTING.md CHANGED
@@ -30,7 +30,7 @@ pnpm check # everyday core (prints wall time; <=60s on the referenc
30
30
  pnpm run check:full # full deterministic floor — the required PR gate
31
31
  ```
32
32
 
33
- The deterministic floor is tiered (#70). `pnpm check` is the everyday core (biome, tsc, the vitest lanes, and the fast contract gates); `pnpm run check:full` adds the hermetic-integration and package/install tiers — including `check-gate-manifests`, the qualification HEAD (runner self-test, manifest-set validation, declared lane inventory; zero COMMITTED mutants executed — the self-test runs only its synthetic fixture mutants in tmp fixture repos — ~20s), but not the separately scheduled mutant-EXECUTING body `check-gate-qualification`, which CI runs on a branch push whose diff touched the qualification surface (and unconditionally on dispatch or the weekly schedule). Development never runs that whole body: a gate, mutant or matrix change runs only its affected exact-argv groups once, as PARTIAL receipts (`./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`), and the whole body runs once per cut, in the prepared SHA's CI. Exact membership is the named `check:*` scripts in `package.json`. Run `check:full` once on your frozen commit candidate — the pre-commit hook (`.husky/pre-commit`) carries only fast static checks (whitespace, lint, typecheck), not the full floor, so a green `pnpm run check:full` before commit is the evidence that your change holds (scheduling contract: AGENTS.md "Verification scheduling"). No install or build lifecycle script installs git hooks: a global `core.hooksPath` guard that chains to repository-local hooks runs its own checks, then delegates — to `.husky/pre-commit` here, unless an executable `.git/hooks/pre-commit` takes precedence.
33
+ The deterministic floor is tiered (#70). `pnpm check` is the everyday core (biome, tsc, the vitest lanes, and the fast contract gates); `pnpm run check:full` adds the hermetic-integration and package/install tiers — including `check-gate-manifests`, the qualification HEAD (runner self-test, manifest-set validation, declared lane inventory; zero COMMITTED mutants executed — the self-test runs only its synthetic fixture mutants in tmp fixture repos — ~20s), but not the separately scheduled mutant-EXECUTING body `check-gate-qualification`, which CI runs only on the weekly schedule or a manual `qualify=true` dispatch, as a drift diagnostic outside release acceptance (#144). Development never runs that whole body: a gate, mutant or matrix change runs only its affected exact-argv groups once, as PARTIAL receipts (`./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`), and no cut waits for the whole body. Exact membership is the named `check:*` scripts in `package.json`. Run `check:full` once on your frozen commit candidate — the pre-commit hook (`.husky/pre-commit`) carries only fast static checks (whitespace, lint, typecheck), not the full floor, so a green `pnpm run check:full` before commit is the evidence that your change holds (scheduling contract: AGENTS.md "Verification scheduling"). No install or build lifecycle script installs git hooks: a global `core.hooksPath` guard that chains to repository-local hooks runs its own checks, then delegates — to `.husky/pre-commit` here, unless an executable `.git/hooks/pre-commit` takes precedence.
34
34
 
35
35
  For changes that touch backend launch, session lifecycle, or `_meta` shape, also run
36
36
  the live ACP smokes that cover the touched rail — at minimum:
package/DELIVERY.md CHANGED
@@ -116,7 +116,7 @@ physical host. Do not read a D-level cell as a Darwin receipt.
116
116
  | **Copilot CLI first-party extension** | raw transport probe; superseded by the owned product unit | D7 path observed; D3 control receipt incomplete; D8 unproven | CLI-spawned extension over stdio JSON-RPC; `joinSession()` + documented `fs.watch` → `session.send({mode:"enqueue"})`. Idle wake, exact-marker reply, and completion passed on 2026-08-23 (CLI 1.0.80, L4, one Linux host). Two-process isolation was observed but its decisive B log was not preserved. Kept as the transport receipt the owned receive unit was built on; the shipped unit differs deliberately — it announces the inbox instead of injecting the body. |
117
117
  | **Copilot CLI garden citizen** | shipped in 0.15.0; send + receive + visible fresh accepted on one host | D6; D7 partial; D3 pending; D8 unproven | Birth, garden id, MCP hand and record-backed sender identity are accepted; the RECEIVER is an installed first-party extension that binds to the V3 record, writes a receiver marker owned by the WATCHER pid, and rings a doorbell the model drains with `entwurf_inbox_read`. `wakeMode` is `self-fetch`, so dispatch reaches the mailbox rail: armed → delivered, unarmed/stale → the honest `mailbox-undeliverable` refusal. **D6 is the owned-invocation LIVE acceptance of 2026-08-23** — garden `20260823T181316-d9f6ba`, native `20fe30c8-b2bc-4600-91a0-8a409131be51`, CLI 1.0.80: receive log `joined`→`armed`→`doorbell fresh=1`→`rang`, mailbox `lastEnqueuedAt 09:23:41.235Z` / `lastReadAt 09:23:56.480Z`, and a model reply on the same record/native/gid chain. **Visible fresh (step 9 clause 7) is a separate LIVE, 2026-08-25** — launch window `@89`/`%89` nonce `mux-fresh-call-690529ae99f99faa2252aefb`; exact-callback garden `20260825T085721-f68be0`; one `entwurf_v2` → `meta-mailbox → enqueued`; same garden `lastReadAt 2026-08-24T23:57:47.784Z` plus same-gid reply; GLG saw footer garden id and a healthy multi-turn window. Those rows stay unmerged. D7 is PARTIAL: reply and read receipt were observed, the completion taxonomy and long-haul operation were not. D3 (second-session isolation of an owned invocation) is PENDING — observed once, decisive log lost to scratch cleanup. Evidence level L4: one host. Launch through the owned invocation `entwurf copilot`, which sets `COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS` for that one process; `doctor-copilot-receive` reads live CLI environments because a session launched without it is silently inert. Visible fresh is operator-metered and is not a release-gate MUST. |
118
118
  | **OMP (`omp`) garden citizen** | shipped in 0.16.0; send + receive + visible fresh accepted on one host | D6; D3 proven; D7 partial; D8 partial | Two in-process extensions in the operator's own TUI: birth mints the `mode === "tui"` host (subagents mint nothing) and names it as sender; the RECEIVER unit joins that citizen in the SAME process, holds an `fs.watch` on its mailbox signal, and rings an announce-only doorbell through the vendor's `pi.sendUserMessage` — measured to be on the FACTORY object, not the event ctx, and measured to start a turn on an idle host with zero typing (`agent_start` +31ms). `wakeMode` is `self-fetch`: the model drains with `entwurf_inbox_read` and THAT read is the receipt. **D6 is the LIVE acceptance of 2026-08-30** (oracle, omp 18.0.0) — garden `20260830T140819-116f6a`, `lastEnqueuedAt 05:08:20.555Z` / `lastReadAt 05:08:23.958Z`, and the citizen's own transcript carrying `mcp__entwurf_bridge_entwurf_inbox_read` for its own garden id. **D3 is PROVEN, not pending**: with two live omp citizens armed, one addressed enqueue rang exactly one doorbell and the sibling persisted no transcript and kept an empty mailbox. D7 is PARTIAL (`lastReadAt` needs no scraping; the reply does). D8 is PARTIAL — dedupe and every stale-handling path are implemented and hermetically pinned, ordering/loop-guard/crash-recovery are not. The `/new` unarm is the rail-specific one: the watch lives in the operator's TUI, so pid + start-key cannot see a citizen change underneath a living process, and without an explicit unarm the previous garden id would keep reading deliverable. Requires `tools: xdev: false` in `~/.omp/agent/config.yml` — the vendor default hides MCP tool schemas from the prompt, so the doorbell would name a tool the model cannot call. The decisive receipt lines — the ordering probe, the D6 chain, the D3 isolation and the `/new` unarm — are pasted into `scripts/raw-omp-measure/README.md` §M7 rather than left in a host-local `/tmp` path. Evidence level L4: one Linux host, ARM. **Visible fresh (step 9) is ACCEPTED — the clause 7 LIVE went green on 2026-08-30:** `entwurf_fresh_call` opens omp on all three public surfaces through the bare `omp` runtime with an explicit `--approval-mode yolo` width and the `mcp__entwurf_bridge_entwurf_v` callback name, behind a five-axis pre-mutation preflight whose fifth axis is omp-specific (`tools.xdev !== true`, without which the model cannot call the callback tool at all). **The first turn is a TWO-STAGE BOOTSTRAP rather than a positional prompt, and that is a measured correction, not a preference.** `[LIVE 2026-08-30]` the positional-prompt candidate opened its window and minted its citizen (garden `20260830T181342-452167`, native `01a051f2-3107-7147-8806-fa2a6f527610`), delivered the byte-identical framing as a user message at `09:13:42.413Z`, and the model answered the literal text `ACK` at `09:13:47.105Z` with ZERO tool calls; the caller timed out at 240s. `[source]` the interactive UI defers MCP discovery (`sdk.ts:1847-1855`, `:1881-1905`) while the positional `initialMessage` prompts straight after `mode.init()` (`main.ts:540-565`), and `[측정]` an observer on the same runtime saw `turn_start` at +654ms with the entwurf tools absent and the callback tool present only at +1484ms. So the launcher now carries `{v,target,nonce,task}` on the fixed registered flag `--entwurf-bootstrap`, and the in-process birth extension polls `getAllTools`(`source:"mcp"`) AND `getActiveTools` for the exact callback name, sends a callback-ONLY prompt, arms the task only on a `tool_result` whose stored `toolCallId`, tool name, target, nonce and `isError === false` all match, and DELIVERS it at the next `turn_end` of that same session. `[LIVE 2026-08-30]` that last boundary is itself a measured correction: a first attempt sent the task from inside the `tool_result` handler with an explicit `deliverAs: "followUp"`, the hook log showed the full chain (`bootstrap-armed` → `bootstrap-ready` +440ms → `bootstrap-callback-observed` → `bootstrap-released`), and the task still never appeared in the session — `[source]` an explicit `deliverAs` queues without starting a turn in either state, while the omitted form starts one when idle (`agent-session.ts:6511-6513`), which the same transcript confirmed three seconds later when the Bundle B doorbell's omitted-option send landed and started a turn. `[측정 2026-08-30]` the callback-only half is what was proven to work: model `openai-codex/gpt-5.6-sol`, tool live at +1105ms, prompt injected at +1107ms, and the sibling calling `mcp__entwurf_bridge_entwurf_v` with the exact nonce (`omp-cb-btkvva4r87` → `20260830T184054-1aa1f2`, `meta-mailbox → enqueued`). **The clause 7 acceptance, `smoke-omp-fresh-live` (release-gate MUST), 2026-08-30, 21 assertions, omp 18.0.0 / `openai-codex/gpt-5.6-sol`:** launch through `tools/call entwurf_fresh_call` with nonce `mux-fresh-call-34faea228f3c3638684b40ff`; sibling garden `20260830T192913-df52b9` taken from the CALLBACK's sender envelope and never from the launch receipt; exactly one new citizen (§3.5); addressed `entwurf_v2` → `meta-mailbox → enqueued`; `lastEnqueuedAt 10:29:19.179Z` / `lastReadAt 10:29:24.673Z`; the drain visible in that session's own transcript for its own garden id. **Both bootstrap stages are in that transcript in order** — the callback-only prompt at offset 970, the caller's task at 4732, no four-backend positional framing anywhere, and an assistant message after the task proving it started a turn rather than sitting in a queue. The unit's own log carries the state machine: `bootstrap-armed 10:29:13.399Z` → `bootstrap-ready 10:29:13.819Z` (+420ms) → `bootstrap-callback-observed 10:29:18.663Z` (`toolCallId=call_KZJtkxfzy1IEE4ejKutCPWcm|fc_0858…`) → `bootstrap-released 10:29:18.731Z` → `bootstrap-task-sent 10:29:18.759Z`. Evidence level L4: one Linux host, ARM, one run. `check-harness-admission-parity` keeps the deterministic half of the admission from being a matter of memory. What this does NOT establish: multi-host, multi-model, or repeated fresh calls in one process. **Cross-harness leg, 2026-08-31 (first bidirectional live-turn roundtrip on the committed bytes + operator redeploy):** a claude-code citizen (`20260831T090152-f998ac`) opened a fresh omp sibling through the public surface (nonce `mux-fresh-call-807cb693b1913ce98ffdbfd1`, callback sender garden `20260831T124226-eac41a`), dispatched an addressed `entwurf_v2` → `meta-mailbox → enqueued`, and the omp citizen's own live turn drained and replied into the claude mailbox — its self-report (doorbell → `entwurf_inbox_read`; callback-only first user message, task second) agrees with every receipt on the chain. |
119
- | **pi-durable native host** | 0.31.0 candidate; visible fresh + addressed receive + both cross-harness legs accepted on one Linux host (2026-10-06, `smoke-pi-durable-fresh-live`, 36 assertions, exit 0) | D6 (D3/D4 shown); D7 partial; D8 unproven | The operator-provided pinned source runtime (`cd32f77` + overlay) launched by the managed `entwurf pi-durable --provider … --model … --width task-wide`; the contact registers six tools and spawns the compiled bridge as a direct child; receive is announce-only self-fetch (doorbell → root submission → `entwurf_inbox_read`). Receipt (V on both sides, `openai-codex/gpt-6.1-sol`): real Pi `20261006T223710-e51e21` opened pd `20261006T223720-ba0c08` through `entwurf_fresh_call`; pd's first action called back into Pi with the exact nonce; Pi's live turn → pd mailbox ENQUEUE `2026-10-06T13-37-35-446Z-b57c69.msg`, that message's doorbell submission `done` on pd's root conversation, drained by pd's live turn (`entwurf_inbox_read` of its own id, settled); pd's live turn → Pi `entwurf_v2` settled `control-socket → sent` (native tool-result, joined by call id) and landed as exactly one Pi row with the expected payload and pd as the anchored sender. Native offering (root `pi.system`, toolsAdded/toolsRemoved applied): the six contact tools + bash/read/edit/write/subagent; pd's first root tool call is the callback. Actual model from root `pi.assistant` rows; the generation checkpoint does not retain `request.model` after completion. |
119
+ | **pi-durable native host** | shipped in 0.31.0 (source-runtime route; carrier route since 0.32.0, see `docs/adding-a-harness.md`), receipt below from the 0.31 route; visible fresh + addressed receive + both cross-harness legs accepted on one Linux host (2026-10-06, `smoke-pi-durable-fresh-live`, 36 assertions, exit 0) | D6 (D3/D4 shown); D7 partial; D8 unproven | The operator-provided pinned source runtime (`cd32f77` + overlay) launched by the managed `entwurf pi-durable --provider … --model … --width task-wide`; the contact registers six tools and spawns the compiled bridge as a direct child; receive is announce-only self-fetch (doorbell → root submission → `entwurf_inbox_read`). Receipt (V on both sides, `openai-codex/gpt-6.1-sol`): real Pi `20261006T223710-e51e21` opened pd `20261006T223720-ba0c08` through `entwurf_fresh_call`; pd's first action called back into Pi with the exact nonce; Pi's live turn → pd mailbox ENQUEUE `2026-10-06T13-37-35-446Z-b57c69.msg`, that message's doorbell submission `done` on pd's root conversation, drained by pd's live turn (`entwurf_inbox_read` of its own id, settled); pd's live turn → Pi `entwurf_v2` settled `control-socket → sent` (native tool-result, joined by call id) and landed as exactly one Pi row with the expected payload and pd as the anchored sender. Native offering (root `pi.system`, toolsAdded/toolsRemoved applied): the six contact tools + bash/read/edit/write/subagent; pd's first root tool call is the callback. Actual model from root `pi.assistant` rows; the generation checkpoint does not retain `request.model` after completion. |
120
120
  | **Copilot CLI TUI+server** — *withdrawn lane, kept as evidence* | rejected | D7; D8 unproven | Older official-SDK probe over hidden `--ui-server`; idle enqueue worked, but loopback RPC authentication was not established. The bundled extension supersedes this candidate without reviving it. |
121
121
  | **ACP Claude / Cortex** | shipped runtime, outside this matrix | — | ACP sessions are children launched by entwurf's pi adapter, not already-running native sessions to wake. |
122
122
 
package/README.md CHANGED
@@ -53,7 +53,7 @@ ownership of the harness.
53
53
 
54
54
  Prerequisites: **Node >=24.0.0**, Python 3 for `setup`, and any harnesses you choose
55
55
  to use, already installed and authenticated. Pi is optional-by-presence, supported
56
- range `>=1.2.0 <1.3`; Claude Code supported floor `>=2.1.217` is required for its
56
+ range `>=1.3.0 <1.4`; Claude Code supported floor `>=2.1.217` is required for its
57
57
  managed exec-hook lifecycle. pnpm is needed only for source-checkout setup.
58
58
 
59
59
  ```bash
@@ -83,7 +83,7 @@ restriction; that is not certification of every platform's harness rails.
83
83
 
84
84
  ### Native durable (pi-durable)
85
85
 
86
- **The package supplies Entwurf's owned app/TUI carrier and nine exact Pi 1.2.0 SDK
86
+ **The package supplies Entwurf's owned app/TUI carrier and nine exact Pi 1.3.0 SDK
87
87
  members.** No separate runtime checkout, patch, build or ordinary Pi CLI is needed.
88
88
  The launch verifies carrier integrity and every reachable SDK edge's name/version;
89
89
  incomplete, drifted or mixed supply refuses by name.
package/VERIFY.md CHANGED
@@ -95,8 +95,7 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
95
95
  ### The canonical floor — two entry points
96
96
 
97
97
  - **Deterministic floor — two tiers (#70):** `pnpm check` is the everyday CORE — toolchain (lint + typecheck), the vitest lanes, and the pure-unit / behavioral-contract / source-topology gates plus the cheap static coherence checks. It prints its own total wall time; acceptance is ≤60s on the reference host `oracle` (an operator measurement, never a hard wall-clock gate on arbitrary hosts). `pnpm run check:full` is the FULL deterministic floor — the core plus the hermetic-integration and package/install tiers — and is what the frozen-candidate protocol, push CI, release-gate, and `prepublishOnly` run. Exact membership is the named `check:*` group scripts in `package.json` (the executable SSOT — this document records meaning and principles, not the command list); a gate changes tier by semantic-class decision, never by getting faster or slower. One core member assumes a build output: the beside test `pi-extensions/entwurf-control.test.ts` (reached through `check-tests-beside-behavior`) registers the COMPILED bridge and refuses by name when it is absent. `prepare` normally builds it at install; after an `--ignore-scripts` install or a bridge source change, run `pnpm run build-bridge` (in the sandbox candidate when verifying one) before the core. The FULL tier carries the qualification HEAD (`check-gate-manifests`, through `check:hermetic`); the everyday core does not, and neither tier carries the separately scheduled mutant-executing body (`check-gate-qualification`).
98
- - **Discriminating power of that floor:** `./run.sh check-gate-qualification` (scheduled, not ambient: the whole body runs only as the bare call — in the CI `check` job on a branch push that touched the qualification surface, and — for a cut — at the prepared SHA, where the exact-SHA release oracle requires that CI step once and the prepared state awaits it, never presumed PASS; a cut therefore batches its commits into that one prepared push (#132 took the cut's body off the local `release-gate`). Development runs no whole body (#133): a lane that changes a gate/mutant/matrix runs its affected exact-argv groups once, after review, as PARTIAL receipts — `./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`, whose arguments reach the runner's parser unchanged and are refused there by name, before any body or snapshot, when malformed, missing or repeated. A receipt is a measurement of one group, never a qualification pass. Neither form is inside the default check chains; a semver TAG push triggers no CI at all, and the exact-SHA evidence a release quotes is whichever run at that commit CARRIES the body — the branch run when the push touched the qualification surface, else a dispatch run; a push that touched none of the qualification surface skips the body, and `workflow_dispatch -f qualify=true` plus a weekly `schedule` run it unconditionally — the exact-SHA release oracle refuses a SHA whose body step did not conclude success) re-plants committed defect mutants (`scripts/mutants/*.json`, one per closed defect class) in an isolated snapshot repo and requires each to turn its gate red **bounded and at its claimed `[QK:<claim>]` signature** — a wrong-reason red fails, a baseline-red control voids the whole group, and the runner is negative-controlled on every run (zero-match/multi-match/survived/wrong-reason/hang/control-red/impurity). This measures whether the deterministic gates still *block* what they claim to block; it is **not a new evidence level** (L0–L5 are untouched) and never substitutes for LIVE evidence. Per-cut records cite claim IDs + killed mutant IDs — "N checks passed" alone is not evidence. `check-agy-permission-matrix` complements it with the enumerated permission contract space (literal cells + stated exclusion rules, oracle independent of the SUT). The gate's HEAD is separable and IS in the floor: `check-gate-manifests` runs the runner self-test, validates the committed manifest set against the origin index, and asserts the declared lane inventory, while executing zero COMMITTED mutants (the self-test runs only its synthetic fixture mutants, in tmp fixture repos) and never snapshotting the repo — three of the five reds qualification has ever produced in CI died in that head, in under five seconds.
99
- - **Push matching is conservative and hunk-aware (#137).** Git ranges read mutant manifests from the named HEAD commit, not a later working tree. Signature sources and the existing deciding machinery always match at file level, including paths that are also subjects. Only TOML subjects (`.toml`) may skip, and only when every mutant's joined `find` span occurs exactly once on both blobs, stays on the same lines, and intersects no zero-context diff hunk. Markdown, JSON, code and unknown subject types remain file-level. An outside-find early return/import/caller change can weaken a code mutant without editing its literal find. A presence/`includes` oracle whose required literal is shorter than the find can be re-satisfied by an out-of-span restatement; a scratch-repo probe measured exactly that false SKIP for `ADMISSION-LEGACY-DOCUMENTED` in `DELIVERY.md`. A later duplicate JSON key wins under `JSON.parse`, which every current JSON data oracle uses. TOML refuses a redefined key, and the current TOML oracles are exact-count/absence checks; a future TOML subject with a presence oracle reopens this boundary. `QUALIFY-FILTER-TOML-ONLY-REFINEMENT` pins Markdown/JSON at file level. Moved, absent, ambiguous, binary or unreadable spans/diffs/manifests run the body with a named reason; renames are compared as delete/add. `--files-from` has no hunk evidence and retains path identity. There is no Herdr filename or release-shape exemption. Span matching is not proof of unchanged kill-power. The rule narrows per-push qualification to those declared TOML spans; forced/scheduled and exact-SHA release qualification remain the backstop. This narrows redundant data-only pushes, never the FULL floor or exact-SHA release body's obligation; a body-less plugin SHA cannot supply the core SHA's evidence.
98
+ - **Discriminating power of that floor:** `./run.sh check-gate-qualification` (scheduled, not ambient: the whole body runs only as the bare call — in the CI `check` job on the weekly `schedule` or a `workflow_dispatch -f qualify=true`, never on a push. It is a drift diagnostic, not a release axis (#144): no cut waits for it and the exact-SHA release oracle reads only the push run's four required jobs. Development runs no whole body (#133): a lane that changes a gate/mutant/matrix runs its affected exact-argv groups once, after review, as PARTIAL receipts — `./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`, whose arguments reach the runner's parser unchanged and are refused there by name, before any body or snapshot, when malformed, missing or repeated. A receipt is a measurement of one group on its own candidate, never a qualification pass and never coverage of a release. Neither form is inside the default check chains; a semver TAG push triggers no CI at all) re-plants committed defect mutants (`scripts/mutants/*.json`, one per closed defect class) in an isolated snapshot repo and requires each to turn its gate red **bounded and at its claimed `[QK:<claim>]` signature** — a wrong-reason red fails, a baseline-red control voids the whole group, and the runner is negative-controlled on every run (zero-match/multi-match/survived/wrong-reason/hang/control-red/impurity). This measures whether the deterministic gates still *block* what they claim to block; it is **not a new evidence level** (L0–L5 are untouched) and never substitutes for LIVE evidence. Per-cut records cite claim IDs + killed mutant IDs — "N checks passed" alone is not evidence. `check-agy-permission-matrix` complements it with the enumerated permission contract space (literal cells + stated exclusion rules, oracle independent of the SUT). The gate's HEAD is separable and IS in the floor: `check-gate-manifests` runs the runner self-test, validates the committed manifest set against the origin index, and asserts the declared lane inventory, while executing zero COMMITTED mutants (the self-test runs only its synthetic fixture mutants, in tmp fixture repos) and never snapshotting the repo — three of the five reds qualification has ever produced in CI died in that head, in under five seconds.
100
99
  - **The snapshot is source-only (#125).** It replicates the git work surface and never copies an ignored artifact from the checkout. A gate that consumes an ignored build output — the compiled `entwurf-bridge` a pi citizen registers — declares it on each of its mutants (`"build": {"argv": [...], "output": "<dir>"}`, one declaration per gate group). For that group only, the runner builds the output from the snapshot's own bytes before the control, rebuilds it after every mutation and from the restored bytes before the post-control (which must reproduce the baseline digest), never counts a build red as a kill, voids a run whose gate writes into the output, and removes the output when the group ends. The runner self-test owns this as `[QK:QUALIFY-BUILD-*]`.
101
100
  - **Live floor:** `LIVE=1 ./run.sh release-gate <scratch-project-dir> --cut` — `pnpm run check:full` + the v2-native live gates + the ACP plugin acceptance floor. It reports a **two-tier summary**:
102
101
  - **MUST tier** (release-blocking — owns the exit code; "green" applies only here): `pnpm run check:full`, `smoke-entwurf-v2-matrix-live`, `check-bridge`, `doctor-pi-provider` (#81 — `check-bridge` proves the launcher this checkout SHIPS; this proves the invocation the operator's pi provider actually EXECS, by booting it and requiring the entwurf verb set back, because `command -v` answers yes for a command that exits 127; wired as a step on 2026-08-19 after a relocated pnpm cmd-shim cost a cut sixteen LIVE steps before the same fact surfaced at `smoke-acp-bundled-mcp-live`), the resident-garden-guard zero-token half (record birth / record-keyed socket / attach-on-reopen), the `smoke-acp-*-live` ACP plugin smokes (socket-citizen / raw-turn / overlay / provider / session-reuse / carrier-augment / memory-containment / rgg / mcp / skill / bundled-mcp / v2-send), the axis wired in on 2026-07-31 that the aggregate had simply never listed (`smoke-claude-native-resume-live`), `smoke-entwurf-chain-live` — the cross-harness delivery chain (native Claude Code → pi GPT → pi ACP Sonnet → mailbox terminus) proving sender identity and replyability at every hop plus a real read receipt at the end — the integrated `smoke-mux-lifecycle-live` (its own note below), and the two OMP steps 0.16.0 wired: `smoke-omp-receive-live` (the addressed roundtrip into a live omp citizen; it reads the capability registry and decides its own outcome rather than passing by default) and `smoke-omp-fresh-live` (the clause 7 receipt the release stop now requires). (`smoke-session-id-name` is gone — #50 C3: its `--session-id`/`--name` substrate has no entwurf consumer anymore.)
@@ -116,7 +115,7 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
116
115
  >
117
116
  > A cut that touches the prompt-lifecycle contract (no wall clock on a running turn) owes one long-turn acceptance the aggregate floor is too short to carry: `LIVE=1 ./run.sh smoke-acp-long-turn-live` drives a real turn whose tool work outlasts the retired 600s cutoff and requires exactly one cold ACP bootstrap in the transcript. It takes >12 minutes by construction and is on-demand, not part of `release-gate`.
118
117
  >
119
- > **The integrated mux lifecycle IS a release-gate MUST.** `LIVE=1 ./run.sh smoke-mux-lifecycle-live` enters through a real MCP `tools/call` on the shipped bridge launcher and follows one citizen the whole way: fresh-call launch receipt, the sibling's own nonce callback whose SENDER ENVELOPE is the address, an `entwurf_v2` control-socket send that lands in the sibling's own transcript, `entwurf_resume_call` REFUSED while that citizen is live, a stable-handle close proving pane and socket gone with the record preserved, delivery to the dormant citizen refused honestly, then the public `entwurf_resume_call` — whose LAUNCH and OBSERVATION receipts stay apart — and finally an `entwurf_v2` send the resumed session answers with a fact it was told BEFORE the window closed. That last step is the point: a socket answering under the same garden id proves a process stood up at that address, and only the recall proves the same conversation came back. Both pi provider shapes are driven to it (native `openai-codex/gpt-6-luna` and recorded-ACP `entwurf/claude-sonnet-5-5`, the only shape that re-injects a bridge extension), and the Claude Code cell ends where its capability ends: its resume is refused as `target-not-pi` with no window opened and no lock residue (the per-gid coordination lock is released).
118
+ > **The integrated mux lifecycle IS a release-gate MUST.** `LIVE=1 ./run.sh smoke-mux-lifecycle-live` enters through a real MCP `tools/call` on the shipped bridge launcher and follows one citizen the whole way: fresh-call launch receipt, the sibling's own nonce callback whose SENDER ENVELOPE is the address, an `entwurf_v2` control-socket send that lands in the sibling's own transcript, `entwurf_resume_call` REFUSED while that citizen is live, a stable-handle close proving pane and socket gone with the record preserved, delivery to the dormant citizen refused honestly, then the public `entwurf_resume_call` — whose LAUNCH and OBSERVATION receipts stay apart — and finally an `entwurf_v2` send the resumed session answers with a fact it was told BEFORE the window closed. That last step is the point: a socket answering under the same garden id proves a process stood up at that address, and only the recall proves the same conversation came back. Both pi provider shapes are driven to it (native `openai-codex/gpt-6.1-sol:low` and recorded-ACP `entwurf/claude-sonnet-5-5`, the only shape that re-injects a bridge extension), and the Claude Code cell ends where its capability ends: its resume is refused as `target-not-pi` with no window opened and no lock residue (the per-gid coordination lock is released).
120
119
  >
121
120
  > One cell cannot be fully fenced, and that is recorded rather than glossed: the recorded-ACP pi cell runs under the operator's REAL home, because its provider spawns `claude` as a child that authenticates from there — measured, a fenced HOME kills that turn with `Authentication required` before the model is ever reached, and `CLAUDE_CONFIG_DIR` alone does not fix it. That is the same trade `smoke-acp-bundled-mcp-live` already makes. While that cell runs, its citizen's control socket and per-gid lock exist under the operator's own `~/.pi/entwurf-control` and `~/.pi/entwurf-v2-locks`; its meta store stays fixture, so no garden record is minted outside the fixture, and the run ends by proving all six real roots hold the entry sets they started with, with no fixture garden id and no leftover lock.
122
121
  >
@@ -210,16 +209,19 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
210
209
 
211
210
  Do not collapse source, package, fixture, and native-host evidence into one “green.”
212
211
 
213
- **Native durable contact (#129, #130 carrier).** `check-pi-durable-beside` is the deterministic
214
- beside-test/mutant coordinate in `check:contracts`: the adapter, the installed carrier/SDK-set
215
- verifier, the preflight, the owner join, the carrier's relocation grammar, resolver and
216
- maintainer emitter (its `--check` reads only the owned in-repo source, #141; the overlay patch is
217
- retired, and `--origin <clone>` checks provenance only), and the bootstrap's explicit `--native-module` ingress
218
- (#130 P2) with its paired `--native-module-dir` (#134), driven through the packaged `main`'s own
212
+ **Native durable contact (#129, #130 carrier).** Three deterministic beside-test/mutant
213
+ coordinates in `check:contracts` split the durable contact by the file that carries each claim's QK
214
+ (#144): a carrier or native-module mutant runs its one file, the rest run four. `check-pi-durable-beside` holds the adapter, the installed
215
+ carrier/SDK-set verifier, the preflight and the owner join. `check-pi-durable-carrier` holds the
216
+ carrier's relocation grammar, resolver and maintainer emitter (its `--check` reads only the owned
217
+ in-repo source, #141; the overlay patch is retired, and `--origin <clone>` checks provenance only)
218
+ and the task footer and sandboxed children described below. `check-pi-durable-native-module` is the coordinate of
219
+ the bootstrap's explicit `--native-module` ingress
220
+ (#130 P2) with its paired `--native-module-dir` (#134). That ingress is driven through the packaged `main`'s own
219
221
  seams: initialization before the TUI and the open, named refusals, the identity and directory
220
222
  guards, the top-level `*.extension.mjs` filter and byte-wise order, cross-module name refusals, the
221
- contact-first order by reference, and the bridge spawn *spec* (not the child's inheritance). The
222
- carrier's task footer (#134) is observed in ONE sandboxed child that loads the committed carrier
223
+ contact-first order by reference, and the bridge spawn *spec* (not the child's inheritance). In
224
+ `check-pi-durable-carrier`, the carrier's task footer (#134) is observed in ONE sandboxed child that loads the committed carrier
223
225
  through its own resolver: the real carrier runtime opened and closed with no model (graph observed
224
226
  for the session, `/tasks` toggling only the panel), then continued after one native background task
225
227
  was committed into that session through the SDK's public `Conversation.commit` (the carrier's graph
@@ -235,7 +237,7 @@ continuation and the reference compaction policy (no background summary; blockin
235
237
  kept, #143); the other renders the carrier prompt's skills section with no model, against a fixture
236
238
  of both settings scopes, an absolute entry, a same-name pair and a wrong-base decoy.
237
239
  `check-pi-runtime-version` asks the
238
- same verifier whether this checkout resolves exactly the pinned SDK set (the native set; the PATH
240
+ same installed verifier (`check-pi-durable-beside`) whether this checkout resolves exactly the pinned SDK set (the native set; the PATH
239
241
  host is setup's subject), and `check-pi-import-surface` asserts the carrier fence. The separate
240
242
  `check-pi-durable-contact`, `check-pi-durable-send` and `check-pi-durable-receive` are
241
243
  CHECKOUT-ONLY SDK/contact gates: they run the checkout's own carrier — verified first, refused by
@@ -260,7 +262,7 @@ initializing only its top-level `*.extension.mjs` (#134) and a directory without
260
262
  before anything opens — and the HOST kept a separate subject — a real pi 1.1.0
261
263
  binary (the previous generation) beside the pinned native set is a named pi FAIL with zero Pi wiring while pi-durable still
262
264
  PASSes — not native admission. The carrier's rebuild
263
- equality is the owned source's emission (#141): the beside claim `PI-DURABLE-CARRIER-EMIT-SOURCE-EQUAL`
265
+ equality is the owned source's emission (#141): the carrier claim `PI-DURABLE-CARRIER-EMIT-SOURCE-EQUAL`
264
266
  on every floor, `emit-pi-durable-carrier --check` as its CLI. The emitter's exact Node is red in the CI
265
267
  `check` job (`ENTWURF_REQUIRE_EMITTER_NODE=1`) and a named SKIP on a host running another Node, not
266
268
  acceptance there. First-release visible fresh/callback and native
@@ -269,11 +271,11 @@ caller/target/cross-harness LIVE are owed by `smoke-pi-durable-fresh-live`, a re
269
271
 
270
272
  | Axis | Required proof | Limit |
271
273
  |---|---|---|
272
- | Source | `pnpm run check:full` + the prepared SHA's CI `./run.sh check-gate-qualification` step | Does not prove an installed consumer. |
274
+ | Source | `pnpm run check:full` in the prepared SHA's CI `check` job | Does not prove an installed consumer. Kill-power of the committed claims is not re-measured per release (#144); the release record says so and lists any earlier-candidate PARTIAL separately. |
273
275
  | Packed install | `check-pack-install` | Real tarball, but checkout-visible. |
274
276
  | Linux artifact consumer | required `check-install-container` CI job against one preserved candidate | Fixtures prove package/oracle shape, not a real Claude lifecycle. |
275
- | Exact release commit | all required CI jobs green, and the `check` job's qualification body step concluded success, at the exact SHA | A different green SHA is not transferable evidence. |
276
- | macOS Entwurf-only install | required `macos-install-surface` CI job at the exact release SHA | Shape-only, CERTIFIED (CI): certifies the Entwurf-only install path on macOS only — never Claude/Copilot/OMP/agy wiring, the pi rail, ACP or mux. Promoted from non-voting (`continue-on-error`) to required in 0.20.0 after its first CERTIFIED (CI) green on a GitHub Actions `macos-latest` runner (not a physical host): run 34303884286 @ `70eda03` (2026-09-09), 65s, all 10 steps success — the packed candidate installed clean, `entwurf --help` and `entwurf check-bridge` ran (the latter listing the seven current `entwurf-bridge` MCP tools), an all-harness-absent `entwurf setup` reached `result: green` across the five documented SKIP probes (`pi`/`claude`/`agy`/`copilot`/`omp`), and five checked paths (`.pi`, `settings.json`, `.gemini`, `.copilot`, `auth.json.bak`) plus a byte-identical `auth.json` proved zero harness/credential writes. A macOS runner failure now blocks every release cut, the same as any other required job. |
277
+ | Exact release commit | the exact SHA's push run: all four required CI jobs green (the qualification body is not read, #144) | A different green SHA is not transferable evidence. |
278
+ | macOS Entwurf-only install | required `macos-install-surface` CI job at the exact release SHA | Shape-only, CERTIFIED (CI): certifies the Entwurf-only install path on macOS only — never Claude/Copilot/OMP/agy wiring, the pi rail, ACP or mux. Promoted from non-voting (`continue-on-error`) to required in 0.20.0 after its first CERTIFIED (CI) green on a GitHub Actions `macos-latest` runner (not a physical host): run 34303884286 @ `70eda03` (2026-09-09), 65s, all 10 steps success — the packed candidate installed clean, `entwurf --help` and `entwurf check-bridge` ran (the latter listing the seven `entwurf-bridge` MCP tools of that date; eight today), an all-harness-absent `entwurf setup` reached `result: green` across the five documented SKIP probes (`pi`/`claude`/`agy`/`copilot`/`omp`), and five checked paths (`.pi`, `settings.json`, `.gemini`, `.copilot`, `auth.json.bak`) plus a byte-identical `auth.json` proved zero harness/credential writes. A macOS runner failure now blocks every release cut, the same as any other required job. |
277
279
  | LIVE runtime | `LIVE=1 ./run.sh release-gate <scratch> --cut` plus any shipped on-demand backend axis | `--cut` enforces `SKIP=0`; a red wired gate blocks the cut. |
278
280
  | Native Claude host | installed strict doctor against a new real session | Missing live join is `NOT CERTIFIED`, not a fixture PASS. |
279
281
  | Native agy host | three doctors plus conversation-id-gated native-push round trip | Aggregate release-gate does not own an agy conversation id. |
@@ -357,7 +359,7 @@ The goal is not merely "invoke Claude Code." We want:
357
359
  **One install command to remember: `./run.sh setup <project>`.** It is idempotent — re-run the exact same command whenever anything looks wrong. There is no second install surface to juggle: from a clone `setup` runs the whole floor in order.
358
360
 
359
361
  1. `pnpm install` — installs the pinned development dependencies and builds the bridge (source-checkout bootstrap only; an installed package never runs npm/pnpm inside `node_modules`)
360
- 2. pi wiring → `<project>/.pi/settings.json` + user-scope registration — only when a `pi` inside the supported range (`>=1.2.0 <1.3`) is on PATH; absent pi is an explicit zero-state SKIP, a below-floor pi is a detected FAIL. The user-scope entry is owner-recorded (#86 C2): another root's live-or-missing ownership makes this step a zero-write refusal (setup: pi FAIL) that names `takeover-user-scope`; the install-states bind the exact managed settings path (a drifted/symlinked/corrupt target is a zero-write refusal) and the inverse removes only the recorded owner's exact entry; `doctor-pi-package` reports the verdict
362
+ 2. pi wiring → `<project>/.pi/settings.json` + user-scope registration — only when a `pi` inside the supported range (`>=1.3.0 <1.4`) is on PATH; absent pi is an explicit zero-state SKIP, a below-floor pi is a detected FAIL. The user-scope entry is owner-recorded (#86 C2): another root's live-or-missing ownership makes this step a zero-write refusal (setup: pi FAIL) that names `takeover-user-scope`; the install-states bind the exact managed settings path (a drifted/symlinked/corrupt target is a zero-write refusal) and the inverse removes only the recorded owner's exact entry; `doctor-pi-package` reports the verdict
361
363
  3. Claude meta-bridge global plugin — only when `claude` is on PATH; otherwise skipped cleanly
362
364
  4. source stable-bin exposure — including certified `entwurf` → this checkout's `run.sh`, the managed runtime Copilot fresh resolves; helper units are attempted independently and a foreign helper is a named FAIL
363
365
  5. agy bridge + exact permission + statusline + `PreInvocation` hook — only when `agy` is on PATH; each adapter is idempotent and independently doctorable
@@ -515,7 +517,7 @@ Pass: user/assistant turns accumulate normally; the transcript is not broken/emp
515
517
 
516
518
  The minimum passing bar:
517
519
 
518
- 1. **Deterministic floor green:** `pnpm run check:full` passes (the core tier plus the hermetic-integration and package/install tiers, incl. `check-pack`), plus the `./run.sh check-gate-qualification` step green in the exact-SHA CI run of the same prepared candidate (criterion 2's run).
520
+ 1. **Deterministic floor green:** `pnpm run check:full` passes (the core tier plus the hermetic-integration and package/install tiers, incl. `check-pack`), in the exact-SHA CI push run of the same prepared candidate (criterion 2's run). The qualification body is not a criterion (#144).
519
521
  2. **All four required CI jobs green on the exact release commit:** `check`, `install-surface`, the required Linux `artifact-consumer`, and `macos-install-surface` — promoted from non-voting to required in 0.20.0 (see the release acceptance axes table above for what its green run does and does not certify); preserve the Linux artifact-consumer's tarball digest and image identity. A macOS runner failure now blocks the cut like any other required job.
520
522
  3. **Live floor MUST green:** `LIVE=1 ./run.sh release-gate <dir> --cut` exits 0 reporting `MUST PASS=N FAIL=0 SKIP=0`; with `--cut` a single SKIP is red, so the exit code itself now carries this condition. A BEHAVIOR FAIL is advisory, not blocking.
521
523
  4. **Native-host doctor green where the Claude meta-bridge is claimed:** a new post-install Claude session exists, live evidence is present, and the installed `doctor-meta-bridge` exits 0. `NOT CERTIFIED` is a release failure for that host, not a skip.
package/demo/README.md CHANGED
@@ -24,7 +24,7 @@ takes/helpers/tests are maintainer tooling and are deliberately excluded from th
24
24
 
25
25
  - Node at the `package.json#engines.node` floor; the checkout's pinned dependencies and
26
26
  current compiled bridge. After a source/bootstrap change, build with `pnpm run build-bridge`.
27
- - Pi at the checkout's supported floor (**current floor 1.2.0**); `entwurf` on PATH must be
27
+ - Pi at the checkout's supported floor (**current floor 1.3.0**); `entwurf` on PATH must be
28
28
  the intended source stable-bin. Source evidence is not registry-package acceptance.
29
29
  - `herdr` on PATH at exactly `scripts/fixtures/herdr-supply.json#version`; `asciinema` v3.
30
30
  - Herdr's existing Pi integration at
@@ -125,18 +125,19 @@ What "supported" means here, per declaration class. The classes are kept apart o
125
125
  undifferentiated "supported" column is what let a Claude PASS read as if it also certified Cortex.
126
126
  The rows are THIS checkout's declarations, not a shipped release: what a published version carried
127
127
  is that version's CHANGELOG entry, and a candidate's own evidence is its issue thread, LIVE receipts
128
- and exact-SHA CI. The pi row shipped in 0.30.0 (#125). The ACP wire SDK, Claude adapter and Claude
129
- Agent SDK rows are the unpublished #127 candidate: published 0.30.0 still declares
130
- `claude-agent-acp 0.79.0` and `@agentclientprotocol/sdk 1.4.0`
131
- (`[측정 2026-10-04]` `npm view @junghanacs/entwurf@0.30.0`; per-bump record in the ROADMAP Dep bump
132
- ledger, 2026-10-03).
128
+ and exact-SHA CI. The pi row shipped in 0.30.0 (#125). The ACP wire SDK and Claude adapter rows
129
+ equal the published 0.36.1–0.37.1 manifests (`claude-agent-acp 0.90.0`, `@agentclientprotocol/sdk
130
+ 1.8.0`); 0.31.0–0.36.0 shipped `0.85.1` / `1.6.0` and 0.30.0 shipped `0.79.0` / `1.4.0`
131
+ (`[측정 2026-10-16]` `git show <tag>:package.json`). The transitive Claude Agent SDK `0.3.296`
132
+ row has no direct manifest entry; its bump is recorded in CHANGELOG 0.36.1 (#128) and the ROADMAP
133
+ Dep bump ledger. 0.38.0 (#145) changes only the pi SDK set; the ACP rows are unchanged from 0.37.1.
133
134
 
134
135
  | Surface | Declaration | Class | What a green actually says |
135
136
  |---|---|---|---|
136
137
  | Entwurf package | `package.json` `version` | checkout declaration, not a release receipt | names the package label these rows sit beside; whether that label shipped, and with which rows, is CHANGELOG's record |
137
- | pi runtime | SDK exact `1.2.0`, host `>=1.2.0 <1.3` | **exact** oracle + **closed range** | the SDK set this checkout builds, gates and (since #130) ships as exact production dependencies; an ordinary Pi host inside the range is accepted, and the ceiling moves only on measurement. The published 0.36.0 ships this 1.2.0 set (#141). Historical: the published 0.33.0 through 0.35.1 ship SDK exact 1.1.0, 0.32.0 ships SDK exact 1.0.4 with the next-minor ceiling (ROADMAP's 2026-10-07 bump entry), and 0.31.0 declared the earlier peer floor 1.0.2 |
138
+ | pi runtime | SDK exact `1.3.0`, host `>=1.3.0 <1.4` | **exact** oracle + **closed range** | the SDK set this checkout builds, gates and (since #130) ships as exact production dependencies; an ordinary Pi host inside the range is accepted, and the ceiling moves only on measurement. The published 0.36.0 through 0.37.1 shipped the 1.2.0 set (#141); 0.38.0 (#145) is the first to carry 1.3.0. Historical: the published 0.33.0 through 0.35.1 ship SDK exact 1.1.0, 0.32.0 ships SDK exact 1.0.4 with the next-minor ceiling (ROADMAP's 2026-10-07 bump entry), and 0.31.0 declared the earlier peer floor 1.0.2 |
138
139
  | ACP wire SDK | `@agentclientprotocol/sdk 1.8.0` | **exact** | the shared wire oracle both adapters speak |
139
- | Claude ACP adapter | `@agentclientprotocol/claude-agent-acp 0.90.0` | **exact**, bundled | checkout candidate; resolved before any PATH fallback; declaration is not compatibility evidence |
140
+ | Claude ACP adapter | `@agentclientprotocol/claude-agent-acp 0.90.0` | **exact**, bundled | shipped since 0.36.1; resolved before any PATH fallback; declaration is not compatibility evidence |
140
141
  | Claude Agent SDK | `0.3.296` (transitive) | **exact** oracle | the runtime risk surface behind the adapter |
141
142
  | Anthropic SDK | `0.100.1` | **exact**, peer-resolution only | satisfies the Agent SDK peer floor (0.93.0+); never an API client here (gate L4) |
142
143
  | Claude Code runtime | `>=2.1.217` (`entwurf.claudeCodeFloor`) | **floor** | below it, hook args are silently dropped; entwurf enforces this itself |
@@ -622,9 +623,13 @@ pnpm run check:full
622
623
  ./run.sh check-acp-session-reuse
623
624
  ./run.sh check-acp-stop-reason
624
625
  ./run.sh check-acp-cortex
625
- ./run.sh check-gate-qualification
626
626
  ```
627
627
 
628
+ The whole `check-gate-qualification` body is not part of this floor: it is a scheduled drift
629
+ diagnostic only (weekly CI or a manual `qualify=true` dispatch, never a release axis, #144). A
630
+ change to a gate, mutant or matrix runs its affected exact-argv groups as PARTIAL receipts
631
+ (VERIFY.md).
632
+
628
633
  Live axes:
629
634
 
630
635
  ```bash
@@ -273,7 +273,7 @@ top-level (`Tool web_search not found`, upstream #5973), fixed by pinning it via
273
273
 
274
274
  `read xd://` reports exactly what the default hides. `[측정]` on a host with only this
275
275
  bridge registered, **11 devices**: omp's own `ast_edit`, `debug`, `lsp`, `browser`, plus all
276
- seven `entwurf_*`. So the default does not merely wrap entwurf — it wraps omp's own LSP and
276
+ seven `entwurf_*` (as reported in that earlier measurement; the current bridge declares eight). So the default does not merely wrap entwurf — it wraps omp's own LSP and
277
277
  debugger too.
278
278
 
279
279
  **`entwurf setup` writes this for a detected omp host, and `entwurf install-omp-config` is