@junghanacs/entwurf 0.14.2 → 0.15.1

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 (87) hide show
  1. package/AGENTS.md +9 -5
  2. package/CHANGELOG.md +149 -0
  3. package/DELIVERY.md +72 -59
  4. package/README.md +120 -20
  5. package/VERIFY.md +10 -7
  6. package/demo/README.md +1 -1
  7. package/docs/acp-backend-rail.md +2 -2
  8. package/docs/external-mcp-host.md +26 -4
  9. package/docs/setup-clean-host.md +118 -18
  10. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +8 -6
  11. package/mcp/entwurf-bridge/dist/pi-extensions/entwurf-capabilities.json +1 -0
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/copilot-fresh-preflight.js +253 -0
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +10 -2
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +102 -28
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +77 -11
  16. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook-copilot.js +288 -0
  17. package/mcp/entwurf-bridge/src/index.ts +10 -6
  18. package/mcp/entwurf-bridge/tsconfig.build.json +2 -1
  19. package/package.json +22 -11
  20. package/pi/copilot-receive/entwurf-receive/extension.mjs +323 -0
  21. package/pi/entwurf-capabilities.json +1 -0
  22. package/pi/meta-bridge-copilot/.claude-plugin/marketplace.json +11 -0
  23. package/pi/meta-bridge-copilot/entwurf-meta-receive-copilot/.claude-plugin/plugin.json +5 -0
  24. package/pi/meta-bridge-copilot/entwurf-meta-receive-copilot/hooks/hooks.json +7 -0
  25. package/pi/meta-bridge-copilot/entwurf-meta-receive-copilot/scripts/copilot-hook-launch.sh +85 -0
  26. package/pi-extensions/entwurf-control.ts +17 -8
  27. package/pi-extensions/lib/copilot-fresh-preflight.ts +251 -0
  28. package/pi-extensions/lib/meta-sender-identity.ts +10 -2
  29. package/pi-extensions/lib/meta-session.ts +102 -29
  30. package/pi-extensions/lib/mux-fresh-call.ts +82 -11
  31. package/pi-extensions/meta-bridge-hook-copilot.ts +323 -0
  32. package/run.sh +1079 -186
  33. package/scripts/agy-bridge.sh +4 -2
  34. package/scripts/check-copilot-birth-hook.ts +1174 -0
  35. package/scripts/check-copilot-launch.ts +395 -0
  36. package/scripts/check-copilot-receive-arm.ts +734 -0
  37. package/scripts/check-copilot-statusline.ts +122 -0
  38. package/scripts/check-entwurf-capabilities.ts +25 -6
  39. package/scripts/check-fresh-cut-gate.sh +104 -27
  40. package/scripts/check-gate-qualification.ts +10 -1
  41. package/scripts/check-install-container.sh +2 -2
  42. package/scripts/check-install-surface.ts +1 -1
  43. package/scripts/check-meta-capability-source.ts +89 -5
  44. package/scripts/check-meta-doctor-oracle.sh +26 -0
  45. package/scripts/check-meta-manifest-schema.py +38 -0
  46. package/scripts/check-meta-receiver-marker.ts +25 -2
  47. package/scripts/check-meta-session.ts +32 -0
  48. package/scripts/check-setup-qualification.sh +126 -0
  49. package/scripts/copilot-bridge-doctor.sh +242 -0
  50. package/scripts/copilot-bridge-install.sh +384 -0
  51. package/scripts/copilot-bridge-oracle.sh +223 -0
  52. package/scripts/copilot-bridge-uninstall.sh +137 -0
  53. package/scripts/copilot-launch.sh +236 -0
  54. package/scripts/copilot-mcp-bridge.sh +177 -0
  55. package/scripts/copilot-mcp-config.py +221 -0
  56. package/scripts/copilot-receive-bridge.sh +483 -0
  57. package/scripts/copilot-statusline-bridge.sh +149 -0
  58. package/scripts/copilot-statusline-config.py +201 -0
  59. package/scripts/copilot-statusline.sh +68 -0
  60. package/scripts/dev-bin.sh +53 -9
  61. package/scripts/fake-copilot-vendor.sh +67 -0
  62. package/scripts/meta-bridge-hook-log.sh +17 -5
  63. package/scripts/mutants/capability-cache.json +64 -0
  64. package/scripts/mutants/copilot-birth.json +244 -0
  65. package/scripts/mutants/copilot-launch.json +187 -0
  66. package/scripts/mutants/copilot-receive.json +263 -0
  67. package/scripts/mutants/fresh-cut.json +17 -0
  68. package/scripts/mutants/mux-fresh-call.json +216 -2
  69. package/scripts/mutants/pack-install.json +17 -0
  70. package/scripts/mutants/pi-package-ownership.json +92 -0
  71. package/scripts/mutants/setup-verdict.json +148 -0
  72. package/scripts/mutants/source-install.json +32 -0
  73. package/scripts/pi_settings_io.py +22 -0
  74. package/scripts/raw-async-delivery/README.md +170 -125
  75. package/scripts/raw-async-delivery/copilot-enqueue-addressed.sh +35 -0
  76. package/scripts/raw-async-delivery/copilot-extension-receive/extension.mjs +123 -0
  77. package/scripts/register-pi-package.py +525 -7
  78. package/scripts/register-pi-provider.py +162 -12
  79. package/scripts/smoke-agy-install-state.sh +86 -30
  80. package/scripts/smoke-agy-statusline-state.sh +9 -6
  81. package/scripts/smoke-copilot-mcp-state.sh +153 -0
  82. package/scripts/smoke-copilot-statusline-state.sh +131 -0
  83. package/scripts/smoke-mux-fresh-call-live.ts +2 -0
  84. package/scripts/smoke-mux-lifecycle-live.ts +3 -1
  85. package/scripts/smoke-setup-verdict.sh +291 -0
  86. package/scripts/smoke-user-scope-citizen.sh +388 -1
  87. package/scripts/tsconfig.json +1 -0
package/AGENTS.md CHANGED
@@ -28,9 +28,9 @@ For agents that own this repo: invariant principles and reproducible verificatio
28
28
  - **entwurf-core (v2)** owns garden-id addressing, peer facts, liveness interfaces, dispatch decisions, rail choice, and delivery evidence.
29
29
  - **Record authority** owns citizen identity. Every addressable citizen uses the same V3 `MetaIdentity` schema. `backend` selects capability/rail behavior; it does not create an identity hierarchy.
30
30
  - **pi adapter** attaches a pi session to a record at `session_start`, hosts the record-keyed control socket, and exposes the native pi tool surface.
31
- - **Native bridges** register already-running native sessions without taking over their transcript or auth: Claude Code is mailbox/self-fetch; Antigravity is probe-backed native-push. Codex has archived probe evidence, but its managed native lane was declined because pi already supplies the official GPT provider path; do not duplicate it as a native citizen or ACP backend.
31
+ - **Native bridges** register already-running native sessions without taking over their transcript or auth: Claude Code and Copilot CLI are mailbox/self-fetch (a Claude hook arms the watch; a forked Copilot extension holds it); Antigravity is probe-backed native-push. Codex has archived probe evidence, but its managed native lane was declined because pi already supplies the official GPT provider path; do not duplicate it as a native citizen or ACP backend.
32
32
  - **ACP plugin** registers provider `entwurf` inside a pi host session and drives a backend under an isolated overlay. The host pi session is already a record-backed socket citizen; the plugin does not mint another citizen/socket/peer layer.
33
- - **mux is launch-only and deliberately small.** Shipped: the tmux placement leaf (`mux-placement.ts` — inspect/append/close inside the caller's own session), the visible runtime launch composition (`mux-launch.ts`), the fresh-call composition (`mux-fresh-call.ts`), and the cwd-aware resume placement composition (`mux-resume-call.ts`). Fresh call is exposed as `entwurf_fresh_call`; visible same-id resume is `entwurf_resume_call`, composed at the two public surfaces by injecting `mux-resume-call` into the v2-side `entwurf-v2-visible-resume.ts`. The exact import graph is enumerated in [docs/mux-launch-rail.md](./docs/mux-launch-rail.md) §11. `entwurf_v2` behavior is unchanged and delivery still never imports launch. Fresh call learns a new sibling's garden id from the CALLBACK it makes, never from a lookup — so the pre-injected-token → identity-lookup design (rail §6) is **closed, not paused**. Do not reopen it without new evidence and explicit GLG re-approval. Fresh-call requires one explicit model and passes it in each runtime's measured CLI dialect (Pi `--model <provider/model>`, Claude Code `--model=<id-or-alias>`); it also takes ONE optional literal absolute `cwd` (#73 — omitted/`""` means the caller's own directory; no trim, no realpath, no project-name resolver; classified by the shared `classify-tmux-cwd.ts` leaf; the receipt echoes the REQUEST only), so a cross-repo fresh sibling is a fresh-call fact and never a reason to resume a dormant record. Resume takes only an existing target id and gets transcript/model/provider/cwd from its record. Do not grow either narrow carrier into a generic driver, harness profile, arbitrary command/env selection, or a second creation API. Ownership and import prohibitions: [docs/mux-launch-rail.md](./docs/mux-launch-rail.md) §11.
33
+ - **mux is launch-only and deliberately small.** Shipped: the tmux placement leaf (`mux-placement.ts` — inspect/append/close inside the caller's own session), the visible runtime launch composition (`mux-launch.ts`), the fresh-call composition (`mux-fresh-call.ts`), and the cwd-aware resume placement composition (`mux-resume-call.ts`). Fresh call is exposed as `entwurf_fresh_call`; visible same-id resume is `entwurf_resume_call`, composed at the two public surfaces by injecting `mux-resume-call` into the v2-side `entwurf-v2-visible-resume.ts`. The exact import graph is enumerated in [docs/mux-launch-rail.md](./docs/mux-launch-rail.md) §11. `entwurf_v2` behavior is unchanged and delivery still never imports launch. Fresh call learns a new sibling's garden id from the CALLBACK it makes, never from a lookup — so the pre-injected-token → identity-lookup design (rail §6) is **closed, not paused**. Do not reopen it without new evidence and explicit GLG re-approval. Fresh-call requires one explicit model and passes it in each runtime's measured CLI dialect (Pi `--model <provider/model>`, Claude Code `--model=<id-or-alias>`, Copilot `--model <name>` beside `--interactive <prompt>` and the explicit `--yolo` policy — a GLG width decision, 2026-08-25, after a callback-only `--allow-tool` grant stopped the sibling at every task tool); the Copilot backend opens through entwurf's OWN managed invocation (`entwurf copilot`), never the bare vendor, and its four required capabilities — birth, MCP hand, receiver, visible footer — are decided by `copilot-fresh-preflight.ts` BEFORE the tmux mutation, so a missing unit is a named refusal instead of a dead window; it also takes ONE optional literal absolute `cwd` (#73 — omitted/`""` means the caller's own directory; no trim, no realpath, no project-name resolver; classified by the shared `classify-tmux-cwd.ts` leaf; the receipt echoes the REQUEST only), so a cross-repo fresh sibling is a fresh-call fact and never a reason to resume a dormant record. Resume takes only an existing target id and gets transcript/model/provider/cwd from its record. Do not grow either narrow carrier into a generic driver, harness profile, arbitrary command/env selection, or a second creation API. Ownership and import prohibitions: [docs/mux-launch-rail.md](./docs/mux-launch-rail.md) §11.
34
34
  - **One delivery verb:** `entwurf_v2` addresses an existing garden id. Current routes are live control-socket send, active self-fetch mailbox enqueue, and probe-alive native-push. NO route starts a process: the hidden background resume for a dormant citizen was withdrawn under the visible-first rule, so a dormant in-domain citizen rejects as `dormant-fire-forget-unsupported` and the intent axis is single-valued. Every other complementary state pair rejects honestly too. Fresh creation is a separate verb — `entwurf_fresh_call` — and it returns a launch receipt only; the new sibling's address arrives asynchronously as the sender envelope of its nonce callback.
35
35
 
36
36
  ## Hard Rules
@@ -41,7 +41,7 @@ For agents that own this repo: invariant principles and reproducible verificatio
41
41
  4. **Dispatch is computed from live facts.** Never store liveness. Never infer send/resume from session type before resolving the target and probing its rail.
42
42
  5. **Rejects are real.** Wrong intent, dead/drifted identity, undeliverable mailbox, ambiguous address, or indeterminate probe returns a reject and mutates nothing. No cosmetic success or silent fallback.
43
43
  6. **MCP is explicit.** Only explicit `mcpServers` wiring. No ambient `~/.mcp.json` scan or automatic retrieval.
44
- 7. **Meta-record store contract is one contract.** Record body is authority; filename must agree with the body; every active entry is a regular non-symlink file readable by the live V3 schema; `nativeSessionId` ownership is unique. Identity writers and doctor certify the whole active store before writing. Address-bearing reads use `readAddressableMetaIdentity`; targeted relay reads keep the documented per-entry contract. `readStoreRecordFile`/`O_NOFOLLOW` and the lstat policy layer are both load-bearing—do not merge or bypass them. No legacy reader/migrator: quiesce and run `entwurf meta-bridge-fresh-cut` when the generation is unreadable. Source and gates: `meta-session.ts`, `check-meta-*`, `check-fresh-cut-gate`.
44
+ 7. **Meta-record store contract is one contract.** Record body is authority; filename must agree with the body; every active entry is a regular non-symlink file readable by the live V3 schema; `nativeSessionId` ownership is unique. Identity writers and doctor certify the whole active store before writing. Address-bearing reads use `readAddressableMetaIdentity`; targeted relay reads keep the documented per-entry contract. `readStoreRecordFile`/`O_NOFOLLOW` and the lstat policy layer are both load-bearing—do not merge or bypass them. No legacy reader/migrator: quiesce and run `entwurf meta-bridge-fresh-cut` when the generation is unreadable. An unknown-backend defect is a stale deployed reader, not a rotten generation: redeploy the sibling unit; do not fresh-cut. `doctor-meta-bridge` already names that — run it after `META_BACKENDS` changes. Source and gates: `meta-session.ts`, `check-meta-*`, `check-fresh-cut-gate`.
45
45
  8. **GC reclaims process resources, never memory/data.** Records and transcripts are preserved or archived; they are not casually deleted.
46
46
  9. **This is not a second harness.** No prompt reconstruction, transcript hydration, tool-result ledger, credential mediation, or harness emulation. Each backend owns auth and transcript state.
47
47
  10. **Native-push is its own rail.** It is not a mailbox or pi socket in disguise. Antigravity replyability is record-backed plus probe-alive; no receiver marker, watch state, or resume authority is invented for it.
@@ -51,6 +51,7 @@ For agents that own this repo: invariant principles and reproducible verificatio
51
51
  14. **Native hook ownership is structural.** Claude hooks use the shipped exec-form launcher and provenance token; marker writers/readers share `isPlausibleOwnerPid`; no shell-form fallback, ancestry guess, or retired pid carrier. entwurf requires Claude Code `>=2.1.217` and enforces that floor itself because upstream gives no fail-loud — an older Claude validates the exec manifest, then drops `args` at runtime and reports success. The number is derived from `package.json` `entwurf.claudeCodeFloor`, never retyped as a second source. Currently certified axis is Linux desktop/workstation. Source/gates: `hook-launch.sh`, `meta-session.ts`, `check-hook-launch-topology`, `check-claude-floor-coherence`, `check-meta-doctor-oracle`.
52
52
  15. **Crash, don't warn.** Bad config/path/model/store state throws. Empty catches are only for bounded environment probing; operator diagnostics go to stderr.
53
53
  16. **mux is launch, never delivery.** A tmux window/pane handle is an ephemeral operator view, not an address: it mints no garden id, stores no record, and reports no liveness. Screen text and keystrokes are never an `entwurf_v2` receipt. Mux owns only placement and fixed-runtime launch; fresh identity correlation stays in callback envelopes, while same-id resume identity/liveness/locking stays on the v2 side of an injected launch seam.
54
+ 17. **Entwurf installs itself; setup composes what the operator already chose.** Package installation and source bootstrap supply Entwurf's own bytes, bins, dependencies and development fixtures only. They never install a harness binary, subscription, credential or login — `pi` has no privileged exception. `setup` detects already-present harnesses by capability and completes each detected integration; absence is an explicit zero-state SKIP, while a detected-but-incomplete integration is named non-green rather than cosmetic success. Source-only pinned Pi dev dependencies are build/test fixtures, not a product promise that neutral npm consumers receive Pi. Installation portability and rail/runtime support are separate evidence axes: Linux proof never certifies macOS or native Windows, and WSL counts as Linux rather than Windows.
54
55
 
55
56
  Detailed incident histories belong in CHANGELOG/issues/BASELINE and source-adjacent comments, not in this prompt. When a concise rule and old archaeology disagree, verify source + gate and repair the stale prose.
56
57
 
@@ -89,7 +90,7 @@ A `--entwurf-control` pi session is a citizen for the same reason a native bridg
89
90
 
90
91
  - **control-socket domain (currently `pi`)**: socket liveness, per-target lock, live send, and a dormant cell that rejects.
91
92
  - **No relaunch transport exists inside delivery.** `spawn-bg` — a detached, window-less resume child — was removed under the visible-first rule, not deprecated behind a reject, and `entwurf_v2` still starts no process: a dormant socket-domain citizen is refused as `dormant-fire-forget-unsupported`. Reopening one is the separate lifecycle verb `entwurf_resume_call`, which is pi-only (`target-not-pi` otherwise), returns a LAUNCH receipt and an OBSERVATION receipt that are never merged, releases its per-gid lock on every path, and on an unobserved socket leaves the visible window open rather than retrying. No watcher, no retry, no supervisor. Do not re-route it through `entwurf_v2` and do not describe a spawn domain that does not exist.
92
- - **self-fetch domain (currently Claude Code)**: active receiver + mailbox deliverability; no resume authority.
93
+ - **self-fetch domain (Claude Code, Copilot CLI)**: active receiver + mailbox deliverability; no resume authority. The two arm that receiver through different vendor surfaces — a Claude hook that emits watchPaths, a Copilot first-party extension that holds the watch in a forked child — and the marker records which, because the pid a reader verifies differs.
93
94
  - **native-push domain (currently Antigravity)**: adapter probe + direct injection; no mailbox and no resume authority.
94
95
  - `origin: "pi-session" | "meta-session" | "external-mcp"` records sender provenance. It is not the citizen identity schema and not a hierarchy.
95
96
  - `entwurf_peers` reports record citizens and liveness facts only. It never embeds routing verbs or socket addresses for peers.
@@ -111,6 +112,7 @@ A `--entwurf-control` pi session is a citizen for the same reason a native bridg
111
112
  - A new issue brings the best available observation plus an executable next measurement. Recovering a missing signature may be the first acceptance; an idea with neither evidence nor a next measurement is not an issue.
112
113
  - No collection points, umbrella trackers, or fallout buckets. Merge issues only when they share one cause and one acceptance.
113
114
  - Sweep manually after a release and before opening an issue. Solved work closes at its durable SHA; it does not wait for the next release.
115
+ - **An issue body is a snapshot; the thread is the live contract.** A body written before GLG stated what the work is *for* will disagree with the thread, and a reader who opens only the body inherits the stale half — including its fences, which is how a fence once forbade the very deliverable the lane existed to produce (#82, 2026-08-20). When they disagree the thread wins. Whoever notices owes the body an edit that strikes the withdrawn clause and says why it was there; deleting it silently makes the queue tidy and the lesson invisible.
114
116
 
115
117
  ## Verification
116
118
 
@@ -180,7 +182,7 @@ implement → affected focused gates → independent review → one amendment bu
180
182
  - Every `.ts` file belongs to one typecheck fence: root emit-capable config, MCP strip-types config, or scripts strip-types config. Do not hide files with `exclude`.
181
183
  - Root pi extensions import TypeBox through `@earendil-works/pi-ai`; do not mix direct `@sinclair/typebox` types.
182
184
  - MCP/scripts use explicit `.ts` imports where Node strip-types requires them. Installed operator surfaces route to compiled JS.
183
- - pi runtime range is `>=0.84.2 <0.85` with devDep exact `0.84.2`; re-evaluate loader aliases and `/compat` at every minor ceiling. The ceiling moves on measurement, never on assumption, and a previous bump's argument is never reused: at 0.83.0→0.84.0 `compat.ts` was still byte-identical but `loader.ts` was NOT, so the diff itself had to be read and judged reachable-or-not. Per-bump hashes, diff judgments, and reachability findings live in the ROADMAP **Dep bump(별도 트랙)** ledger — keep them there, not here.
185
+ - pi runtime range is `>=0.84.3 <0.85` with devDep exact `0.84.3`; re-evaluate loader aliases and `/compat` at every minor ceiling. The ceiling moves on measurement, never on assumption, and a previous bump's argument is never reused: at 0.83.0→0.84.0 `compat.ts` was still byte-identical but `loader.ts` was NOT, so the diff itself had to be read and judged reachable-or-not. Per-bump hashes, diff judgments, and reachability findings live in the ROADMAP **Dep bump(별도 트랙)** ledger — keep them there, not here.
184
186
  - ACP pins are recorded in `package.json` and checked by `check-dep-versions`/`check-acp-sdk-surface`; do not describe a dependency bump as a behavioral fix without evidence.
185
187
 
186
188
  ## Working Style
@@ -206,12 +208,14 @@ An overgrowth is built from locally correct steps; what fails is the absence of
206
208
  - **Unrelated meta-infra never rides a capability lane.** The source-adjacent gate/mutant that proves a capability's contract belongs in the same change as that capability — the removal/repair rule above is untouched. What stays out of a feature commit candidate is unrelated verification machinery: scheduling rework, selectors, caches, receipts, floor restructuring. That pain is recorded and handled in its own subtraction lane later.
207
209
  - **Stop signal — evidence outgrowing the product.** When verification/meta-tool changes grow larger than the capability change they serve, stop and report to GLG. This is an operator-judgment trigger, deliberately not a mechanized ratio gate.
208
210
  - **Claim only what the evidence carries.** "The full floor was green once on the declared candidate" is strong enough; a stronger sentence mints proof obligations, and those obligations mint subsystems.
211
+ - **A claim that crosses sessions carries its evidence state.** Measured here (name the receipt), read at `file:line`, read from an external artifact (name the path), inherited and unchecked (name the source) — and design proposals in a box of their own, since a proposal is adopted or decided differently, never measured. This repo is where siblings from many models each get a few turns, so a bare sentence costs the next one its turn re-deriving the ground, and leaves it only "believe or refute" when the honest move is "that carries no receipt, so I measured it." Retire claims, not people. Receipts in host-local paths do not travel: paste the decisive lines into the artifact that crosses.
209
212
  - **Risk classes are not equal.** Data loss, identity authority, false delivery success, install destruction, and secrets get fail-closed strength. Doc tense, future possibility, and total environment-byte binding get repaired when seen — they do not justify new gate machinery.
210
213
 
211
214
  ## Next and References
212
215
 
213
216
  - [NEXT.md](./NEXT.md) — current priority and exact next move; branch work uses disposable `NEXT--<branch>.md`.
214
217
  - [ROADMAP.md](./ROADMAP.md) — forward direction and deferred lanes.
218
+ - [docs/adding-a-harness.md](./docs/adding-a-harness.md) — **first entry point for putting a NEW harness in the garden.** The order the eight steps are actually walked in (lane choice, vendor measurement, backend registration, birth, statusline, MCP hand, sender identity, receive, grade), what each owes before the next may start, and which of the other docs owns each slice. It routes; it grants nothing — Hard Rule 7 remains the authority on the meta-record store contract its registration step touches, and the gates and doctors it names remain the truth.
215
219
  - [docs/acp-backend-rail.md](./docs/acp-backend-rail.md) — ACP adapter contract and current entry conditions.
216
220
  - [DELIVERY.md](./DELIVERY.md) — delivery capability/evidence coordinates.
217
221
  - [VERIFY.md](./VERIFY.md) / [BASELINE.md](./BASELINE.md) — verification protocol and recorded evidence.
package/CHANGELOG.md CHANGED
@@ -4,6 +4,155 @@ All notable changes to this project will be documented here. Format follows [Kee
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## 0.15.1 — 2026-08-27
8
+
9
+ This patch is the Linux install-honesty floor for #86: Entwurf installs itself only,
10
+ `setup` composes harnesses the operator already chose, and a detected integration that
11
+ cannot be completed makes the command non-green. It is not a new garden capability.
12
+ macOS and native-Windows implementation move to #78; this cut makes no cross-platform
13
+ support claim.
14
+
15
+ ### Changed
16
+
17
+ - **`setup` is presence-driven composition, not recruitment.** Mode is a named
18
+ source-versus-installed branch before any prerequisite check or write. Each detected
19
+ harness (pi, Claude Code, Copilot, agy) is completed independently; absence is
20
+ zero-state SKIP; below-floor or incomplete is named FAIL and a nonzero exit. The old
21
+ unconditional `DONE ... green` is gone — the summary is computed from component
22
+ outcomes. Pi is optional-by-presence with the package-derived floor `>=0.84.3 <0.85`.
23
+ A detected Copilot composes all four native units (birth → MCP → receiver → visible
24
+ footer). Installed-package setup never runs npm/pnpm inside `node_modules`. (#86)
25
+ - **The shared Pi user-scope registration has a recorded owner.** Silent
26
+ last-writer-wins normalization is retired. A second root's install/setup/remove refuses
27
+ with zero settings writes and names `takeover-user-scope`; only that explicit operator
28
+ verb moves the entry (old→new reported). The inverse removes only the recorded owner's
29
+ exact entry. (#86 C2)
30
+ - **Setup no longer mutates credential stores.** The unconditional `sync_auth` path that
31
+ copied the Anthropic OAuth object to an `entwurf` alias is removed. Hosts that already
32
+ ran the legacy path keep the alias and `auth.json.bak` as a documented manual cleanup,
33
+ not an automated one. (#86 A5)
34
+
35
+ ### Added
36
+
37
+ - **Copilot birth has a package-owned inverse.** `uninstall-copilot-bridge` uses the
38
+ qualified `plugin@marketplace` identity, runs a read-only ownership/safety preflight
39
+ before any vendor write, and refuses to remove an unproven foreign unit. Installer,
40
+ inverse, and doctor share one structural oracle. (#86 C3a)
41
+ - **Packed-consumer and all-absent setup rows are first-class fixtures.**
42
+ `smoke-setup-verdict` and the installed `entwurf setup` path inside `check-pack-install`
43
+ prove absence, independence, false-success refusal, and the named installed-versus-source
44
+ branch without a model turn. That npm-consumer harness is the Linux install evidence
45
+ #78 waits on. (#86)
46
+
47
+ ### Fixed
48
+
49
+ - **Source setup now exposes the `entwurf` operator command Copilot fresh requires.**
50
+ `./run.sh setup` manages `~/.local/bin/entwurf` as an ownership-checked symlink to the
51
+ current checkout's `run.sh`, with per-bin state and an honest inverse. npm consumers
52
+ already received this command through package bin linking; the missing source half caused
53
+ `entwurf_fresh_call {backend:"copilot"}` to reject `runtime-unresolved` unless an unrelated
54
+ global package happened to mask the defect. Source setup now fails loud when that
55
+ operator path is foreign, outside PATH, or shadowed; helper units are attempted
56
+ independently and a foreign helper is a named FAIL, never a warning followed by cosmetic
57
+ success. The managed `entwurf copilot` boundary and every fresh/preflight/delivery
58
+ contract are unchanged. Discovered while rechecking #82. (#86)
59
+
60
+ ### Verification
61
+
62
+ - **`pnpm run check:full`** — PASS, exit 0, 252s standalone / 247s inside the gate
63
+ on the 0.15.1 versioned tree (HEAD `4a23af1` + uncommitted changelog/version).
64
+ - **`LIVE=1 ./run.sh release-gate /tmp/entwurf-release-gate-0.15.1.hAAn7U --cut`** —
65
+ **MUST PASS=21 FAIL=0 SKIP=0, BEHAVIOR PASS=1 FAIL=0 SKIP=0, `cut: OK`.**
66
+ `check-gate-qualification` inside the gate killed **277/277** mutants across 33
67
+ lanes. Log: `/tmp/entwurf-release-gate-0.15.1.hAAn7U/release-gate.log`
68
+ (SHA-256 `aa1364922301e685c650670dd6556a3c27feacdf1481d850d8e2ef56ef5cb23e`).
69
+
70
+ ### Notes
71
+
72
+ - #78 owns macOS and native-Windows implementation. WSL remains Linux evidence.
73
+ - Native-harness doctors stay the per-leaf live-certification surface. Setup writes
74
+ artifacts; a new session is still required before `doctor-meta-bridge` / Copilot receive
75
+ can go green on a host that already had processes open.
76
+
77
+ ## 0.15.0 — 2026-08-25
78
+
79
+ This release admits Copilot CLI as a full self-fetch garden citizen — birth, an owned
80
+ MCP hand, record-backed sender identity, an installed first-party receive extension, and
81
+ a visible-fresh launch path — closing #82, and fixes the fresh-launch YOLO regression the
82
+ admission work exposed.
83
+
84
+ ### Added
85
+
86
+ - **Copilot CLI is a self-fetch garden citizen.** `birthCopilotCitizen` upserts
87
+ `(backend:"copilot", nativeSessionId)` into the shared V3 record store, gives the
88
+ session a garden id, an owned `entwurf` MCP hand, a footer statusline slot showing that
89
+ id, and record-backed sender identity on every dispatched message. The receive rail is
90
+ an installed first-party extension (`run.sh install-copilot-receive`) that binds to the
91
+ V3 record, arms a watcher, and rings a doorbell the model drains with
92
+ `entwurf_inbox_read`; `wakeMode` is `self-fetch`, so dispatch reaches the mailbox rail —
93
+ armed sessions get `delivered`, unarmed or stale sessions get the honest
94
+ `mailbox-undeliverable` refusal. Launch is exclusively through the owned invocation
95
+ `entwurf copilot`, which sets `COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS` for that one
96
+ process; a session started any other way is silently inert by design, and
97
+ `doctor-copilot-receive` reads the live CLI environment to catch that class. (#82)
98
+ - **Fresh Copilot siblings are admitted through the same preflight contract as birth.**
99
+ `copilot-fresh-preflight.ts` decides birth, MCP hand, receiver, and visible footer
100
+ BEFORE the tmux mutation, so a missing capability is a named refusal instead of a dead
101
+ window. `entwurf_fresh_call` takes one explicit model in Copilot's measured CLI dialect
102
+ (`--model <name>` beside `--interactive <prompt>`) and opens through `entwurf`'s own
103
+ managed invocation, never the bare vendor binary. (#82)
104
+ - **Visible-fresh and D6 receive are LIVE-accepted on one host.** 2026-08-23 D6 receive
105
+ acceptance (garden `20260823T181316-d9f6ba`, CLI 1.0.80): `joined → armed → doorbell →
106
+ rang`, mailbox enqueue/read timestamps, and a model reply on the same
107
+ record/native/garden-id chain. 2026-08-25 visible-fresh acceptance: launch window `@89`,
108
+ nonce `mux-fresh-call-690529ae99f99faa2252aefb`, exact-callback garden
109
+ `20260825T085721-f68be0`, one `entwurf_v2` mailbox enqueue plus a same-garden reply, and
110
+ an operator-observed footer garden id on a healthy multi-turn window. Both rows are
111
+ evidence level L4 (one host) and stay unmerged; visible fresh is operator-metered and is
112
+ not a release-gate MUST.
113
+
114
+ ### Fixed
115
+
116
+ - **Fresh Copilot siblings now default to `--yolo`, matching the profile a human gets
117
+ from `entwurf copilot`.** `mux-fresh-call.ts` previously passed a callback-only
118
+ `--allow-tool=entwurf-bridge(entwurf_v2)` grant, which caused `copilot-launch.sh`'s
119
+ explicit-policy scan to suppress its own `--yolo` injection — every task-tool call then
120
+ stopped on a confirmation prompt the new sibling could not answer, making it practically
121
+ unusable. GLG operator LIVE on 2026-08-25 confirmed the missing `YOLO` footer and the
122
+ per-task-tool stalls; the fix restores the default without adding a permission
123
+ parameter to the fresh-call API or changing the manual `entwurf copilot` override
124
+ behavior. (#82 follow-up)
125
+ - **Pi runtime pin moves to `0.84.3`.** Certified development pin and closed peer range
126
+ are now `0.84.3` / `>=0.84.3 <0.85`. `compat.ts` stayed byte-identical at the previous
127
+ bump but `loader.ts` did not, so the diff was read and judged reachable before moving
128
+ the ceiling; the argument is not reused across bumps and each future ceiling move is
129
+ judged on its own diff.
130
+
131
+ ### Verification
132
+
133
+ - **`pnpm run check:full`** — PASS, exit 0, 406s standalone on the prepared HEAD.
134
+ - **`LIVE=1 ./run.sh release-gate <scratch> --cut`** — **MUST PASS=21 FAIL=0 SKIP=0,
135
+ BEHAVIOR PASS=1 FAIL=0 SKIP=0, `cut: OK`.** `check-gate-qualification` inside the gate
136
+ killed **252/252** mutants across 30 lanes. Log:
137
+ `/tmp/entwurf-release-gate-0.15.0.run2.fB2LLP/release-gate.log` (SHA-256
138
+ `9a00a22e8b4ca715ad0b955b51c99a2bacc385bf0c225180026948a4618e5ff6`).
139
+ - A first attempt on the same prepared HEAD (scratch `.../entwurf-release-gate-0.15.0.7yUIFH`)
140
+ hit one MUST FAIL in `smoke-mux-lifecycle-live`'s cleanup launcher-integrity self-fence:
141
+ all 78 lifecycle assertions passed, but the Claude Code launcher symlink changed target
142
+ and content mid-run (`2.1.243`→`2.1.245`) because auto-update was still on the default
143
+ channel. GLG pinned `autoUpdatesChannel: stable` before the rerun above; this was an
144
+ environment race during the LIVE run, not a defect in the 0.15.0 candidate.
145
+
146
+ ### Notes
147
+
148
+ - Copilot's D7 grade is PARTIAL: reply and read receipts are observed; completion
149
+ taxonomy and long-haul operation are not. D3 (second-session isolation of an owned
150
+ invocation) is PENDING — observed once, but the decisive log was lost to scratch
151
+ cleanup before it could be preserved; re-measurement is tracked outside this release.
152
+ - #76 (subscription-first refusal of `openrouter/*` sibling launches), #78
153
+ (macOS/native-Windows portability evidence), #80 (public vocabulary), #83, #84, #85, and
154
+ the remaining #72 field-cause investigation stay outside this release.
155
+
7
156
  ## 0.14.2 — 2026-08-20
8
157
 
9
158
  This patch makes bridge availability a property of the exact invocation each harness will run, preserves child-exit facts across ACP transport closure, and records Copilot delivery as probe evidence without admitting a new citizen rail.
package/DELIVERY.md CHANGED
@@ -74,14 +74,22 @@ D8 robustness: partial reason="..."
74
74
 
75
75
  ## Current matrix
76
76
 
77
+ **Vocabulary.** *Owned* in this file names entwurf ownership of a concrete invocation,
78
+ installer, or config writer. Historical receipts may say *managed* for that same ownership
79
+ axis; neither word is an admission grade or a synonym of *supported*. A pre-contract probe
80
+ can be owned without being supported; a supported harness still has to walk
81
+ [`docs/adding-a-harness.md`](./docs/adding-a-harness.md) step 9.
82
+
77
83
  | Harness / surface | Product status | Capability | Transport and boundary |
78
84
  |---|---|---|---|
79
85
  | **pi native Entwurf** | shipped | D7; D8 partial | Record-addressed Unix control socket. A record-less socket is diagnostic only and never dispatched. |
80
86
  | **Claude Code interactive `>=2.1.217`** | shipped; Linux certified | D6; D7/D8 partial | Per-session mailbox + exec-form `FileChanged`/`asyncRewake`. B2 proved idle wake and same-session continuity on one NixOS host. |
81
87
  | **Antigravity / agy** | shipped | D6; D7 partial | Record-backed native-push through LS gRPC `agentapi send-message`; no mailbox or receiver marker. |
82
- | **Codex app-server-backed TUI** | verified probe | D7; D8 unproven | WebSocket-over-UDS `turn/start` into a live `threadId`; status events expose completion. No managed citizen lane yet. |
88
+ | **Codex app-server-backed TUI** | verified probe | D7; D8 unproven | WebSocket-over-UDS `turn/start` into a live `threadId`; status events expose completion. No owned native-citizen install/invocation lane. |
83
89
  | **Codex embedded TUI** | deferred | D0 partial | No supported receive socket/hook on the measured standalone shape. |
84
- | **Copilot CLI TUI+server** | verified probe | D7; D8 unproven | **Old chronological-slice run; the named-turn probe in the tree is unrun.** Official SDK over hidden `--ui-server`: foreground native id + metadata, two-session addressed idle enqueue, same-session auto-model reply, completion events read back through the official session event-history API. Loopback RPC authentication is not established; no managed citizen lane. Evidence is L4 direct-native on ONE Linux workstation, host-local stdout, not archived. |
90
+ | **Copilot CLI first-party extension** | raw transport probe; superseded by the owned product unit | D7 path observed; D3 control receipt incomplete; D8 unproven | CLI-spawned extension over stdio JSON-RPC; `joinSession()` + documented `fs.watch` `session.send({mode:"enqueue"})`. Idle wake, exact-marker reply, and completion passed on 2026-08-23 (CLI 1.0.80, L4, one Linux host). Two-process isolation was observed but its decisive B log was not preserved. Kept as the transport receipt the owned receive unit was built on; the shipped unit differs deliberately it announces the inbox instead of injecting the body. |
91
+ | **Copilot CLI garden citizen** | shipped in 0.15.0; send + receive + visible fresh accepted on one host | D6; D7 partial; D3 pending; D8 unproven | Birth, garden id, MCP hand and record-backed sender identity are accepted; the RECEIVER is an installed first-party extension that binds to the V3 record, writes a receiver marker owned by the WATCHER pid, and rings a doorbell the model drains with `entwurf_inbox_read`. `wakeMode` is `self-fetch`, so dispatch reaches the mailbox rail: armed → delivered, unarmed/stale → the honest `mailbox-undeliverable` refusal. **D6 is the owned-invocation LIVE acceptance of 2026-08-23** — garden `20260823T181316-d9f6ba`, native `20fe30c8-b2bc-4600-91a0-8a409131be51`, CLI 1.0.80: receive log `joined`→`armed`→`doorbell fresh=1`→`rang`, mailbox `lastEnqueuedAt 09:23:41.235Z` / `lastReadAt 09:23:56.480Z`, and a model reply on the same record/native/gid chain. **Visible fresh (step 9 clause 7) is a separate LIVE, 2026-08-25** — launch window `@89`/`%89` nonce `mux-fresh-call-690529ae99f99faa2252aefb`; exact-callback garden `20260825T085721-f68be0`; one `entwurf_v2` → `meta-mailbox → enqueued`; same garden `lastReadAt 2026-08-24T23:57:47.784Z` plus same-gid reply; GLG saw footer garden id and a healthy multi-turn window. Those rows stay unmerged. D7 is PARTIAL: reply and read receipt were observed, the completion taxonomy and long-haul operation were not. D3 (second-session isolation of an owned invocation) is PENDING — observed once, decisive log lost to scratch cleanup. Evidence level L4: one host. Launch through the owned invocation `entwurf copilot`, which sets `COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS` for that one process; `doctor-copilot-receive` reads live CLI environments because a session launched without it is silently inert. Visible fresh is operator-metered and is not a release-gate MUST. |
92
+ | **Copilot CLI TUI+server** — *withdrawn lane, kept as evidence* | rejected | D7; D8 unproven | Older official-SDK probe over hidden `--ui-server`; idle enqueue worked, but loopback RPC authentication was not established. The bundled extension supersedes this candidate without reviving it. |
85
93
  | **ACP Claude / Cortex** | shipped runtime, outside this matrix | — | ACP sessions are children launched by entwurf's pi adapter, not already-running native sessions to wake. |
86
94
 
87
95
  “Verified probe” means the transport worked in a reproducible raw probe but entwurf
@@ -112,7 +120,7 @@ directly through the native adapter, with one bounded re-probe retry. Replyabili
112
120
  `record-backed identity ∧ probe-alive`; mailbox state does not exist on this rail, and no
113
121
  rail has resume authority since the visible-first cut.
114
122
 
115
- The managed bridge, statusline, and hook installers own separate configuration atoms.
123
+ The owned bridge, statusline, and hook installers own separate configuration atoms.
116
124
  Same-pid concurrent model invocation by multiple conversations is not claimed because
117
125
  the pid/start-key sender marker would be last-writer-wins. Current operator checks are
118
126
  in [BASELINE.md](./BASELINE.md); deterministic ownership and sender gates run in
@@ -123,65 +131,70 @@ in [BASELINE.md](./BASELINE.md); deterministic ownership and sender gates run in
123
131
  Do not describe “Codex” as one delivery shape. The measured app-server-backed TUI can
124
132
  accept `turn/start` for a live thread and report completion; the standalone embedded
125
133
  TUI exposed no equivalent receive route. This remains archived method evidence, not a
126
- shipping commitment: GLG closed the managed native Codex lane on 2026-08-01 because pi
134
+ shipping commitment: GLG declined to own a native Codex invocation/install lane on 2026-08-01 because pi
127
135
  already supplies the official GPT provider path. Entwurf will not duplicate it as a
128
136
  native citizen or ACP backend. `turn/steer` is active-turn steering, not idle wake.
129
137
 
130
- ### Copilot CLI: TUI+server is the positive launch mode
131
-
132
- **Two things are recorded here and they are not the same thing: what was MEASURED on
133
- 2026-08-19, and what the probe now CONTRACTS to measure.** The measurement below was
134
- taken with the earlier chronological-slice probe, which scored the events following the
135
- marker's position in the history. The current probe scores a named turn instead (next
136
- subsection). No result below has been re-taken under that contract, and none of it is
137
- retroactively a demonstration of it.
138
-
139
- **Measured 2026-08-19 (old chronological-slice probe).** A plain Copilot TUI and shell
140
- command hooks do not establish the measured route. CLI 1.0.80 launched with hidden
141
- `--ui-server --port <port>` and joined by first-party `@github/copilot-sdk` 1.0.11 did:
142
- protocol-v3 ping, foreground session id plus cwd/git metadata, exact session resume, idle
143
- `enqueue`, same-session model-`auto` reply, and `assistant.message`/`turn_end`/`session.idle`
144
- completion. A second run created a no-turn control session B, targeted A, and proved B
145
- received no user/turn/assistant event, closing D3 on one Linux workstation.
146
-
147
- The two-session shape also exposed a D8 gap: A visibly replied and persisted
148
- `assistant.message` + `turn_end`, but the joining SDK client did not receive ephemeral
149
- `session.idle`, so SDK `sendAndWait()` timed out. Bounded reads of the official session
150
- event-history API (`session.getEvents()` / `getMessages()`) then observed the completed
151
- target turn. Claim that at its real size: it is the SDK's own full event history, not a
152
- narrower or more privileged view, and equally not TUI, file, or database transcript
153
- scraping the probe never reads Copilot's own storage. It is probe evidence, not a
154
- product polling/retry design.
155
-
156
- **Evidence level for everything above: L4 direct-native, ONE Linux workstation, one run.**
157
- The receipt is host-local probe stdout; it was not archived as a durable artifact, so this
158
- row is reproducible-by-instruction, not citable to a stored file.
159
-
160
- **Current probe contract (not yet run LIVE).** Attribution is now a named chain rather
161
- than a position in the history: the probe's unique marker body must match exactly one
162
- `user.message`; that event's `interactionId` must open exactly one `assistant.turn_start`;
163
- that turn_start must expose a `turnId`; and only `assistant.message` / `assistant.turn_end`
164
- carrying that `turnId` are scored. Every link is required, and absent-or-ambiguous fails
165
- the probe closed there is no positional fallback and no "the turn after ours" rule.
166
- Note what is deliberately NOT the key: `session.send()` resolves to the SDK's own
167
- submission handle, a string that appears on no server event and is a different axis from
168
- `user.message.id`/`interactionId`, so joining on it cannot hold. It is logged as a
169
- diagnostic only. The next LIVE turn is what would demonstrate this contract; until then
170
- it is a design, not evidence.
171
-
172
- The probe also stays out of the operator's lifecycle, stated precisely: it never deletes
173
- target session A and issues no `A.disconnect()` of its own. `client.stop()` does tear down
174
- every tracked session — A included — as a wire `session.destroy`; because A's foreground
175
- ownership is re-confirmed immediately before teardown, the TUI keeps A as its foreground
176
- session, so the net effect on A is detach-equivalent, not removal.
177
-
178
- This is not yet admissible as a native-push adapter. The flag is hidden from CLI help,
179
- and the loopback JSON-RPC server did not enforce the SDK connection token in the
180
- measured launch: an unauthenticated client connected, while a token-bearing client was
181
- rejected as `AUTHENTICATION_NOT_CONFIGURED`. The TCP port is only a runtime endpoint,
182
- never identity authority. Do not add a record backend or dispatch route until
183
- permission ownership, stale/crash handling, and a supported fail-closed local
184
- boundary are demonstrated.
138
+ ### Copilot CLI: one citizen, two rails, one pending receipt
139
+
140
+ The branch product owns the native citizen's birth, garden id, statusline, MCP hand,
141
+ outbound sender identity — and, since RAIL 5, the receiver. A real Copilot CLI 1.0.80
142
+ session minted a V3 record and sent under that record-backed garden id on 2026-08-21.
143
+ That proved who SENDS. Whether a reply LANDS is a different fact on a different process,
144
+ and the paragraphs below are the two halves of it: where the transport came from, and
145
+ what the owned product unit had to add before it could be dispatched to.
146
+
147
+ The missing receive transport was found and measured on 2026-08-23. Copilot's platform
148
+ package bundles its first-party extension SDK and bootstrap. With
149
+ `COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS`, the CLI forks an installed extension and
150
+ speaks JSON-RPC over the child's stdio; `joinSession()` binds the foreground session, and
151
+ the vendor-documented `fs.watch` `session.send({mode:"enqueue"})` pattern wakes it.
152
+ An idle, never-typed-into session received a unique marker and returned it, then emitted
153
+ `session.idle`. A second armed process was observed to remain untouched, but its decisive
154
+ B log was not preserved before scratch cleanup, so D3 isolation remains an admission
155
+ rerun rather than a durable acceptance. This is L4 direct-native evidence on one Linux
156
+ workstation. The travelling receipt and reproduction are in
157
+ [`scripts/raw-async-delivery/README.md`](./scripts/raw-async-delivery/README.md).
158
+
159
+ This extension rail has no network listener, so the rejected `--ui-server` loopback
160
+ transport's authentication blocker does not apply. The owned product unit then took that
161
+ transport and gave it the obligations a product owes (#82 RAIL 5):
162
+
163
+ - **Artifact.** `run.sh install-copilot-receive` installs the receiver into the user
164
+ extensions directory from an install-state file it owns, refuses a unit it did not
165
+ put there, and removes only what that state names.
166
+ - **Identity.** The extension arms only when the CLI pid's sender marker, the V3 record
167
+ and the SDK's `session.sessionId` all agree; a drifted id or a parent-pid carrier that
168
+ disagrees with the real parent is a refusal, logged, never a best guess.
169
+ - **Liveness.** The marker's owner is the EXTENSION child the process that actually
170
+ holds the watch so a crashed receiver stops being deliverable at the next start-key
171
+ read, and the vendor's bootstrap already exits that child when the CLI goes.
172
+ - **Dispatch.** `wakeMode: self-fetch` puts Copilot on the existing mailbox rail. Armed
173
+ and matching enqueue + doorbell; anything else `mailbox-undeliverable`.
174
+ - **The flag.** entwurf still does not own the operator's shell and writes nothing to it,
175
+ but it owns ONE invocation: `entwurf copilot` execs the vendor CLI in the caller's own
176
+ terminal with `COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS` set for that process only,
177
+ and refuses to launch at all unless the receiver unit it is promising is really
178
+ installed. `doctor-copilot-receive` still reads the live CLI environments, because a
179
+ session started any other way without the flag is silently inert. Plain `copilot` is
180
+ untouched; running the owned invocation IS the consent to its profile (EXTENSIONS,
181
+ `--model auto` when no model was given, `--yolo` when no explicit permission or surface
182
+ policy flag was given).
183
+
184
+ The owned receive invocation has now been accepted LIVE (2026-08-23, receipts in the matrix row
185
+ above), which is what moved receive from D0 to D6. Visible fresh is a later, separate LIVE
186
+ (2026-08-25, same row) and does not reopen D3 or D8. What remains owed is still EVIDENCE,
187
+ not code: D3 isolation lost its decisive log to a scratch cleanup and is pending, and the
188
+ active-turn case, `/clear` re-arm and flag durability across vendor releases are
189
+ unmeasured. The hermetic gate drives the real installer and the real extension against a
190
+ stubbed SDK it proves everything on entwurf's side of the fork and nothing about the
191
+ vendor turn on the other side of it, so a green gate is still not a wake.
192
+
193
+ The hidden `--ui-server` probe remains retired evidence, not a fallback. It found a real
194
+ idle-enqueue capability through an unauthenticated loopback door; the extension finds the
195
+ same class of capability through the CLI-owned stdio lifecycle. Absence of Claude's
196
+ `FileChanged` / `asyncRewake` / `watchPaths` therefore means only that Claude's hook
197
+ mechanism cannot be copied — it never proved Copilot had no vendor wake surface.
185
198
 
186
199
  ## Recording a new claim
187
200