@junghanacs/entwurf 0.31.0 → 0.33.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 (58) hide show
  1. package/AGENTS.md +3 -2
  2. package/CHANGELOG.md +128 -0
  3. package/README.md +62 -117
  4. package/VERIFY.md +40 -21
  5. package/demo/README.md +1 -1
  6. package/docs/acp-backend-rail.md +1 -1
  7. package/docs/setup-clean-host.md +112 -95
  8. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +1 -1
  9. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +1 -1
  10. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +8 -10
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +3 -3
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-runtime.js +153 -205
  13. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +6 -4
  14. package/mcp/entwurf-bridge/src/index.ts +1 -1
  15. package/package.json +14 -17
  16. package/pi/pi-durable/bootstrap.mjs +142 -19
  17. package/pi/pi-durable/carrier/LICENSE +21 -0
  18. package/pi/pi-durable/carrier/harness-setup.js +123 -0
  19. package/pi/pi-durable/carrier/prompt.js +74 -0
  20. package/pi/pi-durable/carrier/runtime.js +402 -0
  21. package/pi/pi-durable/carrier/sessions.js +56 -0
  22. package/pi/pi-durable/carrier/subagent.js +55 -0
  23. package/pi/pi-durable/carrier/tui.js +655 -0
  24. package/pi/pi-durable/carrier-relocation.mjs +160 -0
  25. package/pi/pi-durable/carrier-resolver.mjs +38 -0
  26. package/pi/pi-durable/overlay/upstream-pin.json +103 -11
  27. package/pi-extensions/lib/fresh-call-composition.ts +1 -1
  28. package/pi-extensions/lib/mux-fresh-call.ts +8 -10
  29. package/pi-extensions/lib/pi-durable-fresh-preflight.ts +3 -3
  30. package/pi-extensions/lib/pi-durable-runtime.ts +197 -263
  31. package/pi-extensions/meta-bridge-pi-durable.ts +13 -7
  32. package/run.sh +519 -248
  33. package/scripts/check-entwurf-bridge-pi-free.ts +7 -5
  34. package/scripts/check-fresh-call-dispatch.ts +1 -1
  35. package/scripts/check-gate-qualification.ts +86 -34
  36. package/scripts/check-herdr-activation.ts +5 -4
  37. package/scripts/check-pi-durable-contact.ts +26 -93
  38. package/scripts/check-pi-durable-receive.ts +22 -59
  39. package/scripts/check-pi-durable-send.ts +235 -75
  40. package/scripts/check-release-gate-outcomes.ts +21 -17
  41. package/scripts/emit-pi-durable-carrier.ts +355 -0
  42. package/scripts/lib/mutation-qualify.ts +21 -45
  43. package/scripts/lib/pi-durable-operator-guard.ts +89 -0
  44. package/scripts/lib/qualification-receipt.ts +7 -11
  45. package/scripts/mutants/control-send-receipt.json +1 -1
  46. package/scripts/mutants/gate-qualification.json +13 -0
  47. package/scripts/mutants/mux-fresh-call.json +13 -13
  48. package/scripts/mutants/pack-install.json +3 -3
  49. package/scripts/mutants/pi-durable.json +442 -109
  50. package/scripts/mutants/pi-floor.json +24 -2
  51. package/scripts/mutants/release-gate.json +5 -3
  52. package/scripts/pi-durable-contact-host.mjs +3 -3
  53. package/scripts/pi-durable-receive-host.mjs +3 -3
  54. package/scripts/pi-durable-send-host.mjs +76 -5
  55. package/scripts/smoke-herdr-raw-install-live.sh +1 -1
  56. package/scripts/smoke-pi-durable-fresh-live.ts +3 -3
  57. package/scripts/smoke-setup-verdict.sh +15 -15
  58. package/scripts/smoke-user-scope-citizen.sh +1 -1
@@ -28,8 +28,8 @@ evidence split, and its three states must not collapse into "macOS is supported"
28
28
  | npm/pnpm | npm is bundled with Node; pnpm is required for source setup | package or source installation |
29
29
  | Python 3 | required by `setup`/`install` (project-path normalization + settings writers); `--help`/`check-bridge` stay Python-free | pi/Claude/agy/Copilot/Codex wiring writers |
30
30
  | entwurf | global/project-local `@junghanacs/entwurf`, or a source checkout | operator command and garden capability |
31
- | pi | optional-by-presence, `>=1.0.2 <1.1` — absent is an explicit setup SKIP, below-floor is a named FAIL | ACP provider, control sockets |
32
- | Native durable (`pi-durable`) | optional-by-presence, operator-provided experimental source runtime at the fixed `…/entwurf/pi-durable/runtime`, pinned to `cd32f77` plus the narrow runtime-contact overlay; not supplied by ordinary Pi npm installation — absent is an explicit setup SKIP, present-but-not-the-pin a named FAIL | optional 0.31.0 candidate contact via `entwurf pi-durable`; first native Pi ↔ pi-durable admission/LIVE accepted on one Linux host, runtime provision and release acceptance separate (§2b) |
31
+ | pi | optional-by-presence, `>=1.1.0 <1.2` — absent is an explicit setup SKIP, below-floor is a named FAIL | ACP provider, control sockets |
32
+ | Native durable (`pi-durable`) | supplied by the Entwurf package (#130): a pinned upstream v1.1.0 app carrier plus the exact 1.1.0 pi SDK set as production dependencies — setup PASS when they verify, a named FAIL otherwise (never SKIP) | the `entwurf pi-durable` contact; native birth/LIVE on this supply surface is a separate release proof (§2b) |
33
33
  | Claude Code | optional, **`>=2.1.217`** — the exec-form hook floor | Claude ACP auth/runtime and mailbox-backed native citizen |
34
34
  | GitHub Copilot CLI | optional-by-presence, operator-installed and authenticated — absent is an explicit setup SKIP; detected composes all four units (birth/MCP/receiver/footer) | self-fetch citizen and visible fresh |
35
35
  | OMP (`omp`) | optional-by-presence, operator-installed — absent is an explicit setup SKIP; detected composes all four units (birth/MCP/`tools.xdev` setting/receiver) | self-fetch citizen and visible fresh (accepted on one host — see §4b) |
@@ -191,7 +191,7 @@ on Darwin; that is wiring, not a rail receipt. If `pi` is on PATH,
191
191
  Install the exact release floor, then wire the project:
192
192
 
193
193
  ```bash
194
- npm install -g @earendil-works/pi-coding-agent@1.0.2
194
+ npm install -g @earendil-works/pi-coding-agent@1.1.0
195
195
  pi --version
196
196
 
197
197
  cd ~/entwurf-smoke
@@ -199,7 +199,7 @@ entwurf install .
199
199
  pi -e "$(npm root -g)/@junghanacs/entwurf" --list-models entwurf
200
200
  ```
201
201
 
202
- The supported range is `>=1.0.2 <1.1`. It is a hard minimum: installing this
202
+ The supported range is `>=1.1.0 <1.2`. It is a hard minimum: installing this
203
203
  release onto a 0.83.x pi host upgrades the runtime rather than keeping the older
204
204
  minor. A host using only the external MCP bridge can skip pi until it needs a
205
205
  control socket; no delivery rail launches a pi process.
@@ -285,102 +285,119 @@ emacsclient -s "${PI_EMACS_AGENT_SOCKET:-server}" --eval '(...)'
285
285
 
286
286
  ## 2b. Optional native durable (`pi-durable`)
287
287
 
288
- **0.31.0 installation contract; first native admission/LIVE accepted on one Linux host.**
289
- The [DELIVERY matrix](../DELIVERY.md) records the 2026-10-06 LIVE36 candidate
290
- acceptance; release/artifact and runtime-supply evidence remain separate.
291
- Durable is a separate native harness contact, not an option automatically enabled
288
+ **#130 / 0.32 installation contract: installing Entwurf supplies pi-durable.** The
289
+ operator clones, patches, builds and copies nothing. 0.31.0 shipped the earlier
290
+ source-runtime route (an operator checkout of Pi 1.0.2/source `cd32f77` at a fixed XDG
291
+ place); that route is retired, not kept as a fallback, and its runtime directory is never
292
+ read. Durable is a separate native harness contact, not an option automatically enabled
292
293
  by `entwurf pi` or by registering ordinary Pi's adapter.
293
294
 
294
- There are three different things to install or supply:
295
-
296
- 1. **Entwurf:** the existing global/project-local npm or source-checkout route in
297
- §1 stays unchanged. It supplies Entwurf bytes, not the native harness.
298
- 2. **Durable library:** `@earendil-works/pi-durable` is npm-installable. A library
299
- dependency does not install the experimental coding app/TUI or birth a citizen.
300
- 3. **Native app/runtime:** upstream's experimental durable app runs from a Pi
301
- source checkout through its source resolver. The pinned 1.0.2 ordinary
302
- `pi-coding-agent` package excludes experimental app output; upgrading the global
303
- `pi` CLI does not supply it. Entwurf's maintained contact requires the exact
304
- upstream commit `cd32f7725fdbddbaecdff5b1e68491563394e0ca` plus its narrow
305
- runtime-contact overlay, operator-provided dependencies and pinned runtime data.
306
-
307
- The upstream [library installation guide](https://github.com/earendil-works/pi/blob/cd32f7725fdbddbaecdff5b1e68491563394e0ca/packages/durable/README.md#installation)
308
- and [experimental app guide](https://github.com/earendil-works/pi/blob/cd32f7725fdbddbaecdff5b1e68491563394e0ca/packages/coding-agent/src/experimental/durable/README.md)
309
- describe different consumers. Running the bare upstream app does not attach
310
- Entwurf's garden contact. Entwurf does not install a second harness distribution,
311
- rebuild its controller/model/auth/storage system or proxy a subscription.
312
-
313
- ### What the operator supplies
314
-
315
- The runtime lives at ONE fixed place, with no path override:
316
- `$XDG_DATA_HOME/entwurf/pi-durable/runtime` (an absolute `XDG_DATA_HOME`; otherwise
317
- `~/.local/share/entwurf/pi-durable/runtime`). It counts as the pin only when:
318
-
319
- - HEAD is `cd32f7725fdbddbaecdff5b1e68491563394e0ca`, nothing is staged, `git diff`
320
- equals the packaged overlay `pi/pi-durable/overlay/runtime-contacts.patch` byte for
321
- byte, and no non-ignored file is untracked;
322
- - the upstream source resolver
323
- `packages/coding-agent/src/experimental/source-resolver.ts` is present;
324
- - the git-ignored model data in `packages/ai/src/providers/data` matches the pinned
325
- digest: the bytes `@earendil-works/pi-ai@1.0.2` ships in `dist/providers/data`,
326
- **including its `.manifest.json` dotfile** (recorded in
327
- `pi/pi-durable/overlay/upstream-pin.json`).
328
-
329
- The operator supplies it by hand; Entwurf never downloads, installs, repairs,
330
- moves or deletes the runtime. The sequence below was run on a Linux host
331
- (2026-10-06); afterwards the runtime verifier `entwurf setup` consults returned
332
- the pin (exit 0) and the checkout's native contact cells passed against it.
333
- `ENTWURF_ROOT` is your Entwurf package root or checkout, which ships the patch:
295
+ What the Entwurf package supplies:
296
+
297
+ 1. **The pi SDK set** — `@earendil-works/{pi-coding-agent, pi-ai, pi-tui, pi-agent-core,
298
+ pi-durable, chord, pi-mcp, pi-codemode, pi-telemetry}` at exactly `1.1.0`, plus
299
+ `proper-lockfile`, as Entwurf's own production dependencies (declared once in
300
+ `pi/pi-durable/overlay/upstream-pin.json` `sdk`). Model data rides the published
301
+ `pi-ai`; there is no catalog copy.
302
+ 2. **The native app/TUI carrier** — upstream does not publish the experimental durable
303
+ app (`pi-coding-agent` excludes `dist/experimental`; `pi-durable` on npm is the
304
+ library). Entwurf ships the six pinned app files from upstream tag `v1.1.0`
305
+ (`abe508e1b89912adde45528136c3221eb69acdd7`), its narrow runtime-contact overlay
306
+ applied to `runtime.ts`, type-stripped and relocated, in `pi/pi-durable/carrier/`
307
+ with upstream's MIT license. Each file's source blob and emitted digest are in the pin.
308
+ The carrier reaches pi-coding-agent's internals only through its resolver
309
+ (`pi/pi-durable/carrier-resolver.mjs`), which maps them to the published package's
310
+ own `dist/` as installed — never through a source checkout.
311
+
312
+ The upstream [library guide](https://github.com/earendil-works/pi/blob/v1.1.0/packages/durable/README.md)
313
+ and [experimental app guide](https://github.com/earendil-works/pi/blob/v1.1.0/packages/coding-agent/src/experimental/durable/README.md)
314
+ describe what the carrier is. Running the bare upstream app does not attach Entwurf's
315
+ garden contact. Entwurf does not rebuild the controller/model/auth/storage system or
316
+ proxy a subscription; native execution, models, auth, queues, SQLite and recovery stay
317
+ upstream-owned.
318
+
319
+ ### What Entwurf checks
320
+
321
+ The carrier is runnable only when, read from where Entwurf is installed: every pinned
322
+ carrier file, the license, the resolver and its relocation grammar are present
323
+ (`pi-durable-package-incomplete`); each carrier file carries its pinned digest
324
+ (`pi-durable-carrier-drift`); every declared SDK package resolves from the carrier
325
+ (`pi-durable-sdk-absent`); and every reachable physical edge — from the carrier to each package,
326
+ and from every package copy it reaches, at any depth, to its own `@earendil-works` dependencies —
327
+ lands on a package of the declared name at exactly the pinned version (`pi-durable-sdk-mismatch`). The members declare one another with caret
328
+ ranges, so semver satisfaction is not the contract; the bytes an import binds are. Sharing
329
+ one copy with an aligned host install of the same version is an ordinary layout. A mixed
330
+ tree (for example an override that binds pi-durable's `pi-ai` to an older published version) still
331
+ *imports* — which is why the edge check exists — and is refused by name.
332
+
333
+ - `entwurf setup` reports a `pi-durable` row from that check and writes no durable wiring:
334
+ **PASS** when it verifies, **FAIL** with the named refusal otherwise — never SKIP, because
335
+ nothing is optional to detect: a missing piece is an incomplete installation, repaired by
336
+ reinstalling Entwurf.
337
+ - `entwurf pi-durable [args…]` is the managed launch. It verifies first (exit 3 on any
338
+ refusal), then runs the packaged bootstrap `pi/pi-durable/bootstrap.mjs` under the carrier
339
+ resolver, owning this terminal:
340
+
341
+ ```bash
342
+ entwurf pi-durable --provider <provider> --model <exact catalog id> --width task-wide
343
+ entwurf pi-durable --continue # this directory's newest durable session
344
+ ```
345
+
346
+ The bootstrap imports only the compiled closure shipped beside it
347
+ (`mcp/entwurf-bridge/dist/…`); a source checkout needs a built bridge
348
+ (`pnpm run build-bridge`) and its development dependencies installed first.
349
+ `plugins/pi-durable/bootstrap.mjs` is only the checkout path that re-exports it.
350
+
351
+ - **One explicit native module (optional).** Add `--native-module <absolute file>` to either
352
+ launch to load ONE module of your own. It is an ordinary ES module: its top-level code (top-level
353
+ await included) runs first, before the TUI and the durable runtime load, so it can prepare the
354
+ environment the provider runtime and tool children will read; its default export is a native
355
+ durable `Extension` (`{ name, tools?, sections?, hooks?, … }`, the upstream durable API, not
356
+ ordinary Pi's `ExtensionAPI`), installed after Entwurf's contact. An env-only module exports
357
+ just `{ name }`. Refused by name before anything opens: a relative or non-file path
358
+ (`native-module-path-*`), a module that throws (`native-module-import-failed`), a function or
359
+ nameless default (`native-module-export-invalid`), an extension named like one the app installs
360
+ itself (`entwurf`, `coding-tools`, `pi-prompt`, `subagent`) or a tool named like one of Entwurf's
361
+ contact tools (`native-module-name-reserved`; any other duplicate is the native registry's to
362
+ judge), and a module whose initialization changes
363
+ `PI_SESSION_ID`, `PI_CODING_AGENT_DIR`, `HOME` or any `ENTWURF_*` (`native-module-env-identity-changed`)
364
+ or the process directory (`native-module-cwd-changed`). Your module is trusted code; those
365
+ checks catch mistakes, they do not sandbox it. Nothing else names a module — no directory,
366
+ setting or profile — and a sibling opened by `entwurf_fresh_call` starts without one.
367
+
368
+ - **Known warning.** Ordinary Pi may print `Host-provided extension packages must be declared in
369
+ peerDependencies with a "*" range, not dependencies: @earendil-works/…` for Entwurf's
370
+ `package.json`. Entwurf declares the exact pi SDK set as production dependencies on purpose:
371
+ the installed copies serve the separate pi-durable native process. Pi's check reads that
372
+ manifest field; it is a known constraint of supplying both from one package, accepted for 0.32,
373
+ not a claim that every load path is harmless.
374
+
375
+ The ordinary Pi CLI on PATH is a separate subject (§2, range `>=1.1.0 <1.2`): a host Pi is
376
+ not needed to run pi-durable, and a host inside the range need not be the same copy as the
377
+ carrier's. Native Pi owns credentials, model settings and durable SQLite sessions; keep them
378
+ in place rather than copying credentials or migrating ordinary Pi transcripts. Native
379
+ recovery does not prove exactly-once Entwurf dispatch or inbox read recovery. The contact
380
+ provides garden attachment, visible identity and announce-only root-directed self-fetch.
381
+ Package gates prove the installed carrier's load, its physical edges and the public launch up
382
+ to the app's own model resolution; the checkout contact/send/receive gates run the same carrier
383
+ with scripted S plus native H; Pi ↔ pi-durable LIVE on this supply surface is a separate release
384
+ proof ([#130](https://github.com/junghan0611/entwurf/issues/130)).
385
+
386
+ ### Maintainer: re-emitting the carrier
387
+
388
+ Only a maintainer moving the pin runs `scripts/emit-pi-durable-carrier.ts`. It reads the
389
+ pinned commit's objects (`<commit>:<path>`, `--no-replace-objects`) from a repository the
390
+ maintainer names, applies the overlay patch with `git apply` in a private scratch tree,
391
+ type-strips with Node's own strip-only TypeScript, relocates, and checks that the six files
392
+ import exactly the pin's declared `distTargets`:
334
393
 
335
394
  ```bash
336
- case "${XDG_DATA_HOME:-}" in
337
- /*) R="$XDG_DATA_HOME/entwurf/pi-durable/runtime" ;;
338
- *) R="$HOME/.local/share/entwurf/pi-durable/runtime" ;;
339
- esac
340
- git clone --no-checkout https://github.com/earendil-works/pi.git "$R"
341
- git -C "$R" checkout --detach cd32f7725fdbddbaecdff5b1e68491563394e0ca
342
- git -C "$R" apply "$ENTWURF_ROOT/pi/pi-durable/overlay/runtime-contacts.patch" # worktree only; do not stage
343
- (cd "$R" && npm ci --ignore-scripts) # upstream lockfile; dependency install scripts skipped
344
- T=$(mktemp -d)
345
- (cd "$T" && npm pack @earendil-works/pi-ai@1.0.2)
346
- tar -xzf "$T/earendil-works-pi-ai-1.0.2.tgz" -C "$T" package/dist/providers/data
347
- cp -a "$T/package/dist/providers/data/." "$R/packages/ai/src/providers/data/" # dotfiles too
348
- entwurf setup # expect: pi-durable PASS
395
+ node scripts/emit-pi-durable-carrier.ts --source <clone holding the pinned commit> --write
396
+ node scripts/emit-pi-durable-carrier.ts --source <clone holding the pinned commit> --check # rebuild equality
349
397
  ```
350
398
 
351
- Why it is a source checkout and not `npm install`: `@earendil-works/pi-coding-agent`
352
- (1.0.2 and 1.0.4 alike) excludes `dist/experimental` from its `files`, and its only
353
- experimental export resolves to `src/`, which the tarball does not ship, so the
354
- durable app's `experimental/durable/runtime.ts` and `tui.ts` exist only in a source
355
- checkout. `@earendil-works/pi-durable` on npm is the library (no app, TUI or bin).
356
-
357
- ### What Entwurf does with it
358
-
359
- - `entwurf setup` reports a `pi-durable` row from that check and writes no durable
360
- wiring in any case: **PASS** when the runtime is the pin, **SKIP** when nothing is
361
- at the fixed place, **FAIL** with the named refusal when something is there but is
362
- not the pin.
363
- - `entwurf pi-durable [args…]` is the managed launch. It verifies the same runtime
364
- first (refusal exit 4 when absent, 3 otherwise), then runs the packaged bootstrap
365
- `pi/pi-durable/bootstrap.mjs` under the runtime's source resolver, owning this
366
- terminal. The bootstrap imports only the compiled closure shipped beside it
367
- (`mcp/entwurf-bridge/dist/…`), so an installed package never imports checkout
368
- TypeScript; a source checkout needs a built bridge (`pnpm run build-bridge`) first.
369
- `plugins/pi-durable/bootstrap.mjs` is only the checkout path that re-exports it.
370
-
371
- Existing users who do not enable durable keep the same installation steps. For
372
- durable, native Pi owns credentials, model settings, SQLite sessions and recovery;
373
- keep them in place rather than copying credentials or migrating ordinary Pi
374
- transcripts. Native recovery does not prove exactly-once Entwurf dispatch or inbox
375
- read recovery. The contact provides garden attachment, visible identity and
376
- announce-only root-directed self-fetch. First native admission closed
377
- [#129](https://github.com/junghan0611/entwurf/issues/129) at reviewed main:
378
- visible fresh/callback, addressed receive and both real Pi ↔ pi-durable LIVE legs
379
- passed on one Linux host. Installed-bootstrap import-only proof is not a native
380
- runtime/TUI launch or a live Claude ↔ pi-durable receipt. This section states the
381
- installation contract; exact release/artifact acceptance is a separate floor.
382
- [#130](https://github.com/junghan0611/entwurf/issues/130) owns npm-only runtime
383
- supply, later Pi versions, ACP and UI follow-ups.
399
+ `--check` without such a repository is a named SKIP, never rebuild acceptance; the emitter
400
+ version (Node) is part of the pin.
384
401
 
385
402
  ## 3. Optional Claude Code native citizen
386
403
 
@@ -545,7 +562,7 @@ as a note rather than a fault.
545
562
 
546
563
  **entwurf sets no OMP version floor in code, and will not grow one on schedule.** Detection is
547
564
  presence-only (`command -v "${OMP_BIN:-omp}"`); there is no `entwurf.ompFloor`, no coherence
548
- gate, and no exact pin — unlike Node (`engines.node`), pi (`>=1.0.2 <1.1`) and Claude Code
565
+ gate, and no exact pin — unlike Node (`engines.node`), pi (`>=1.1.0 <1.2`) and Claude Code
549
566
  (`entwurf.claudeCodeFloor`), each of which has an enforcement point. That asymmetry is a
550
567
  decision, not an omission. A floor is the answer to a vendor that fails SILENTLY — Claude Code
551
568
  earned one because an older binary validates the exec manifest, drops `args` at runtime, and
@@ -640,7 +640,7 @@ server.tool("entwurf_fresh_call", "Open ONE fresh visible sibling beside you and
640
640
  "a running sibling. Nothing polls. " +
641
641
  "For EXISTING citizens use entwurf_v2 — this tool only creates, and entwurf_peers only reports. Model is REQUIRED and passed to the chosen " +
642
642
  "runtime CLI (`provider/model` for pi, an id/alias for Claude Code, `provider/model id` exactly as the catalog names it for pi-durable, a pattern for the rest). On tmux, copilot/omp/codex/pi-durable are refused BEFORE any window " +
643
- "opens when their birth, MCP, receive or visible-identity units are absent, pi-durable also when its operator-provided pinned runtime is absent or drifted, and codex also needs the " +
643
+ "opens when their birth, MCP, receive or visible-identity units are absent, pi-durable also on named refusals of its installed carrier or exact SDK set, and codex also needs the " +
644
644
  "operator-owned app-server socket entwurf never starts; in herdr they are refused by name first. " +
645
645
  "Optional placement.tmuxSession is a TMUX-ONLY seat naming ONE EXISTING session and " +
646
646
  "ALWAYS wins; omitted, the seat follows the CALLER, never the backend opened: a CODEX CALLER opens beside " +
@@ -25,7 +25,7 @@ import { randomBytes } from "node:crypto";
25
25
  /** The backends this rail can open. Fixed set, not a profile — a further one is a decision,
26
26
  * not a config entry. `copilot` was added by #82 RAIL 9, `omp` by #87 Bundle C, `codex`
27
27
  * by #95 after its system birth and app-server rails were measured, and `pi-durable` by #129
28
- * (the operator-provided durable app through the managed `entwurf pi-durable`). The set is joined to the
28
+ * (the durable app this package carries, through the managed `entwurf pi-durable`). The set is joined to the
29
29
  * citizen backends by `check-harness-admission-parity`: a harness that mints records but is
30
30
  * missing HERE is not an unwired convenience, it is a release blocker. */
31
31
  export const FRESH_CALL_BACKENDS = ["pi", "claude-code", "copilot", "omp", "codex", "pi-durable"];
@@ -156,9 +156,9 @@ export const FRESH_CALL_RUNTIME = {
156
156
  copilot: "entwurf",
157
157
  omp: "omp",
158
158
  codex: "codex",
159
- // #129: like copilot, a MANAGED verb and never the bare app. The durable app is source-only
160
- // and runs under the operator-provided runtime's own resolver; `entwurf pi-durable` is the one
161
- // fixed invocation that verifies that runtime against the pin and execs the packaged bootstrap.
159
+ // #129/#130: like copilot, a MANAGED verb and never the bare app. The durable app is this
160
+ // package's carrier and runs under the carrier's resolver; `entwurf pi-durable` is the one fixed
161
+ // invocation that verifies the carrier and its SDK set and execs the packaged bootstrap.
162
162
  "pi-durable": "entwurf",
163
163
  };
164
164
  /**
@@ -345,15 +345,13 @@ export function freshCall(params, env = process.env, nonce = mintNonce()) {
345
345
  }
346
346
  if (params.backend === "pi-durable") {
347
347
  // The framed first input is computed here only to MEASURE it against the bootstrap payload
348
- // cap; the same pure function composes it again below. The runtime is located and verified
349
- // with THIS process's env, before anything is placed. That is the bridge's env, not
350
- // necessarily the window's: a new-window pane inherits the tmux SERVER's environment
351
- // (measured, see SCRUBBED_INHERITED_ENV), and the window runs whatever `entwurf` PATH names.
352
- // The managed verb re-verifies with its own env before it execs anything, so the window never
353
- // runs an unverified runtime — but when HOME/XDG_DATA_HOME or the package closure differ, this
348
+ // cap; the same pure function composes it again below. The carrier is verified from THIS
349
+ // process's package closure, before anything is placed. The window runs whatever `entwurf`
350
+ // PATH names, and the managed verb re-verifies its own package before it execs anything, so
351
+ // the window never runs an unverified carrier — but when the two package closures differ, this
354
352
  // verdict and the window's can disagree, and the window is left showing its own refusal.
355
353
  const layout = piDurablePackageLayout();
356
- const runtime = layout === null ? null : checkPiDurableRuntime(env, layout);
354
+ const runtime = layout === null ? null : checkPiDurableRuntime(layout);
357
355
  const missing = piDurableFreshPreflight({
358
356
  model,
359
357
  firstInput: buildFreshCallPrompt({ backend: params.backend, task, callerGardenId, nonce }),
@@ -19,9 +19,9 @@
19
19
  * `{v:2,task}` payload, whose decoder caps `task` at 16000 characters. A framed
20
20
  * task over that cap would open a window whose bootstrap refuses its own argv.
21
21
  *
22
- * ── Then the runtime, then the four units ──
22
+ * ── Then the carrier, then the four units ──
23
23
  *
24
- * runtime operator-provided at the fixed locator and verified against the pin
24
+ * carrier the package's own pi-durable carrier and its declared SDK set, verified
25
25
  * (`pi-durable-runtime.ts`); passed in as that check's verdict.
26
26
  * birth the compiled contact in this package's closure — it mints the record.
27
27
  * MCP hand the compiled entwurf-bridge entry in the same closure — the contact spawns it.
@@ -32,7 +32,7 @@
32
32
  *
33
33
  * ── What this deliberately does NOT claim ──
34
34
  *
35
- * Filesystem truth about ONE package closure and ONE runtime directory. It does not prove the durable
35
+ * Filesystem truth about ONE package closure and the SDK it resolves. It does not prove the durable
36
36
  * app opens, the bridge connects, the doorbell arms or a garden id renders — that is runtime truth for
37
37
  * the clause 7 LIVE receipt. No spawn, no network, no mutation; every path arrives as an argument, so
38
38
  * this leaf imports nothing but types.