@junghanacs/entwurf 0.35.0 → 0.36.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 (91) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +338 -0
  3. package/CONTRIBUTING.md +1 -1
  4. package/DELIVERY.md +15 -0
  5. package/FAQ.md +3 -3
  6. package/README.md +30 -16
  7. package/VERIFY.md +14 -11
  8. package/demo/README.md +1 -1
  9. package/docs/acp-backend-rail.md +29 -3
  10. package/docs/setup-clean-host.md +31 -23
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +46 -2
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/model-ids.js +67 -0
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +9 -20
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/codex-fresh-preflight.js +4 -3
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +11 -0
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-dispatch.js +27 -1
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/herdr-fresh-call.js +3 -0
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +2 -0
  19. package/mcp/entwurf-bridge/dist/pi-extensions/lib/native-push/codex-ws-client.js +99 -18
  20. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-runtime.js +3 -3
  21. package/mcp/entwurf-bridge/dist/pi-extensions/lib/resume-launch-identity.js +13 -4
  22. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +178 -25
  23. package/mcp/entwurf-bridge/dist/scripts/codex-socket-classify.js +44 -0
  24. package/mcp/entwurf-bridge/tsconfig.build.json +5 -0
  25. package/package.json +20 -15
  26. package/pi/pi-durable/bootstrap.mjs +12 -8
  27. package/pi/pi-durable/carrier/runtime.js +52 -2
  28. package/pi/pi-durable/carrier/subagent.js +6 -1
  29. package/pi/pi-durable/carrier/tui.js +31 -4
  30. package/pi/pi-durable/carrier-relocation.mjs +2 -2
  31. package/pi/pi-durable/overlay/upstream-pin.json +79 -36
  32. package/pi-extensions/lib/acp/backend-adapter.ts +52 -2
  33. package/pi-extensions/lib/acp/model-ids.js +77 -0
  34. package/pi-extensions/lib/acp/models.ts +15 -22
  35. package/pi-extensions/lib/codex-fresh-preflight.ts +4 -3
  36. package/pi-extensions/lib/entwurf-v2-visible-resume.ts +12 -0
  37. package/pi-extensions/lib/fresh-call-dispatch.ts +25 -1
  38. package/pi-extensions/lib/herdr-fresh-call.ts +5 -0
  39. package/pi-extensions/lib/mux-fresh-call.ts +3 -0
  40. package/pi-extensions/lib/native-push/codex-ws-client.ts +129 -18
  41. package/pi-extensions/lib/pi-durable-runtime.ts +4 -4
  42. package/pi-extensions/lib/resume-launch-identity.ts +12 -4
  43. package/pi-extensions/meta-bridge-pi-durable.ts +230 -34
  44. package/run.sh +193 -58
  45. package/scripts/check-acp-backend-preflight.ts +10 -2
  46. package/scripts/check-acp-cortex.ts +7 -6
  47. package/scripts/check-acp-prompt-lifecycle.ts +2 -2
  48. package/scripts/check-acp-provider-surface.ts +1 -1
  49. package/scripts/check-acp-session-reuse.ts +5 -5
  50. package/scripts/check-acp-stop-reason.ts +2 -2
  51. package/scripts/check-acp-stream-hooks.ts +2 -2
  52. package/scripts/check-acp-usage-accounting.ts +2 -2
  53. package/scripts/check-codex-app-server-launch.ts +55 -12
  54. package/scripts/check-codex-native-push.ts +231 -12
  55. package/scripts/check-fresh-call-dispatch.ts +47 -4
  56. package/scripts/check-gate-qualification.ts +8 -6
  57. package/scripts/check-probe-ordering.ts +13 -6
  58. package/scripts/check-resume-launch-identity.ts +38 -0
  59. package/scripts/codex-app-server-launch.sh +54 -29
  60. package/scripts/codex-socket-classify.ts +46 -0
  61. package/scripts/emit-pi-durable-carrier.ts +159 -168
  62. package/scripts/mutants/acp-cortex.json +17 -8
  63. package/scripts/mutants/acp-set-model-readback.json +28 -0
  64. package/scripts/mutants/codex-app-server-launch.json +39 -12
  65. package/scripts/mutants/codex-native.json +15 -0
  66. package/scripts/mutants/control-send-receipt.json +1 -1
  67. package/scripts/mutants/fresh-call-dispatch.json +11 -0
  68. package/scripts/mutants/herdr-dev-checkout.json +70 -0
  69. package/scripts/mutants/pack-install.json +3 -3
  70. package/scripts/mutants/pi-durable.json +282 -16
  71. package/scripts/mutants/pi-floor.json +5 -5
  72. package/scripts/mutants/resume-launch-identity.json +15 -0
  73. package/scripts/mutants/v2-visible-resume.json +11 -0
  74. package/scripts/pi-durable-contact-host.mjs +1 -1
  75. package/scripts/resolve-acp-bridge.ts +1 -1
  76. package/scripts/smoke-acp-bundled-mcp-live.ts +1 -1
  77. package/scripts/smoke-acp-carrier-augment-live.ts +1 -1
  78. package/scripts/smoke-acp-long-turn-live.ts +1 -1
  79. package/scripts/smoke-acp-mcp-live.ts +1 -1
  80. package/scripts/smoke-acp-memory-containment-live.ts +1 -1
  81. package/scripts/smoke-acp-ordering-probe-live.ts +1 -1
  82. package/scripts/smoke-acp-overlay-live.ts +1 -1
  83. package/scripts/smoke-acp-provider-live.ts +1 -1
  84. package/scripts/smoke-acp-raw-turn-live.ts +1 -1
  85. package/scripts/smoke-acp-session-reuse-live.ts +1 -1
  86. package/scripts/smoke-acp-skill-live.ts +1 -1
  87. package/scripts/smoke-acp-socket-citizen-live.ts +2 -2
  88. package/scripts/smoke-acp-v2-send-live.ts +1 -1
  89. package/scripts/smoke-entwurf-chain-live.ts +1 -1
  90. package/scripts/smoke-mux-lifecycle-live.ts +1 -1
  91. package/pi/pi-durable/overlay/runtime-contacts.patch +0 -283
package/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # AGENTS.md — Maintainer Guidelines for entwurf
2
2
 
3
- For agents who own this repository: durable invariants and the documents that own the changing evidence. This is the **entwurf capability package**: garden-citizen dispatch substrate, native-harness bridges, ACP plugin, and pi adapter. Entwurf is the subject; pi is one adapter. ACP is a plugin, not the boundary. V2 addresses existing citizens; `entwurf_fresh_call` creates a new sibling.
3
+ For agents who own this repository: durable invariants and the documents that own the changing evidence. This is the **entwurf capability package**: visible sibling lifecycle and garden-id delivery — the v2 dispatch core, native-harness bridges, ACP plugin, and pi adapter. Entwurf is the subject; pi is one adapter. ACP is a plugin, not the boundary. V2 addresses existing citizens; `entwurf_fresh_call` creates a new sibling.
4
4
 
5
5
  ## North Star — One Forged Screwdriver
6
6
 
@@ -42,7 +42,7 @@ Ask: does this follow capability rather than a surface name; record backend asym
42
42
  14. **Native-hook ownership is structural.** Use shipped exec launchers and provenance, shared plausible-owner-pid policy, no shell fallback or ancestry guess. Version floors belong to their package source and are enforced there; hook contract/docs own the changing detail.
43
43
  15. **Crash, don’t warn.** Invalid config/path/model/store state throws. Empty catches are only bounded environment probes; diagnostics go to stderr.
44
44
  16. **mux launches, never delivers.** A tmux handle is an ephemeral view, not an address or liveness receipt; screen text/keystrokes are not delivery evidence. A Codex caller's seat is the pane whose title carries its own thread-id, a placement input only; it is never an address, and never a pane nobody named. Cross-window adjacency requires the documented observed-coordinate proof, never pane guessing.
45
- 17. **Supply the missing surface; do not become the harness.** Installation supplies Entwurf bytes, development fixtures, and declared upstream SDK dependencies. Where upstream omits a native execution surface from its distribution, Entwurf may carry that pinned, removable app/TUI with its declared overlay and deterministic emit/import relocation, against one coherent published-library version set. Native execution, auth, queues, storage, transcript and recovery remain upstream-owned (Rule 9). Provenance, license, rebuild and installed-consumer proof belong to the supply contract. No Entwurf-owned copying/inlining of provider model catalogs, subscription, credential or login; no launch-time download, repair, update or fallback. Setup checks capability, version-set coherence and carrier integrity: absent optional capability is explicit skip; incomplete installation, mismatch and drift are named non-green refusals. Portability and runtime evidence remain separate.
45
+ 17. **Supply the missing surface; do not become the harness.** Installation supplies Entwurf bytes, development fixtures, and declared upstream SDK dependencies. Where upstream omits a native execution surface from its distribution, Entwurf owns that thin, removable app/TUI composition as canonical source and ships its deterministic emission (type strip + import relocation) as a carrier, against one coherent published-library version set. The engine — native execution, auth, queues, storage, transcript, compaction, cancellation and recovery — remains the upstream SDK (Rule 9). Provenance, license, rebuild and installed-consumer proof belong to the supply contract. No Entwurf-owned copying/inlining of provider model catalogs, subscription, credential or login; no launch-time download, repair, update or fallback. Setup checks capability, version-set coherence and carrier integrity: absent optional capability is explicit skip; incomplete installation, mismatch and drift are named non-green refusals. Portability and runtime evidence remain separate.
46
46
 
47
47
  History and incident detail belong in [CHANGELOG.md](./CHANGELOG.md), issue threads, [BASELINE.md](./BASELINE.md), or source-adjacent comments. When prose and behavior disagree, repair the owning source or document.
48
48
 
package/CHANGELOG.md CHANGED
@@ -4,6 +4,344 @@ All notable changes to this project will be documented here. Format follows [Kee
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.36.0 - 2026-10-13
8
+
9
+ ### pi-durable
10
+
11
+ - **The thin app/TUI composition is Entwurf-owned source (#141).** The six carrier files
12
+ are emitted from `pi/pi-durable/src/experimental/durable/*.ts` (with `src/LICENSE`), which
13
+ folds in the retired `runtime-contacts.patch`, and run on the 1.2.0 SDK set (below). Net
14
+ against 0.35.1, three carrier files change: `runtime.js` `60c2965e…118403`, `tui.js`
15
+ `0f9ebaf8…b3abc5` and `subagent.js` `1cb2390b…a64220`. `harness-setup.js`, `prompt.js`,
16
+ `sessions.js` and LICENSE keep their 0.35.1 bytes. The source checkpoint `86d4b65` left the
17
+ package version at 0.35.1; this release sets 0.36.0. The first step (S0) moved ownership
18
+ alone: no carrier byte, no LICENSE and no SDK version (then 1.1.0) changed, only the pin's
19
+ carrier source blob ids. The upstream SDK still owns
20
+ execution, auth, queues, storage/transcript, compaction, cancellation and recovery (Rule 17).
21
+ - **Pin schema 3.** `pi/pi-durable/overlay/upstream-pin.json` keeps its path and the shapes
22
+ installed readers use. A frozen `origin` holds the upstream commit, its recorded blobs, the
23
+ retired patch's digest and the 0.35.1 carrier digests. Only `carrier` is generated.
24
+ - **Emitter.** `scripts/emit-pi-durable-carrier.ts --check` reads only in-repo source, and a
25
+ missing file is a named refusal. A host running a different Node gets the byte proof plus a
26
+ named emitter-identity SKIP, not a PASS. `--write` names every generated field it changes.
27
+ `--origin <clone>` checks provenance only. The CI `check` job runs the pinned emitter Node
28
+ exactly, with `ENTWURF_REQUIRE_EMITTER_NODE=1`; other jobs float the major.
29
+ - **Typecheck fence.** `pi/pi-durable/tsconfig.json` is the fourth `pnpm typecheck` program:
30
+ strict, `erasableSyntaxOnly` / `verbatimModuleSyntax`, and `rootDirs` onto the installed
31
+ `pi-coding-agent/dist`, so internals are typed by their published declarations. Its explicit
32
+ empty `exclude` receives what the root program excludes. The exact devDependency
33
+ `@types/proper-lockfile@4.1.4` supplies the one missing declaration.
34
+ - **Formatting.** The owned source uses upstream width (indentWidth 3), with no per-file
35
+ exception. Formatting `tui.ts` wrapped its one Entwurf-written dock line and added one trailing
36
+ comma, so `tui.js` was re-emitted (sha256 `63600d4b…095b`, the S1-B1 intermediate; the S1-B3
37
+ changes below produce the current `0f9ebaf8…b3abc5`). A parser-derived token/AST
38
+ comparison found nothing else changed. The `PI-DURABLE-FOOTER-BADGE-PROTECTED` mutant follows
39
+ the wrapped line and plants the same fault.
40
+ - **Proof.** New claims: `PI-DURABLE-CARRIER-EMIT-SOURCE-EQUAL`, `-EMIT-NODE-EXACT`,
41
+ `PI-DURABLE-SOURCE-FENCE-RESOLVES`, `PI-DURABLE-SOURCE-NOT-SHIPPED` (the source, the fence and the
42
+ retired patch stay out of the JS-only tarball; proved on npm's own file list with
43
+ `--ignore-scripts` beside the carrier, while check-pack keeps the same tripwire on the floor), and
44
+ `PI-DURABLE-EMITTER-NODE-CI-BOUND` / `-CI-REQUIRED`. These two read the check job's active
45
+ setup-node input and its actual `check:full` step env, never comment text or another step.
46
+ Retired with the patch: `PI-DURABLE-CARRIER-PATCH-SECTIONS`.
47
+ - **SDK set 1.2.0 (#141 S1-B2).** The nine published `@earendil-works/*` production dependencies
48
+ move from 1.1.0 to 1.2.0, with the pin's `sdk.members`, the install constellation, the pin-leak
49
+ matcher and the declared ranges (`>=1.2.0 <1.3`). `pi-client` and `pi-protocol` leave the set (not
50
+ published at 1.2.0); the only new third-party package is `@silvia-odwyer/photon@0.3.3`.
51
+ - **1.2.0 tool output (#141 S1-B3).** On the 1.2.0 SDK set a native durable tool result's model
52
+ channel is `output`, which the SDK renamed from 1.1's `content`. When a result omits `output`, the
53
+ model gets the text the tool retained through `api.output()`. `content` is not read, so a result
54
+ naming only `content` that retained no output reaches the model as nothing. The subagent tool (now
55
+ `satisfies ToolExecutionResult`), the contact's bridge tools and the synthetic native-module
56
+ fixture retain none, so they answer in `output`. The ordinary Pi
57
+ `ToolExecutionComponent.updateResult` and `InputSubmissionDraft` keep `content`.
58
+ - **Fatal session.** The carrier runtime takes the Session's own close listener and the report that
59
+ follows it: a session that failed and closed itself is on screen at once (`Session failed: <cause>.
60
+ It takes no more input, and a tool still running may take a while to stop. Close this session,
61
+ then reopen it with --continue.`) and input to it is refused by name, without waiting for
62
+ `closed`, which a tool ignoring its abort can hold off. A normal `close()` unsubscribes first and
63
+ is no failure. A failure listener subscribed after the failure is told at once, once. On that
64
+ signal the contact retires its receiver as `session-failed` before the next doorbell — also when
65
+ the session had already failed before the contact attached, so no receiver marker is left behind;
66
+ a normal close still retires it as `closed`, and a cleanup failure is thrown, not swallowed.
67
+ - **Compaction failure.** The TUI draws the conversation's retained `pi.live.compactionFailure`
68
+ (`Compaction failed (<reason>): <error>`) for as long as the SDK keeps it. A failed background
69
+ compaction the SDK starts on its own (`threshold`) had no other report; the manual one keeps its
70
+ existing notice beside the line.
71
+ - **Proof (S1-B3).** New claims `PI-DURABLE-SUBAGENT-OUTPUT-MODEL-VISIBLE`,
72
+ `-BRIDGE-TOOL-OUTPUT-MODEL-VISIBLE`, `-FATAL-SESSION-VIEW`, `-FATAL-SESSION-SHOWN`,
73
+ `-FATAL-SUBMIT-REFUSED`, `-RECEIVER-RETIRE-ON-FATAL`, `-SELF-CLOSE-NOT-FAILURE` and
74
+ `-COMPACTION-FAILURE-SHOWN` run the real bootstrap and carrier on the published 1.2.0 SDK with a
75
+ faux model and an injected storage failure; each mutant plants its fault in the generated carrier
76
+ or the bridge source.
77
+
78
+ ### Codex
79
+
80
+ - **The 0.162.1 control endpoint is accepted as its exact alias (#141).** Codex 0.162.1 binds its
81
+ 0600 control socket under `realpath(/tmp)/codex-daemon-<euid>/`, named by the sha256 of the
82
+ canonical advertised path, and makes the advertised path a symlink to it. One classifier,
83
+ `checkCodexSocketFile`, accepts a plain socket or exactly that alias (link owner, byte-equal
84
+ target, a 0700 socket directory owned by the same euid, a socket no other user can open) and
85
+ refuses every other symlink. The delivery probe, `codex queue --remote` and the fresh-call
86
+ preflight connect to the socket it verified. The managed launcher runs the same classifier's
87
+ compiled twin (`mcp/entwurf-bridge/dist/scripts/codex-socket-classify.js`) and keeps no copy of
88
+ its own: a missing twin is an incomplete installation, refused as
89
+ `codex-app-server-classifier-missing` (reinstall the package, or run `pnpm run build-bridge` in
90
+ a source checkout), and an answer it does not recognise is refused by name. This is measured
91
+ on the 0.162.1 layout only and promises nothing about a later Codex. The plain-socket layout is
92
+ kept; its native acceptance remains the dated 0.153.4 record, not a claim about every older or
93
+ newer version.
94
+ - **Stated limits.** The launcher reports a dangling exact alias as the dead leftover the vendor
95
+ removes on start and launches over it, but its alias and dangling-alias paths have no LIVE
96
+ observation; they are proven on the classifier in a sandbox. The birth hook's thread naming,
97
+ the fresh Codex TUI's `--remote` endpoint and the fresh-call smoke's thread reads still hand the
98
+ advertised path to a connect without classifying it. Those connections worked in the named
99
+ diagnostic on this host; they remain unclassified. That is recorded as an Observation: not
100
+ every Codex connection goes through the classifier. A same-euid process can still replace the
101
+ verified socket file; that residual is named, not locked.
102
+
103
+ ### Docs
104
+
105
+ - **Open, reopen and message lead the one-line surfaces.** The README, FAQ, CONTRIBUTING,
106
+ AGENTS, the Herdr plugin README and manifest description, and the package description and
107
+ keywords name the three verbs and where each lands, instead of describing Entwurf as
108
+ garden-id messaging alone. The README gains an open/reopen/message table with each verb's
109
+ harness scope. FAQ's tmux list includes pi-durable again, and CONTRIBUTING no longer calls
110
+ the shipped Codex native-push citizen an unreleased candidate.
111
+
112
+ ### Release boundary and verification
113
+
114
+ - **Review.** The source checkpoint `86d4b65` and its amendment `d1c9103` were reviewed by
115
+ the #141 coordinator, Fable advisory reviews (no Blocker; their Defects were fixed before
116
+ the checkpoint) and a read-only Grok review of `86d4b65`. Grok's eight documentation and
117
+ live-authority findings were closed in `d1c9103`, and its recheck found no new Defect. The
118
+ Codex fix `90fa8bb` follows a coordinator-approved design with a read-only Grok design
119
+ review; a Fable advisory review of its pre-commit bytes found no Blocker, and its one Defect,
120
+ the missing Codex entry above, is closed in this section.
121
+ - **Local evidence before this preparation is focused, not a whole pass.** Each affected
122
+ qualification wave (PARTIAL) measured its own candidate and none is carried to another. S0
123
+ killed 70/70 in two groups; 891 of its 961 committed claims were not run. The S1-B3 source
124
+ bytes killed 82/82 in three groups (dep-versions 4, pin-matcher 2, pi-durable beside 76), each
125
+ with a green control; 887 of the 969 committed claims were not run there, nor was the
126
+ node-floor coherence group. The Codex fix bytes, verified content-identical to `90fa8bb`,
127
+ killed 219/219 in six groups (app-server launch 10, native push 8, admission parity 2,
128
+ attribution self-test 1, gate manifests 52, mux fresh call 146), each with a green control;
129
+ 752 of the 971 committed claims were not run. An earlier wave over that fix stopped at its
130
+ first group with 9 killed and one WRONG-REASON; it is kept as it was, not relabelled. The
131
+ vitest results cache drifting outside the dependency seal and one socket fixture temp root
132
+ observed during the native-push group are recorded, not waived. A fresh Entwurf-only npm
133
+ consumer of the `86d4b65` source bytes (packed with 0.35.1 metadata) proved graph and load
134
+ only: nine SDK members at 1.2.0, 24/24 carrier dist targets inside the consumer, and the
135
+ public launch reaching the SDK's own model refusal before any birth. A store migrated by a
136
+ 1.2.0 run and reopened on 1.1.0 kept its version-2 tool task blocked as `task_too_old`: a
137
+ one-time fixture receipt, not a supported downgrade.
138
+ - **Codex 0.162.1 diagnostic is not a cut.** On the pre-amendment candidate, one Linux
139
+ `smoke-codex-fresh-live` diagnostic against a live 0.162.1 app-server passed 65 assertions,
140
+ native push included, with `gpt-5.6-sol` on the Codex side and `openai-codex/gpt-6.1-sol` for
141
+ the Pi sibling only. It is not release-gate acceptance and covers no other model. The earlier
142
+ local FULL and LIVE `--cut` were taken on the pre-fix candidate (the cut was BLOCKED when the
143
+ advertised alias was refused) and are not evidence for this one. The frozen FULL and the final
144
+ LIVE `--cut` passed on this candidate (below); the installed-consumer proof
145
+ (`check-pack-install`, run by the CI `install-surface` job, not by `check:full`) and the
146
+ prepared SHA's CI body are pending.
147
+ - **Final frozen floor on this candidate.** One frozen tree, HEAD `90fa8bb` plus this release's
148
+ metadata, with the same work-surface fingerprint before and after both runs.
149
+ `pnpm run check:full` passed once (817 s, exit 0; 599 files in the dry-run pack).
150
+ `LIVE=1 ./run.sh release-gate <scratch> --cut` passed once: **MUST PASS=24 FAIL=0 SKIP=0**,
151
+ **BEHAVIOR PASS=1 FAIL=0 SKIP=0**, `cut: OK`. Its own static FULL (814 s) means this floor ran
152
+ FULL twice. The Codex step named the operator-owned 0.162.1 app-server by pid (851181) with
153
+ `gpt-5.6-sol` on the Codex side and `openai-codex/gpt-6.1-sol` for the Pi siblings, and passed
154
+ 65 assertions, native push included; it attaches to an existing server, so the managed
155
+ launcher's alias and dangling-alias paths remain unobserved. Scratch
156
+ `/tmp/entwurf-release-gate-0.36.0.lw5Xju`, log SHA-256
157
+ `17a2bd54efaaeba2899bf9bbd3c13c0e68749d9d03367347c4872d6f4126ad30`; FULL log SHA-256
158
+ `184ea443326a72858d25b70ba25b44e804307205586d8a03d4af7c5b07ee1288`. A read-only host census
159
+ afterwards found one `entwurf-chain-*` and one `smoke-pi-durable-fresh-live-*` root from this
160
+ run, the same per-run residue earlier LIVE runs left; it is recorded and was not cleaned. This
161
+ is local acceptance only: not the exact CI, not a whole qualification pass.
162
+ - **Exact CI pending.** The prepared SHA's exact CI (the four required jobs and the
163
+ qualification body) is the next checkpoint and is not presumed PASS.
164
+ - **Unpublished candidate carrier.** As in 0.35.1, `plugins/herdr/runtime-lock.json`
165
+ temporarily names the closed `herdr-checkout` source: an npm-source lock must agree with
166
+ the checkout's core version, and 0.36.0 has no published integrity yet. The Herdr
167
+ manifest stays 0.35.1. After the operator publishes core 0.36.0, a separate Herdr snapshot
168
+ re-pins the measured registry bytes.
169
+ - **Publication boundary.** No make artifact, core tag, GitHub Release or npm publication
170
+ is claimed; they wait for the exact CI, the make decision and the operator.
171
+
172
+ ## v2026.10.13-herdr.0.35.1 — Herdr Entwurf plugin 0.35.1
173
+
174
+ A separate Herdr plugin snapshot, not another core release: core package 0.35.1 and
175
+ its `v0.35.1` tag remain unchanged. The operator has published the core to npm.
176
+
177
+ ### Herdr plugin
178
+
179
+ - **Re-pin the published core 0.35.1 and close the checkout window.**
180
+ `plugins/herdr/runtime-lock.json` returns to production npm source
181
+ `@junghanacs/entwurf@0.35.1` with the registry's measured sha512
182
+ (`sha512-cZZaGfNP…EIchcQ==`). The plugin manifest moves 0.35.0 → 0.35.1;
183
+ admission remains Herdr >= 0.9.0 and the one-build/one-pane/Linux shape is unchanged.
184
+ - **The same core capability through Herdr.** The runtime this snapshot acquires carries
185
+ core 0.35.1: the Claude 5.5 curation with its set-model readback and the pi-durable inbox
186
+ repair (#140). The core release also adds an English, source-only checkout menu. The
187
+ plugin changes no rail, gate or mutant.
188
+ - **Upgrade by acquisition source, not just version.** A settled npm-source 0.35.0
189
+ installation can rebind under the plugin README's ownership conditions. A host that
190
+ installed the intervening `herdr-checkout` candidate must explicitly deactivate by
191
+ its own absolute runtime path before reinstalling the npm-source snapshot.
192
+ No operator installation or active session is rewired by this release work.
193
+
194
+ ### Source-specific verification
195
+
196
+ - Registry metadata reports version/latest 0.35.1, repair 0.12.8-repair.1. The downloaded
197
+ tarball is 11101943 bytes, SHA256
198
+ `6edbcf9fbf31a6df1aff04f34b28ac279a071917d13916410bf466fd33a44eae`, equal to the preserved
199
+ core release candidate. Independently computed sha512 equals `dist.integrity`;
200
+ the registry-shipped runtime helper is byte-equal to this checkout's.
201
+ - Required exact-registry-tarball Docker consumer passed without repacking. Real-npm
202
+ 0.35.0 → 0.35.1 swap and harness-seeded torn-swap recovery passed: the product restored
203
+ the last-good tree before reacquisition, certified the new registry digest, then
204
+ performed an exact-request no-op and owned-fixture removal. Seven focused
205
+ Herdr/manifest gates passed with HEAD, index and work surface unchanged.
206
+ `check-herdr-sandbox` was not run locally for this snapshot because it reads the
207
+ operator's own herdr panes; it rides the pushed SHA's FULL floor in CI.
208
+ - At preparation time, the public-ref install/use/deactivate/reinstall journey and the
209
+ pushed plugin SHA's ordinary four-job CI are still pending. Their actual outcomes belong
210
+ to the release checkpoint; this paragraph is not their acceptance. Earlier npm or
211
+ checkout-carrier receipts cannot certify these source-specific axes.
212
+ - Core 0.35.1's native Codex LIVE remains an explicit per-cut unmeasured exception, not a
213
+ PASS or a standing waiver. Its whole qualification body ran at the core release SHA;
214
+ this plugin-only metadata change does not borrow that body as its own.
215
+
216
+ ## 0.35.1 - 2026-10-13
217
+
218
+ ### ACP
219
+
220
+ - **Claude rows move to Opus/Sonnet 5.5 (#128).** The curated `entwurf` Claude ids are
221
+ now `claude-opus-5-5`, `claude-sonnet-5-5` and `claude-fable-5-1`; the Cortex rows keep
222
+ their native 5 ids. Driver `claude-agent-acp` stays 0.85.1, whose SDK already lists the
223
+ 5.5 ids. Curation and launch checks alone do not certify a live 5.5 turn; the narrow
224
+ LIVE evidence is recorded under the release boundary below. The retired
225
+ `claude-opus-5` / `claude-sonnet-5` are not aliased: an Entwurf-built pi launch
226
+ (`entwurf_fresh_call` `entwurf/<id>`, or `entwurf_resume_call` of a session recorded on
227
+ one) refuses them as `acp-model-not-curated` before a pane opens, because Pi's substring
228
+ resolver would otherwise open them on the Cortex rows. Records and transcripts are not
229
+ rewritten.
230
+ - **Claude set-model answers are read back before the prompt (#128).** The driver answers
231
+ `claude-sonnet-5-5` and `claude-opus-5-5` with its alias rows `sonnet` / `opus`, named
232
+ `Sonnet 5.5` / `Opus 5.5`, and `claude-fable-5-1` with its own row (measured against
233
+ 0.85.1 without a prompt). The claude adapter now accepts only that answer: a missing
234
+ model option, another row, or any row other than that exact value/name pair refuses the
235
+ turn before the prompt instead of letting a different model answer under the requested
236
+ id. Cortex answers are not read back; they are unmeasured.
237
+
238
+ ### Developer checkout
239
+
240
+ - **A source-only menu returns a host to its checkout.** `./run.sh menu` offers a read-only
241
+ readiness check, or switches to the developer board: after that same check and the exact
242
+ confirmation `DEV`, it runs the existing `plugins/herdr/use-dev-checkout.sh --apply`, which
243
+ deactivates the currently owned installation and then links Pi / Claude Code wiring and
244
+ Herdr's local plugin to this checkout. It needs an interactive terminal, runs only from a
245
+ source checkout, and adds no installer, npm acquisition, retry or recovery. Its prompts
246
+ and messages are English.
247
+
248
+ ### pi-durable
249
+
250
+ - **A read withdraws the inbox notices it made stale (#140).** A doorbell queues one native
251
+ follow-up per arriving message, while `entwurf_inbox_read` drains them all, so each
252
+ leftover notice started a run that read an empty inbox. After a read attempt, the
253
+ pi-durable host aborts (`Submission.abort`) its own queued notices whose announced mail is
254
+ no longer unread. Reads and rings share one gate. A failed inspection of the mailbox
255
+ retains the tracked notices; a failed abort releases its tracked handle without retry.
256
+ Both are named on stderr and leave the read's outcome unchanged. This does not claim the
257
+ native queued notice was removed after a failed abort, nor crash-safe receive.
258
+
259
+ ### Release boundary and verification
260
+
261
+ - **Driver unchanged by operator instruction.** `claude-agent-acp` stays 0.85.1. The 0.89.1
262
+ line (ACP SDK 1.6 → 1.8, agent SDK 0.3.293) is a separate lane and is not read as
263
+ compatible here.
264
+ - **Local evidence is focused, not a whole pass.** Each slice ran its affected focused gates
265
+ and its affected qualification groups once as PARTIAL receipts, each with a green
266
+ control: the #128 launch cut killed 99/99 claims in 12 groups, the set-model readback
267
+ 75/75 in 12 groups, and the menu 6/6 in one group. The set now holds 956 claims across
268
+ 72 lanes. By operator instruction the FULL floor and the whole qualification BODY were
269
+ not repeated locally during development; both ran in the first prepared SHA's exact CI.
270
+ Push run 38258514409 at `b93bb37` first failed `check` at `check-herdr-sandbox`
271
+ `[QK:HS-NO-RESIDUE]`: a sandbox process still held the private HOME after
272
+ `herdr server stop` and the gate's fixed 2 s wait. A rerun of the failed job on the same
273
+ SHA passed that assertion, and the run concluded with all four required jobs green and
274
+ the qualification body at 956/956 claims killed. The first red stays on record as a
275
+ teardown-timing observation; it is not read as a pass.
276
+ - **LIVE release gate, native Codex excluded for this cut.** As in 0.35.0, the operator
277
+ excluded native Codex: its MUST step stays wired and declined for lack of the
278
+ operator-supplied app-server pid and model tiers, so no Codex app-server, sibling or
279
+ turn started. That SKIP is an unmeasured per-cut exception, not a PASS or a standing
280
+ waiver. The gate ran from fresh scratch at `b93bb37`, with HEAD, index and tracked tree
281
+ identical before and after: `/tmp/entwurf-release-gate-0.35.1.aXzo1A/release-gate.log`,
282
+ MUST PASS=23 FAIL=0 SKIP=1 (only native Codex), BEHAVIOR PASS=1 FAIL=0 SKIP=0, standard
283
+ `--cut` exit 1 / BLOCKED (MUST SKIP). An earlier attempt failed only its static step,
284
+ because the checkout's bridge `dist` was older than the source mtimes
285
+ (`check-bridge-delivery` staleness); the bridge was rebuilt and the whole gate re-run,
286
+ and only the re-run is the receipt.
287
+ - **What the 5.5 evidence covers.** The ACP steps drove `claude-sonnet-5-5` prompt turns,
288
+ the provider-path ones through the set-model readback above. `claude-opus-5-5` ran only
289
+ as a turn-free socket citizen whose record and `get_info` report
290
+ `entwurf/claude-opus-5-5`; neither it nor Fable 5.1 has prompt-turn evidence. Before the
291
+ gate, one no-prompt wire measurement against 0.85.1 recorded the set-model answers for
292
+ all three ids, and one operator-started ACP turn on `claude-sonnet-5-5` reported its own
293
+ exact model id; that is a model's self-report, not a gate.
294
+ - **Unpublished candidate carrier.** As in 0.35.0, `plugins/herdr/runtime-lock.json`
295
+ temporarily names the closed `herdr-checkout` source: an npm-source lock must agree with
296
+ the checkout's core version, and 0.35.1 has no published integrity yet. The Herdr
297
+ manifest stays 0.35.0. After the operator publishes core 0.35.1, a separate Herdr
298
+ snapshot re-pins the measured registry bytes.
299
+ - **Publication boundary.** This record amendment carries no source change and takes its
300
+ own exact CI, qualification body included, before the make artifact, core tag and GitHub
301
+ Release. npm publication belongs to the operator; the Herdr re-pin follows it.
302
+
303
+ ## v2026.10.12-herdr.0.35.0 — Herdr Entwurf plugin 0.35.0
304
+
305
+ A separate Herdr plugin snapshot, not another core release: core package0.35.0 and
306
+ its `v0.35.0` tag remain unchanged. The operator has published the core to npm.
307
+
308
+ ### Herdr plugin
309
+
310
+ - **Re-pin the published core0.35.0 and close the checkout window.**
311
+ `plugins/herdr/runtime-lock.json` returns to production npm source
312
+ `@junghanacs/entwurf@0.35.0` with the registry's measured sha512
313
+ (`sha512-ENivJbtr…umf2zA==`). The plugin manifest moves0.34.2→0.35.0;
314
+ admission remains Herdr>=0.9.0 and the one-build/one-pane/Linux shape is unchanged.
315
+ - **The same core capability through Herdr.** This snapshot follows the renewed demo
316
+ and source-tooling restoration, plus #137's conservative TOML-only qualification
317
+ refinement. It records no new demo or model turn and changes no rail, gate or mutant.
318
+ - **Upgrade by acquisition source, not just version.** A settled npm-source0.34.2
319
+ installation can rebind under the plugin README's ownership conditions. A host that
320
+ installed the intervening `herdr-checkout` candidate must explicitly deactivate by
321
+ its own absolute runtime path before reinstalling the npm-source snapshot.
322
+ No operator installation or active session is rewired by this release work.
323
+
324
+ ### Source-specific verification
325
+
326
+ - Registry metadata reports version/latest0.35.0, repair0.12.8-repair.1. The downloaded
327
+ tarball is11083782 bytes, SHA256
328
+ `82ae9ab99b799c987fe0dac4bb76fc406afe42088a128a131af4d69a97592e71`, equal to the preserved
329
+ core release candidate. Independently computed sha512 equals `dist.integrity`;
330
+ the registry-shipped runtime helper is byte-equal to this checkout's.
331
+ - Required exact-registry-tarball Docker consumer passed without repacking. Real-npm
332
+ 0.34.2→0.35.0 swap and harness-seeded torn-swap recovery passed: the product restored
333
+ the last-good tree before reacquisition, certified the new registry digest, then
334
+ performed an exact-request no-op and owned-fixture removal. Seven focused
335
+ Herdr/manifests gates passed; HEAD/index/work surface stayed unchanged during that run.
336
+ - At preparation time, public-ref install/use/deactivate/reinstall and the exact pushed
337
+ plugin SHA's ordinary four-job CI/#137 next-plugin BODY-SKIP observation are still
338
+ pending. Their actual outcomes must be recorded in the release checkpoint and #137
339
+ before tagging/closing; this paragraph is not their acceptance. Earlier npm or
340
+ checkout-carrier receipts cannot certify these source-specific axes.
341
+ - Core0.35.0's whole940 qualification and native Codex LIVE remain explicit per-cut
342
+ unmeasured exceptions, never PASS or standing waivers. This plugin-only metadata
343
+ change does not run the approximately95-minute BODY or another core release aggregate.
344
+
7
345
  ## 0.35.0 - 2026-10-12
8
346
 
9
347
  ### Collaboration and qualification
package/CONTRIBUTING.md CHANGED
@@ -4,7 +4,7 @@ This is a daily-driver bridge. Correctness beats feature breadth. Read this befo
4
4
 
5
5
  ## What this repo is
6
6
 
7
- `entwurf` is a **garden-citizen dispatch bridge** — entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + an **ACP plugin on a two-backend adapter rail** — that lets already-running harnesses address one another by garden id; pi is one adapter, not the subject. The ACP plugin borrows the backend's identity (system prompt preset, model behavior, tool implementations) and shapes the *operating surface* — tools, MCP, skills, permissions — to match pi's own policy **wherever that backend exposes a knob for it**. Where it does not, the plugin does not fake one: a cortex session keeps its own native tool surface and receives MCP through an overlay projection, so "shaped to pi's policy" is a Claude-strength claim, not a universal one. Claude is the reference ACP backend and Snowflake Cortex Code is the second (landed 0.13.0, `cortex-` prefixed ids — [docs/acp-backend-rail.md](./docs/acp-backend-rail.md#cortex-code-audit-d1d10)); Codex is not on this rail at all — it is an unreleased native-push candidate with record birth and delivery-probe evidence (see AGENTS.md, DELIVERY.md), never ACP-managed — and Gemini is not a shipped backend. That is the entire ACP-rail scope.
7
+ `entwurf` opens and messages visible sibling sessions across independent harnesses, and reopens dormant pi siblings in tmux ([capability table](./README.md)), with the garden id as their address — entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + an **ACP plugin on a two-backend adapter rail**; pi is one adapter, not the subject. The ACP plugin borrows the backend's identity (system prompt preset, model behavior, tool implementations) and shapes the *operating surface* — tools, MCP, skills, permissions — to match pi's own policy **wherever that backend exposes a knob for it**. Where it does not, the plugin does not fake one: a cortex session keeps its own native tool surface and receives MCP through an overlay projection, so "shaped to pi's policy" is a Claude-strength claim, not a universal one. Claude is the reference ACP backend and Snowflake Cortex Code is the second (landed 0.13.0, `cortex-` prefixed ids — [docs/acp-backend-rail.md](./docs/acp-backend-rail.md#cortex-code-audit-d1d10)); Codex is not on this rail at all — it is a shipped native-push citizen that keeps its own vendor tools and work context (see AGENTS.md, DELIVERY.md), never ACP-managed — and Gemini is not a shipped backend. That is the entire ACP-rail scope.
8
8
 
9
9
  **How a backend joins the rail** (the shape a PR must take): one adapter object in `pi-extensions/lib/acp/backend-adapter.ts` + its own curated rows/overlay modules + its own `check-acp-*` gate and mutant lane. Backend-specific *behavior* must stay behind the adapter, and backend-specific settings ride the opaque `adapterSettings` seam rather than growing the common config. That is not a ban on ever touching the common layer (`backend.ts`'s turn loop, `acp-client.ts`, `event-mapper.ts`, `session-store.ts`, `config.ts`) — cortex's landing did change `backend.ts` to pass the authoritative session key through the generic `ensureOverlay` seam. The rule is narrower and stricter: a common-layer change must be **backend-invariant** (it reads no backend name and branches on no backend) and **separately gated**. A common file that grows an `if (backend === …)` is the thing to reject.
10
10
 
package/DELIVERY.md CHANGED
@@ -193,6 +193,21 @@ no daemon and no pid file: Ctrl-C is the operator's. A live socket, an unidentif
193
193
  second `--listen` are named refusals; a dead socket file is reported and launched over. Passing
194
194
  the raw vendor command by hand remains equivalent and is not deprecated.
195
195
 
196
+ **The control endpoint from Codex 0.162.1 (#141).** `[source rust-v0.162.1]` The advertised path is
197
+ now only an alias: the vendor binds a 0600 socket under `realpath(/tmp)/codex-daemon-<euid>/`, named
198
+ by the sha256 of the canonical advertised path, and symlinks the advertised path to it
199
+ (`app-server-transport/src/transport/unix_socket.rs:43-131, 290-304`; `uds/src/daemon_directory.rs:1-38`).
200
+ One classifier, `checkCodexSocketFile`, accepts exactly a plain socket or that exact alias — link
201
+ owner, byte-equal target, a 0700 socket directory, a socket no other user can open — and refuses
202
+ every other symlink. The delivery probe, `codex queue --remote` and the fresh-call preflight connect
203
+ to the socket it verified, never to the alias again. The launcher runs the same classifier's
204
+ compiled twin (`mcp/entwurf-bridge/dist/scripts/codex-socket-classify.js`) directly, refuses any
205
+ answer it does not recognise, and reports a dangling exact alias as the dead leftover the vendor
206
+ removes on start. A same-euid process can still replace the verified socket file; that residual is
207
+ named, not locked. The alias layout is certified on the classifier in a sandbox; the 0.162.1
208
+ app-server protocol itself requires a named LIVE observation; a diagnostic is not release-cut
209
+ acceptance, which separately requires the official release gate.
210
+
196
211
  #95 D1 (GLG, 2026-09-16) retired the requirement that this session be named `codex`, and with it the
197
212
  rule that an omitted-placement Codex TARGET selected it. The operator still owns the app-server and
198
213
  still chooses its room; Entwurf neither creates nor supervises it, and a missing app-server rejects.
package/FAQ.md CHANGED
@@ -8,7 +8,7 @@ No. Entwurf is closer to a workshop than a factory: it connects independently ow
8
8
 
9
9
  ## What does Entwurf do?
10
10
 
11
- It gives an existing session a stable **garden id** and routes a message, reply, or visible sibling launch through the rail that session actually supports. It does not reconstruct prompts, hydrate transcripts, manage credentials, or emulate another harness.
11
+ It opens, reopens and messages visible sibling sessions across independent harnesses, each under a stable **garden id**. `entwurf_fresh_call` opens a new sibling in the caller's Herdr workspace or tmux session by default, `entwurf_resume_call` reopens a dormant pi sibling under the same id, and `entwurf_v2` delivers a message, reply or hand-off to an existing one through the rail it actually supports. It does not reconstruct prompts, hydrate transcripts, manage credentials, or emulate another harness.
12
12
 
13
13
  ## What is a garden id?
14
14
 
@@ -28,11 +28,11 @@ No. [`entwurf_v2`](./README.md#entwurf_v2--canonical-dispatch-verb) only address
28
28
 
29
29
  ## Where do visible siblings open?
30
30
 
31
- Inside Herdr, Entwurf opens a new unfocused tab in the caller's workspace and currently admits pi and Claude Code. Outside Herdr, it opens one of the fixed pi, Claude Code, Copilot, OMP, or Codex runtimes in a visible tmux window. The runtime keeps its own model, tools, authentication, and transcript.
31
+ Inside Herdr, Entwurf opens a new unfocused tab in the caller's workspace and currently admits pi and Claude Code. Outside Herdr, it opens one of the fixed pi, pi-durable, Claude Code, Copilot, OMP, or Codex runtimes in a new window of the caller's tmux session, or of an existing session the caller names; without an explicit tmux placement, a Codex caller opens beside its own TUI pane. A dormant pi sibling reopens under the same id in a visible tmux window. The runtime keeps its own model, tools, authentication, and transcript.
32
32
 
33
33
  ## Does Entwurf replace Herdr or tmux?
34
34
 
35
- No. Herdr and tmux provide visible seats. Entwurf provides identity, delivery, and receipts across independent harness sessions. A pane or tmux session is a location for a sibling, never its address or liveness proof.
35
+ No. Herdr and tmux provide visible seats. Entwurf opens siblings into them, reopens dormant pi siblings, and carries identity, delivery, and receipts across independent harness sessions. A pane or tmux session is a location for a sibling, never its address or liveness proof.
36
36
 
37
37
  ## How do I install it?
38
38
 
package/README.md CHANGED
@@ -1,10 +1,12 @@
1
1
  # entwurf
2
2
 
3
- `entwurf` is a garden-citizen dispatch substrate: a thin bridge that lets independent
4
- agent harnesses address one another by **garden id**, without owning each other's
5
- transcript, authentication, tools, or runtime.
3
+ `entwurf` connects independent agent harnesses as visible siblings: open a new session,
4
+ reopen a dormant pi session in tmux, or reach an existing sibling by **garden id**. Fresh
5
+ sessions open in the caller's Herdr workspace or tmux session by default; explicit tmux
6
+ placement can name another existing session. Each harness keeps its own runtime,
7
+ authentication, tools and transcript.
6
8
 
7
- ![entwurf — a forged screwdriver for garden-citizen dispatch](docs/assets/entwurf-hero.jpg)
9
+ ![entwurf — a forged screwdriver for visible sibling sessions](docs/assets/entwurf-hero.jpg)
8
10
 
9
11
  **Pi ↔ native Claude Code inside the [Herdr workbench](#herdr-workbench).**
10
12
  A recorded source-checkout demo: callback → task → native Bash → reply.
@@ -21,12 +23,15 @@ receipts and named lifecycle verbs; the operator and native harnesses keep steer
21
23
  Git branches, worktrees, file isolation and internal delegation remain their concern.
22
24
  [Short answers: FAQ](./FAQ.md).
23
25
 
24
- ```text
25
- pi / pi-durable / Claude Code / Copilot / OMP / Antigravity / Codex
26
- → record-backed garden id
27
- → entwurf_v2
28
- → control-socket | self-fetch mailbox | native-push
29
- ```
26
+ | Verb | Tool | Where it lands | Harnesses |
27
+ |---|---|---|---|
28
+ | **Open** a new sibling | `entwurf_fresh_call` | Herdr: a new unfocused tab in the caller's workspace. tmux: a new window in the caller's session, or an existing session named by `placement.tmuxSession`; without an explicit tmux placement, a Codex caller opens beside its own TUI pane | Herdr: pi, Claude Code. tmux: pi, pi-durable, Claude Code, Copilot, OMP, Codex |
29
+ | **Reopen** a dormant sibling | `entwurf_resume_call` | A visible tmux window under the same garden id, with the transcript, model, provider and cwd its record names; no turn is run | pi |
30
+ | **Message** an existing sibling | `entwurf_v2` | Its own rail: control socket, self-fetch mailbox or native push; delivery starts no process | pi, pi-durable, Claude Code, Copilot, OMP, Antigravity, Codex |
31
+
32
+ Antigravity is message-only: an existing conversation registers itself, and Entwurf never
33
+ launches one. A launch receipt is neither the new sibling's address nor proof that it
34
+ processed its task; the sibling's own callback envelope supplies its garden id.
30
35
 
31
36
  The package holds the v2 core, native-harness bridges, a pi adapter and an ACP
32
37
  plugin. ACP is one ingress, not the boundary; pi is one adapter, not the center.
@@ -40,14 +45,15 @@ receipts; [CHANGELOG](./CHANGELOG.md) records source history.
40
45
  ## Install
41
46
 
42
47
  **Choose by where you work. Bring your own harnesses, subscriptions and login.**
43
- The native durable route below additionally supplies the upstream app/TUI missing from its npm
44
- release; it does not supply credentials or take ownership of the harness.
48
+ The native durable route below additionally supplies an app/TUI, Entwurf's own thin composition of
49
+ the durable app upstream omits from its npm release; it does not supply credentials or take
50
+ ownership of the harness.
45
51
 
46
52
  ### Direct — ordinary shell or tmux
47
53
 
48
54
  Prerequisites: **Node >=24.0.0**, Python 3 for `setup`, and any harnesses you choose
49
55
  to use, already installed and authenticated. Pi is optional-by-presence, supported
50
- range `>=1.1.0 <1.2`; Claude Code supported floor `>=2.1.217` is required for its
56
+ range `>=1.2.0 <1.3`; Claude Code supported floor `>=2.1.217` is required for its
51
57
  managed exec-hook lifecycle. pnpm is needed only for source-checkout setup.
52
58
 
53
59
  ```bash
@@ -77,7 +83,7 @@ restriction; that is not certification of every platform's harness rails.
77
83
 
78
84
  ### Native durable (pi-durable)
79
85
 
80
- **The package supplies the pinned upstream app/TUI and nine exact Pi 1.1.0 SDK
86
+ **The package supplies Entwurf's owned app/TUI carrier and nine exact Pi 1.2.0 SDK
81
87
  members.** No separate runtime checkout, patch, build or ordinary Pi CLI is needed.
82
88
  The launch verifies carrier integrity and every reachable SDK edge's name/version;
83
89
  incomplete, drifted or mixed supply refuses by name.
@@ -87,8 +93,9 @@ entwurf pi-durable --provider <provider> --model <model-id> --width task-wide
87
93
  entwurf pi-durable --continue
88
94
  ```
89
95
 
90
- The contact adds garden identity and two-way mailbox communication. Runtime/TUI,
91
- models/auth, queues, SQLite, transcripts and recovery remain upstream-owned:
96
+ The contact adds garden identity and two-way mailbox communication. Entwurf owns the
97
+ thin app/TUI composition (shipped as an emitted JS carrier); execution, models/auth, queues,
98
+ SQLite, transcripts and recovery remain the upstream SDK's:
92
99
  [Hard Rule 17](./AGENTS.md#hard-rules), **supply the missing surface; do not become the harness**.
93
100
 
94
101
  Optional `--native-module <absolute file>` initializes trusted ESM before runtime/TUI
@@ -161,6 +168,13 @@ Liveness is read at dispatch time; an id's shape does not tell you its transport
161
168
 
162
169
  ### `entwurf_v2` — canonical dispatch verb
163
170
 
171
+ ```text
172
+ pi / pi-durable / Claude Code / Copilot / OMP / Antigravity / Codex
173
+ → record-backed garden id
174
+ → entwurf_v2
175
+ → control-socket | self-fetch mailbox | native-push
176
+ ```
177
+
164
178
  | What you want | Tool | What its receipt means |
165
179
  |---|---|---|
166
180
  | Message, reply or hand off to an existing garden id | `entwurf_v2 {target, intent:"fire-and-forget", message}` | Receiver acceptance boundary, mailbox enqueue or native injection; not completion |
package/VERIFY.md CHANGED
@@ -116,7 +116,7 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
116
116
  >
117
117
  > 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
118
  >
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`, 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).
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).
120
120
  >
121
121
  > 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
122
  >
@@ -213,8 +213,8 @@ Do not collapse source, package, fixture, and native-host evidence into one “g
213
213
  **Native durable contact (#129, #130 carrier).** `check-pi-durable-beside` is the deterministic
214
214
  beside-test/mutant coordinate in `check:contracts`: the adapter, the installed carrier/SDK-set
215
215
  verifier, the preflight, the owner join, the carrier's relocation grammar, resolver and
216
- maintainer emitter (its source reads refuse replace refs; its one patch carries exactly one
217
- section per patched carrier file, #134), and the bootstrap's explicit `--native-module` ingress
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
218
  (#130 P2) with its paired `--native-module-dir` (#134), driven through the packaged `main`'s own
219
219
  seams: initialization before the TUI and the open, named refusals, the identity and directory
220
220
  guards, the top-level `*.extension.mjs` filter and byte-wise order, cross-module name refusals, the
@@ -250,11 +250,13 @@ constructed depth-3 mismatch refused by the verifier and seen by the oracle, the
250
250
  app's own model refusal before any birth — also with one installed `--native-module` initialized
251
251
  first, a reserved extension name refused before anything opens, one installed `--native-module-dir`
252
252
  initializing only its top-level `*.extension.mjs` (#134) and a directory without a module refused
253
- before anything opens — and the HOST kept a separate subject — a real pi 1.0.4
253
+ before anything opens — and the HOST kept a separate subject — a real pi 1.1.0
254
254
  binary (the previous generation) beside the pinned native set is a named pi FAIL with zero Pi wiring while pi-durable still
255
- PASSes — not native admission. The maintainer's rebuild
256
- equality is `emit-pi-durable-carrier --check` against a supplied upstream clone; without one it is
257
- a named SKIP, not acceptance. First-release visible fresh/callback and native
255
+ PASSes — not native admission. The carrier's rebuild
256
+ equality is the owned source's emission (#141): the beside claim `PI-DURABLE-CARRIER-EMIT-SOURCE-EQUAL`
257
+ on every floor, `emit-pi-durable-carrier --check` as its CLI. The emitter's exact Node is red in the CI
258
+ `check` job (`ENTWURF_REQUIRE_EMITTER_NODE=1`) and a named SKIP on a host running another Node, not
259
+ acceptance there. First-release visible fresh/callback and native
258
260
  caller/target/cross-harness LIVE are owed by `smoke-pi-durable-fresh-live`, a release-gate MUST
259
261
  (LIVE=1; vendor V on a real Pi and a real pi-durable host); SDK or package green does not waive it.
260
262
 
@@ -278,7 +280,7 @@ consumer image outside this standing protocol.
278
280
  ### Verifying the two capabilities a gate cannot fully judge
279
281
 
280
282
  - **Garden-id delivery:** discover a target with `entwurf_peers`, then `entwurf_v2 fire-and-forget` — the intent axis is single-valued since the visible-first cut. It reaches a live pi target over its control socket, a deliverable self-fetch citizen through the mailbox, and a probe-alive native-push conversation by direct injection. A DORMANT in-domain citizen rejects as `dormant-fire-forget-unsupported` — delivery never wakes it; reopen it with the separate lifecycle verb `entwurf_resume_call {target}`, then dispatch again. A wrong target state is rejected, never auto-fixed and never launched into.
281
- - **ACP continuity:** a direct `pi --provider entwurf --model claude-sonnet-5` turn, or the `smoke-acp-session-reuse-live` gate (process-scoped reuse + recall). Multi-turn reuse is proven by that gate, not by any v1 resume tool.
283
+ - **ACP continuity:** a direct `pi --provider entwurf --model claude-sonnet-5-5` turn, or the `smoke-acp-session-reuse-live` gate (process-scoped reuse + recall). Multi-turn reuse is proven by that gate, not by any v1 resume tool.
282
284
  - **agy citizenship:** in a fresh agy conversation, the first `PreInvocation` must yield a garden id, `entwurf_self` must report `agentId=meta-session/antigravity` and `replyable:true` only while the native probe is alive, and a reply to that same garden id must direct-inject into the same conversation. No mailbox/receiver-marker evidence counts on this rail.
283
285
 
284
286
  ### What NOT to do — bypassing the operational path
@@ -348,7 +350,7 @@ The goal is not merely "invoke Claude Code." We want:
348
350
  **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.
349
351
 
350
352
  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`)
351
- 2. pi wiring → `<project>/.pi/settings.json` + user-scope registration — only when a `pi` inside the supported range (`>=1.1.0 <1.2`) 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
353
+ 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
352
354
  3. Claude meta-bridge global plugin — only when `claude` is on PATH; otherwise skipped cleanly
353
355
  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
354
356
  5. agy bridge + exact permission + statusline + `PreInvocation` hook — only when `agy` is on PATH; each adapter is idempotent and independently doctorable
@@ -393,7 +395,7 @@ strips Claude hooks (`hooks: {}` overlay). Strip those carriers:
393
395
  cd /path/to/scratch
394
396
  env -u CLAUDE_CONFIG_DIR -u PI_SESSION_ID -u PI_AGENT_ID \
395
397
  LIVE=1 /path/to/entwurf/run.sh release-gate /path/to/scratch --cut
396
- pi --provider entwurf --model claude-sonnet-5 -p "reply with ok only" # one-turn smoke
398
+ pi --provider entwurf --model claude-sonnet-5-5 -p "reply with ok only" # one-turn smoke
397
399
  ```
398
400
 
399
401
  The one-turn smoke is a **provider**-surface check (auth + model routing + a real
@@ -421,7 +423,7 @@ frozen here.
421
423
 
422
424
  ## 1A. Main Agent Evaluation — Is `entwurf` Claude strong enough?
423
425
 
424
- Separate from continuity gates. Gates prove "sessions continue"; this questionnaire examines tool self-awareness / native tool usability / MCP-boundary awareness / long-turn focus / quality vs direct Claude Code. Run it against `entwurf/claude-sonnet-5` via a direct `pi --provider entwurf` turn (or a live ACP session); accumulate turns by re-prompting the same target.
426
+ Separate from continuity gates. Gates prove "sessions continue"; this questionnaire examines tool self-awareness / native tool usability / MCP-boundary awareness / long-turn focus / quality vs direct Claude Code. Run it against `entwurf/claude-sonnet-5-5` via a direct `pi --provider entwurf` turn (or a live ACP session); accumulate turns by re-prompting the same target.
425
427
 
426
428
  ### 1A.0 Two carrier surfaces — engraving vs pi-context-augment (load-bearing)
427
429
 
@@ -459,6 +461,7 @@ The single-turn / multi-turn / cross-process / persistence-boundary / shutdown i
459
461
  | Tool-call / event mapping | `check-acp-event-mapper`, `smoke-acp-provider-live` |
460
462
  | Prompt lifecycle — no wall-clock cutoff on a running turn; abort ends it by ACP `session/cancel` with bounded cleanup; a child death is reported with exit status + stderr on new AND reuse turns; our prompt-phase error text is not classified transient by pi | `check-acp-prompt-lifecycle`, `check-probe-ordering` |
461
463
  | Claude typed `incomplete_tool_call` prompt failure — real pi retry/overflow classifiers reject the fixed verdict, raw evidence stays in existing diagnostics, exactly one seal and drop on new/reuse; other failures retain the legacy stderr path, cancel stays separate. A deterministic receipt does not certify the target vendor runtime. No LIVE gate induces this rejection; the raw-turn and reuse smokes certify only their own rows above. | `check-acp-vendor-rejection` (four mutants) |
464
+ | Claude set-model answer read back before the prompt — an exact row, or the one alias row (value and name) measured for the requested id; a missing model option, another row or any other value/name pair refuses with non-transient text. Deterministic only: the measured 0.85.1 answer shapes are fixture literals, not a runtime certificate. | `check-acp-set-model-readback` (two mutants), `check-probe-ordering` |
462
465
  | Operator mcpServers / skills reach the live session | `smoke-acp-mcp-live`, `smoke-acp-skill-live`, `check-acp-config` |
463
466
  | Overlay isolation + memory containment | `check-acp-overlay`, `smoke-acp-memory-containment-live`, `check-acp-tool-surface` |
464
467