@junghanacs/entwurf 0.14.1 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +8 -5
- package/CHANGELOG.md +113 -0
- package/DELIVERY.md +73 -3
- package/README.md +55 -4
- package/VERIFY.md +6 -6
- package/demo/README.md +3 -1
- package/demo/demo-baseline.sh +12 -1
- package/demo/demo.sh +9 -1
- package/docs/acp-backend-rail.md +103 -4
- package/docs/external-mcp-host.md +26 -4
- package/docs/setup-clean-host.md +3 -3
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +8 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/entwurf-capabilities.json +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/copilot-fresh-preflight.js +253 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +10 -2
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +102 -28
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +77 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook-copilot.js +288 -0
- package/mcp/entwurf-bridge/dist/scripts/doctor-pi-provider.js +139 -47
- package/mcp/entwurf-bridge/dist/scripts/probe-bridge-command.js +294 -0
- package/mcp/entwurf-bridge/src/index.ts +10 -6
- package/mcp/entwurf-bridge/tsconfig.build.json +17 -6
- package/package.json +23 -12
- package/pi/copilot-receive/entwurf-receive/extension.mjs +323 -0
- package/pi/entwurf-capabilities.json +1 -0
- package/pi/meta-bridge-copilot/.claude-plugin/marketplace.json +11 -0
- package/pi/meta-bridge-copilot/entwurf-meta-receive-copilot/.claude-plugin/plugin.json +5 -0
- package/pi/meta-bridge-copilot/entwurf-meta-receive-copilot/hooks/hooks.json +7 -0
- package/pi/meta-bridge-copilot/entwurf-meta-receive-copilot/scripts/copilot-hook-launch.sh +85 -0
- package/pi-extensions/entwurf-control.ts +17 -8
- package/pi-extensions/lib/acp/backend.ts +229 -9
- package/pi-extensions/lib/copilot-fresh-preflight.ts +251 -0
- package/pi-extensions/lib/meta-sender-identity.ts +10 -2
- package/pi-extensions/lib/meta-session.ts +102 -29
- package/pi-extensions/lib/mux-fresh-call.ts +82 -11
- package/pi-extensions/meta-bridge-hook-copilot.ts +323 -0
- package/run.sh +389 -26
- package/scripts/agy-bridge-config.py +47 -13
- package/scripts/agy-bridge.sh +73 -23
- package/scripts/check-acp-prompt-lifecycle.ts +221 -9
- package/scripts/check-copilot-birth-hook.ts +497 -0
- package/scripts/check-copilot-launch.ts +395 -0
- package/scripts/check-copilot-receive-arm.ts +734 -0
- package/scripts/check-copilot-statusline.ts +122 -0
- package/scripts/check-entwurf-bridge-boot.ts +28 -0
- package/scripts/check-entwurf-capabilities.ts +25 -6
- package/scripts/check-fresh-cut-gate.sh +92 -23
- package/scripts/check-gate-qualification.ts +10 -3
- package/scripts/check-install-container.sh +2 -2
- package/scripts/check-install-surface.ts +1 -1
- package/scripts/check-meta-capability-source.ts +89 -5
- package/scripts/check-meta-doctor-oracle.sh +26 -0
- package/scripts/check-meta-manifest-schema.py +38 -0
- package/scripts/check-meta-receiver-marker.ts +25 -2
- package/scripts/check-meta-session.ts +32 -0
- package/scripts/check-probe-bridge-command.ts +201 -0
- package/scripts/check-release-gate-outcomes.ts +54 -1
- package/scripts/copilot-bridge-doctor.sh +209 -0
- package/scripts/copilot-bridge-install.sh +224 -0
- package/scripts/copilot-launch.sh +236 -0
- package/scripts/copilot-mcp-bridge.sh +177 -0
- package/scripts/copilot-mcp-config.py +221 -0
- package/scripts/copilot-receive-bridge.sh +483 -0
- package/scripts/copilot-statusline-bridge.sh +149 -0
- package/scripts/copilot-statusline-config.py +201 -0
- package/scripts/copilot-statusline.sh +68 -0
- package/scripts/dev-bin.sh +4 -1
- package/scripts/doctor-pi-provider.ts +155 -51
- package/scripts/meta-bridge-hook-log.sh +17 -5
- package/scripts/mutants/acp-prompt-lifecycle.json +25 -3
- package/scripts/mutants/bridge-command-boot.json +107 -0
- package/scripts/mutants/capability-cache.json +64 -0
- package/scripts/mutants/copilot-birth.json +155 -0
- package/scripts/mutants/copilot-launch.json +187 -0
- package/scripts/mutants/copilot-receive.json +263 -0
- package/scripts/mutants/fresh-cut.json +17 -0
- package/scripts/mutants/mux-fresh-call.json +216 -2
- package/scripts/mutants/pack-install.json +17 -0
- package/scripts/mutants/release-gate.json +13 -0
- package/scripts/probe-bridge-command.ts +330 -0
- package/scripts/raw-async-delivery/README.md +203 -1
- package/scripts/raw-async-delivery/copilot-enqueue-addressed.sh +35 -0
- package/scripts/raw-async-delivery/copilot-extension-receive/extension.mjs +123 -0
- package/scripts/raw-async-delivery/copilot-ui-server-probe.mjs +337 -0
- package/scripts/smoke-acp-raw-turn-live.ts +1 -1
- package/scripts/smoke-agy-install-state.sh +76 -2
- package/scripts/smoke-copilot-mcp-state.sh +153 -0
- package/scripts/smoke-copilot-statusline-state.sh +131 -0
- package/scripts/smoke-entwurf-chain-live.ts +1 -1
- package/scripts/smoke-entwurf-v2-matrix-live.ts +2 -2
- package/scripts/smoke-mux-fresh-call-live.ts +3 -1
- package/scripts/smoke-mux-lifecycle-live.ts +4 -2
- package/scripts/smoke-pi-provider-state.sh +135 -6
- package/scripts/smoke-resident-garden-guard.sh +2 -2
- package/scripts/tsconfig.json +1 -0
package/run.sh
CHANGED
|
@@ -120,7 +120,7 @@ usage() {
|
|
|
120
120
|
cat <<'EOF'
|
|
121
121
|
Usage:
|
|
122
122
|
./run.sh setup [project-dir] # ONE confident install: pnpm install + install + meta-bridge (if native harness) + v2 install smoke (LIVE substrate = release-gate)
|
|
123
|
-
./run.sh release-gate [project-dir] [--cut] [--allow-skip-gemini] # SINGLE release gate: full static (pnpm run check:full) + the v2-native live gates (v2 matrix-live, check-bridge, RGG) + the ACP plugin acceptance floor (12 LIVE smokes: socket-citizen/raw-turn/overlay/provider/session-reuse/carrier-augment/memory-containment/rgg/mcp/skill/bundled-mcp/v2-send) + the one surviving axis the aggregate used to omit silently (claude-native-resume; Cortex stays a documented on-demand direct call) + the cross-harness delivery chain (smoke-entwurf-chain-live). TWO-TIER summary: MUST (release-blocking, owns the exit code — "green" applies here) + BEHAVIOR (advisory, non-blocking: RGG positives model-in-loop turn). STEP OUTCOME protocol: every step is INVOKED and reports its own PASS / SKIP (exit 97, a prerequisite it does not have) / FAIL — a skip is never counted as a pass. Without --cut this is the unattended diagnostic (SKIPs reported, exit 0). WITH --cut it is read as release acceptance and ANY MUST SKIP is red, which is what makes "a CUT needs LIVE=1, SKIP=0" executable instead of prose. --allow-skip-gemini accepted-but-ignored (back-compat). final cut authorization is GLG's.
|
|
123
|
+
./run.sh release-gate [project-dir] [--cut] [--allow-skip-gemini] # SINGLE release gate: full static (pnpm run check:full) + the v2-native live gates (v2 matrix-live, check-bridge, doctor-pi-provider, RGG) + the ACP plugin acceptance floor (12 LIVE smokes: socket-citizen/raw-turn/overlay/provider/session-reuse/carrier-augment/memory-containment/rgg/mcp/skill/bundled-mcp/v2-send) + the one surviving axis the aggregate used to omit silently (claude-native-resume; Cortex stays a documented on-demand direct call) + the cross-harness delivery chain (smoke-entwurf-chain-live). TWO-TIER summary: MUST (release-blocking, owns the exit code — "green" applies here) + BEHAVIOR (advisory, non-blocking: RGG positives model-in-loop turn). STEP OUTCOME protocol: every step is INVOKED and reports its own PASS / SKIP (exit 97, a prerequisite it does not have) / FAIL — a skip is never counted as a pass. Without --cut this is the unattended diagnostic (SKIPs reported, exit 0). WITH --cut it is read as release acceptance and ANY MUST SKIP is red, which is what makes "a CUT needs LIVE=1, SKIP=0" executable instead of prose. --allow-skip-gemini accepted-but-ignored (back-compat). final cut authorization is GLG's.
|
|
124
124
|
./run.sh check-bridge # entwurf-bridge direct MCP smoke + protocol/negative-path test.sh (live substrate = v2 live smokes)
|
|
125
125
|
./run.sh check-entwurf-bridge-boot # deterministic gate (5d-5-pre, G1a/G1b/G1e/G1f, IN pnpm run check:full): boot start.sh under strip-types + assert v2 fence graph loads + entwurf_v2 and entwurf_resume_call registered/schema + the tools/list surface is EXACTLY the seven shipped garden verbs; tools/list only, no auth/side-effect
|
|
126
126
|
./run.sh check-entwurf-bridge-pi-free # deterministic gate (0.12.1 A, IN pnpm check): static — bridge index eager value-import closure must carry no @earendil-works/pi-* (type-only + dynamic import excluded); proves the meta-bridge boots pi-free
|
|
@@ -130,6 +130,10 @@ Usage:
|
|
|
130
130
|
./run.sh check-meta-session # deterministic gate (#30 step 2, V3-only): fs store — idempotent decideUpsert/upsertMetaSession + mailbox enqueue/read + receipt state, no API
|
|
131
131
|
./run.sh check-meta-v3-record # deterministic gate: the ONE live record schema (v3) — canonical serialize/round-trip/mint, foreign-generation rejections name fresh-cut with the actual version value, strict keyset, no API
|
|
132
132
|
./run.sh check-mailbox-receipt-state # deterministic gate (0.11 Stage 0 step 3B): mailbox receipt state schema + store (stamp→persist→read-back) in a temp mailbox, strict keyset, no API
|
|
133
|
+
./run.sh check-copilot-birth-hook # #82 gate: drives the real Copilot assembler into a temp dir, fires the baked launcher with NO ARGV (the way Copilot's `exec`-string schema forces), and requires a backend:"copilot" v3 record + attach + peer row + a SENDER marker the resolver joins back to that record, and still zero mailbox/receiver marker (who-sent needs a shared parent; a receiver needs a doorbell this backend has not got). Hermetic; no Copilot, no model turn
|
|
134
|
+
./run.sh check-copilot-receive-arm # #82 RAIL 5 gate: the REAL receiver installer + the REAL extension.mjs forked with a stubbed SDK. Arms only after birth, marker owned by the WATCHER pid, self-fetch dispatch answer, doorbell carries the garden id and NOT the body, id-drift/foreign-parent refusals. Hermetic; no Copilot, no model turn
|
|
135
|
+
./run.sh check-copilot-launch # #82 RAIL 7 gate: the MANAGED launch `entwurf copilot`, driven through its public address against a FAKE VENDOR on a sandbox PATH. Receiver precondition refusals, EXTENSIONS token + operator token preservation, injected defaults before the `--` terminator, byte-identical argv, the 11 explicit permission/surface policy overrides that suppress `--yolo`, exec (not fork) pid identity, exit passthrough, recursion refusal. Hermetic; no Copilot, no model turn
|
|
136
|
+
./run.sh check-copilot-statusline # #82 Copilot custom-footer renderer. session_id → ready/?/gid + rail `cop`; exit 0. IN pnpm check. No Copilot, no model turn
|
|
133
137
|
./run.sh check-entwurf-capabilities # deterministic gate (0.11 Stage 0 step 3C): backend capability registry (pi/entwurf-capabilities.json) — coverage==META_CITIZEN_BACKENDS + agrees with live META_BACKEND_DESCRIPTORS + strict keyset, no API
|
|
134
138
|
./run.sh check-capability-bundle-reach # deterministic gate (IN pnpm check): re-ask EVERY shipped copy of meta-session (source + bridge bundle emit) whether metaCapabilitiesFilePath() reaches the registry — the artifact-depth check the source-path gates cannot make; needs a built dist, missing dist FAILS
|
|
135
139
|
./run.sh smoke-pi-attach # deterministic gate (#50 C2 checkpoint + C3 ACP tail): a pi session attaches as a V3 meta-record citizen (backend:"pi"), the gardenId is the RECORD's not pi's session id, the control socket is keyed on it, a re-open ATTACHES to the same address (never a second mint), the BUILT DIST ENTRY driven over MCP stdio lists the citizen + delivers entwurf_v2 to that socket with an RPC ack, and the ACP identity chain lands a send AS the host record (enrichMcpServersWithEnvelope env → bridge sender = host gardenId). mkdtemp-isolated; the live store is never read
|
|
@@ -156,8 +160,8 @@ Usage:
|
|
|
156
160
|
./run.sh check-mux-launcher-fence # deterministic gate for the shared operator-launcher fence (issue #67): scripts/lib/claude-launcher-fence.ts + its wiring into BOTH mux LIVE smokes. Replants the observed install-destruction shape (real HOME + fixture XDG_DATA_HOME → self-update retargets the real `claude` launcher into the fixture tree, teardown deletes it) wholly inside disposable mkdtemp roots — the real launcher is never inspected. Pins fail-closed preflight, retarget/content-change detection before cleanup, removal BLOCKED on fixture reference / unproven safety / surviving tracked panes, exact operator-parity XDG restore (absent = DELETED, not canonical defaults), the lifecycle cell-branch topology, and one shared helper consumed by both smokes
|
|
157
161
|
./run.sh check-entwurf-v2-visible-resume # deterministic gate: S1 visible-resume COMPOSITION (entwurf-v2-visible-resume.ts) with every seam injected — the whole state machine incl. the timeout branch runs with no tmux/lock/socket/clock. Pins lock BEFORE liveness, identity under the lock and before any window (no-transcript citizen fails loud, opens nothing), live/indeterminate/address-conflict refused unlaunched, observation as a BOUNDED WAIT (measured: socket answers ~2–4s after launch, so one immediate probe would call a successful resume unobserved), exactly ONE launch on every path, timeout → lock released + window left open + nothing retried/killed, failed release throws, and the two receipts staying separate in type and text
|
|
158
162
|
./run.sh check-resume-launch-identity # deterministic gate for resume-launch-identity.ts, the record-authoritative launch-identity leaf preserved through the visible-first cut (spawn-bg and all its callers are gone; this leaf answers "which being is this, and which conversation is theirs"). Temp meta-store fixture: gardenId→record.transcriptPath happy path with header cwd/provider/model; C3 integrity (header id ≠ record.nativeSessionId → refused, never resumed); #52 ADDRESSABLE read (a gid that no longer holds its nativeSessionId alone is refused from EITHER side — the plain targeted read would resume one transcript twice under two locks); cause fidelity per impossible resume incl. the F7 pin (recorded-but-deleted transcript → MISSING, not "no recorded model"); header↔gate SSOT. No spawn/socket/timer
|
|
159
|
-
./run.sh smoke-entwurf-v2-matrix-live # LIVE sentinel (0.11 Stage 0 step 5d-5, D4-b) — OUT of pnpm check, needs LIVE=1. Drives REAL production runEntwurfV2 deps over REAL OS objects, 4 cells: C1 control-socket (real pi --entwurf-control resident → RPC send → lock acquire→release ×1), C1b record-less socket (#50 C4: live record-less pi → EVERY intent rejected pre-probe record-less-socket, no lock, rendered hint names record authority + fresh-cut), C2 meta-mailbox deliverable (armed self-fetch citizen → real .msg enqueue, lock-free), C3 meta-mailbox guard (no armed receiver → reject, no garbage). Model-in-loop OUT (transport/lock/enqueue gate, GPT Q2); negative/timeout stay deterministic. Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.
|
|
160
|
-
./run.sh smoke-agy-native-push-live # 봉인 8 LIVE acceptance for the native-push (agy) rail — OUT of pnpm check, needs LIVE=1 + AGY_CONVERSATION_ID (a live agy conversation). Drives the REAL antigravity adapter + register core + runEntwurfV2 (production deps): doctor-static preflight (dangling→FAIL, the ③ gate), probe route, register create/attach idempotency, fire→native-push delivered, post-send re-probe (D7 partial), bogus-conv→native-push-probe-indeterminate. Meta-store isolated to a temp dir (only the agy round-trip is real; no real-store residue). LIVE=1 AGY_CONVERSATION_ID=<convId> ./run.sh smoke-agy-native-push-live
|
|
163
|
+
./run.sh smoke-entwurf-v2-matrix-live # LIVE sentinel (0.11 Stage 0 step 5d-5, D4-b) — OUT of pnpm check, needs LIVE=1. Drives REAL production runEntwurfV2 deps over REAL OS objects, 4 cells: C1 control-socket (real pi --entwurf-control resident → RPC send → lock acquire→release ×1), C1b record-less socket (#50 C4: live record-less pi → EVERY intent rejected pre-probe record-less-socket, no lock, rendered hint names record authority + fresh-cut), C2 meta-mailbox deliverable (armed self-fetch citizen → real .msg enqueue, lock-free), C3 meta-mailbox guard (no armed receiver → reject, no garbage). Model-in-loop OUT (transport/lock/enqueue gate, GPT Q2); negative/timeout stay deterministic. Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.6-luna). LIVE=1 ./run.sh smoke-entwurf-v2-matrix-live
|
|
164
|
+
./run.sh smoke-agy-native-push-live # 봉인 8 LIVE acceptance for the native-push (agy) rail — OUT of pnpm check, needs LIVE=1 + AGY_CONVERSATION_ID (a live agy conversation). Drives the REAL antigravity adapter + register core + runEntwurfV2 (production deps): doctor-static preflight (dangling→FAIL, the ③ gate), probe route, register create/attach idempotency, fire→native-push delivered, post-send re-probe (D7 partial), bogus-conv→native-push-probe-indeterminate. Meta-store isolated to a temp dir (only the agy round-trip is real; no real-store residue). COST FENCE: open that agy conversation on gemini-3.6-flash (free account) — never a Pro tier; entwurf never selects the agy model and no assertion reads it. LIVE=1 AGY_CONVERSATION_ID=<convId> ./run.sh smoke-agy-native-push-live
|
|
161
165
|
./run.sh smoke-mux-lifecycle-live # RELEASE MUST integrated LIVE lifecycle acceptance for mux, through the REAL MCP surface — OUT of pnpm check, needs LIVE=1 and spends model turns (two pi siblings: native + recorded-ACP provider, each resumed once; one Claude Code sibling). tools/call fresh_call -> nonce callback sender envelope -> v2 control send landing in the sibling's own transcript -> resume_call REFUSED while live (window count unchanged) -> stable-handle close (pane gone, socket dead, record kept) -> dormant delivery refused honestly -> public entwurf_resume_call with LAUNCH and OBSERVATION receipts kept apart, same-gid socket alive, zero new citizens, zero lock residue, resumed pane_start_path == RECORD cwd (separate tmux query), transcript byte-identical across the resume -> v2 recall of the pre-close fact. claude-code resume refused target-not-pi, no window opened and no lock residue. LIVE=1 ./run.sh smoke-mux-lifecycle-live
|
|
162
166
|
./run.sh check-entwurf-facts # deterministic gate (0.11 Stage 0 step 4, fact-provider slice 1+2): PURE PeerFact core + resolveFactList union — R1 out-of-domain→unsupported, R3b socket-domain 4-value, facts-only keyset; union: PeerFact + RecordLessSocketFact by gardenId (#50 C4: record-less socket = diagnostic subject, gid+liveness only), dormant→dead, F3 indeterminate preserved, out-of-socket-domain+socket fail-loud; pure, no IO
|
|
163
167
|
./run.sh check-socket-discovery # deterministic gate (0.11 Stage 0 step 4, fact-provider slice 3): SOCKET-axis scanSocketProbes — probes (dir sockets) ∪ (in-domain citizen canonical paths) 3-valued; dormant citizen no-file → dead (resumable, not unprobed), stall → indeterminate (F3), dir hygiene/dedup/missing-dir + e2e → resolveFactList; readdir/probe injected, no IO
|
|
@@ -185,6 +189,8 @@ Usage:
|
|
|
185
189
|
./run.sh check-probe-ordering # §11-7 ordering-probe deterministic gate: raw-client SAMENESS pinned to backend.ts (sequence/args/timeouts/permission policy — the probe may never measure a lookalike), phase attribution incl. set-model, probe-mode fixture wire markers (delay honored, probeRunId REQUIRED, smoke-acp-mcp-live legacy compat), event-log door integrity (reserved keys refused at write; unknown marker name, broken sort axis, or a payload the classifier cannot judge on is MALFORMED, never a quiet event), and the §11-7 paired-verdict truth table (P0/I0 outside the space, phase-qualified D, B promotion ladder, C, A two-delay rule). Offline/deterministic; one product claim (no production prompt cutoff) is replant-qualified via scripts/mutants/probe-ordering.json, while the other assertions are direct [CHECK:*] contracts
|
|
186
190
|
./run.sh check-probe-cli-shim # §11-7-c B-name-snapshot PRODUCER gate: the CLI shim driven as a REAL process against fake CLIs (no API, no cost). Proves what a defect would buy — FABRICATED evidence (a malformed init is never reported as an empty name set; the boot report carries the true target path+sha256 the classifier verifies against the roster), a DESTROYED turn (byte transparency across mid-UTF8/CRLF/oversized/unterminated framing, exit-code fidelity, signal re-raise, inbound signal forwarding, stderr passthrough, stdout backpressure), and LEAKED operator state (exact-allowlist env scrub, no argv/env/prompt body in the log). Offline/deterministic; 20 direct [CHECK:*] contracts, deliberately no longer replant-qualified after #70 subtraction
|
|
187
191
|
./run.sh smoke-agy-statusline-state # agy ambient garden-id statusLine install/doctor/inverse regression. Offline/deterministic
|
|
192
|
+
./run.sh smoke-copilot-statusline-state # Copilot custom-footer install/doctor/inverse regression. Offline/deterministic
|
|
193
|
+
./run.sh smoke-copilot-mcp-state # Copilot MCP install/doctor/inverse regression. Offline/deterministic
|
|
188
194
|
./run.sh smoke-agy-hooks-state # agy PreInvocation birth/sender hook install/doctor/inverse + direct stdin→meta-record regression. Offline/deterministic
|
|
189
195
|
./run.sh smoke-user-scope-citizen # 0.12.6 install-boundary: pi packages[] registration SSOT (register-pi-package.py) — idempotent + preserves unrelated + normalizes stale + remove symmetry + fails loud. Offline/hermetic (deps: bash+python3)
|
|
190
196
|
./run.sh smoke-meta-prune # 1.0.0 meta-bridge Phase 4: listing-only store janitor regression gate — classify keep/orphan/stale/ambiguous, delete nothing. Offline/deterministic (deps: bash+node)
|
|
@@ -195,8 +201,21 @@ Usage:
|
|
|
195
201
|
./run.sh install-meta-bridge # INTERNAL part of `setup` (native-harness plugin) + doctor recovery path — prefer `setup`; stateful GLOBAL install (plugin + USER MCP + settings keyset, honest uninstall state)
|
|
196
202
|
./run.sh uninstall-meta-bridge # 1.0.0 meta-bridge Phase 2: stateful GLOBAL uninstall (restore only keys/items captured in install-state)
|
|
197
203
|
./run.sh doctor-meta-bridge # THE RELEASE ORACLE (#51, Linux-certified repair axis). exit 0 = every required layer was MEASURED on this Linux host: toolchain + state + plugin/MCP + resolved-artifact launch-form classification (all 3 owner hooks + doorbell static contract) + synthetic owner join + store scan + hook errors + SessionStart evidence + REQUIRED live MCP↔marker join + writer-version parity. Missing live evidence is NOT CERTIFIED (open a Claude session and re-run), never a pass; Darwin is not yet verified/certified and stays nonzero for this cut (future validation may reopen it). Detection power is held by check-meta-doctor-oracle
|
|
204
|
+
./run.sh copilot [args...] # #82 RAIL 7: the MANAGED Copilot launch. exec()s the vendor CLI in THIS terminal (cwd/pid/exit preserved) with COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS set for that one invocation — entwurf owns no part of your shell and writes nothing to it, but it owns the process it is about to become. Without that flag Copilot skips the extension scan SILENTLY. Refuses to launch unless the receiver unit is actually installed. Injects `--model auto` when no --model was given and `--yolo` when no explicit permission/surface policy flag was given, both BEFORE any `--`; every argument you pass is forwarded byte-identical. RUNNING THIS IS YOUR CONSENT to that profile — use plain `copilot` for stock vendor behaviour. Not tmux, not fresh-call, mints no citizen (birth is still the first prompt)
|
|
205
|
+
./run.sh install-copilot-bridge # #82: GLOBAL install of the Copilot BIRTH plugin (own marketplace root; node+entry baked into the no-argv exec string). MCP wiring and the RECEIVER extension are separate install surfaces (install-copilot-mcp, install-copilot-receive). Also retires the stale Claude unit (--keep-stale-claude-unit opts out)
|
|
206
|
+
./run.sh doctor-copilot-bridge # #82: fail-loud surface for that unit. Red = a hook that RAN and failed, or a broken/unbaked artifact. "Installed with zero records" is NOT red and is reported as NOT-YET: a Copilot session is born on its FIRST PROMPT, not when the window opens (measured)
|
|
207
|
+
./run.sh install-copilot-statusline # own Copilot statusLine + footer.showCustom with an install-state preimage
|
|
208
|
+
./run.sh uninstall-copilot-statusline # honest inverse of install-copilot-statusline
|
|
209
|
+
./run.sh doctor-copilot-statusline # static ownership/config/bin doctor; never claims a render receipt
|
|
210
|
+
./run.sh install-copilot-mcp # #82 RAIL 5: register ONE entwurf-bridge server in ~/.copilot/mcp-config.json (adopt / create / REFUSE symlink), type:local, install-state under $XDG_DATA_HOME/entwurf/copilot-mcp/
|
|
211
|
+
./run.sh uninstall-copilot-mcp # honest inverse of install-copilot-mcp from install-state
|
|
212
|
+
./run.sh doctor-copilot-mcp # static ownership/config/boot doctor; RED only when install-state exists
|
|
213
|
+
./run.sh install-copilot-receive # #82 RAIL 5: install the RECEIVER extension (user scope ~/.copilot/extensions/entwurf-receive). Owns the artifact and CHECKS the launch flag; it never sets one (a launch does — see `./run.sh copilot`). Arms per session after birth
|
|
214
|
+
./run.sh uninstall-copilot-receive # honest inverse from install-state; never removes a unit it did not install
|
|
215
|
+
./run.sh doctor-copilot-receive # artifact + digest, COPILOT_CLI_ENABLED_FEATURE_FLAGS on the LIVE copilot processes (the silent failure), live receiver markers via the production reader, receiver log. RED only when install-state exists
|
|
198
216
|
./run.sh install-agy-bridge # 봉인 7: agy MCP install adapter — register ONE entwurf-bridge server in the agy mcp_config (adopt file / create / REFUSE symlink), stable bin command, install-state under $XDG_DATA_HOME/entwurf/agy-bridge/
|
|
199
217
|
./run.sh uninstall-agy-bridge # 봉인 7: honest inverse of install-agy-bridge from install-state (restore preimage / remove key; refuse if config became a symlink)
|
|
218
|
+
./run.sh probe-bridge-command <cmd> [args...] # #81: BOOT the given bridge invocation and require the entwurf MCP tool surface back. `--invocation-json '{"command":"…","args":[],"env":{}}'` preserves a harness config exactly. It waits for a valid initialize response, then sends initialized + tools/list only (no tools/call, lock, record, or delivery). exit 0 = it serves the bridge; 1 = it does not. The pi/agy doctors use this leaf.
|
|
200
219
|
./run.sh doctor-agy-bridge # fail-loud doctor: MCP config + exact permission rule + state + live probe label
|
|
201
220
|
./run.sh install-agy-statusline # own the agy statusLine subtree with bare entwurf-agy-statusline; preserve unrelated settings
|
|
202
221
|
./run.sh uninstall-agy-statusline # honest inverse from statusline install-state
|
|
@@ -212,6 +231,7 @@ Usage:
|
|
|
212
231
|
./run.sh check-dep-versions # local deterministic check that the pi pin agrees across package.json (devDeps + peer range), run.sh (peer-install pins), and the baseline docs (AGENTS/README/ROADMAP/setup-clean-host/demo)
|
|
213
232
|
./run.sh check-node-floor-coherence # binds the Node floor (24+, single axis) across engines.node, run.sh setup preflight, meta-bridge install/doctor judgment logic, clean-host docs, the bridge launcher header, and the CI runner node-version — engines.node is the SSOT, everything else is derived; sweeps tracked contract text for an unregistered declaration
|
|
214
233
|
./run.sh check-pack # publish gate (dry-run): npm pack --dry-run + tarball invariants (runtime-critical present, dev residue absent)
|
|
234
|
+
./run.sh check-pack-pin-matcher # pure self-test of check-pack-install's pin-leak matcher against synthetic .pnpm lookalikes (version boundary: @0.84.30 must leak, @0.84.3 bare/peer-hash must pass); snapshot-safe qualification oracle, also run first inside check-pack-install
|
|
215
235
|
./run.sh check-fresh-cut-gate # SOURCE cell of the generation-boundary proof (IN pnpm run check:full): drives real install/setup/fresh-cut in a sandbox; certification refusal is pre-write, quiescence is fail-closed, archives preserve bytes, and the #54 exit matrix distinguishes complete / no-move / usage / incomplete transition / complete-with-cleanup-residue. No model/network/cost
|
|
216
236
|
./run.sh check-pack-install # heavy publish gate (prepublishOnly): actual npm pack + tar -tf + fresh-temp install smoke with the pinned pi peers (0.82.x) + the npm-installed bridge BOOTS (tools/list) and DELIVERS (tools/call entwurf_v2 → .msg lands) + the INSTALLED generation lifecycle on a seeded previous-generation host (REFUSE before activation writes / zero Claude invocations → installed fresh-cut archives + opens empty → install-meta-bridge PASSES)
|
|
217
237
|
./run.sh check-install-container # 0.12.8 (#51 C): Linux artifact-CONSUMER gate — one candidate .tgz handed read-only to a checkout-invisible node:<engines-major>-bookworm cell. Default packs once to temp; ENTWURF_CANDIDATE_TGZ=/absolute/preserved.tgz consumes those exact bytes with no re-pack and prints canonical path+sha256 for release. Non-root global PATH install, frozen package, MCP tools/list, fake-Claude install-meta-bridge, path+sha256 fence, strict doctor, and the GENERATION host-state matrix (clean / v3-only store bytes unchanged / previous-generation REFUSE→fresh-cut→retry PASS) seeded inline. Docker missing = honest SKIP; ENTWURF_REQUIRE_DOCKER=1 makes that RED (required CI)
|
|
@@ -737,6 +757,41 @@ check_meta_receiver_marker() {
|
|
|
737
757
|
run_ts scripts/check-meta-receiver-marker.ts
|
|
738
758
|
}
|
|
739
759
|
|
|
760
|
+
check_copilot_birth_hook() {
|
|
761
|
+
# #82 gate: the Copilot BIRTH path, proven without Copilot. Drives the REAL
|
|
762
|
+
# assembler (--assemble-only, into a temp dir), then fires the baked launcher the
|
|
763
|
+
# way Copilot fires it — NO ARGV, envelope on stdin — and requires a v3 record with
|
|
764
|
+
# backend "copilot", an attach on the second event of the same prompt, no
|
|
765
|
+
# mailbox/marker of any kind, and a peer row with liveness `unsupported`. Refusals
|
|
766
|
+
# (disagreeing ids, missing cwd, no id, malformed) must refuse rather than guess.
|
|
767
|
+
# It proves the MECHANISM, never the admission: §6 acceptance is a record minted by
|
|
768
|
+
# a real Copilot session, which costs a model turn.
|
|
769
|
+
run_ts scripts/check-copilot-birth-hook.ts
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
check_copilot_statusline() {
|
|
773
|
+
# #82 Copilot custom-footer renderer. Drives scripts/copilot-statusline.sh with
|
|
774
|
+
# session_id on stdin in an isolated store. ready / ? / exact gid; exit 0.
|
|
775
|
+
run_ts scripts/check-copilot-statusline.ts
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
check_copilot_launch() {
|
|
779
|
+
# #82 RAIL 7. The subject is a process REPLACEMENT, so the oracle is a fake vendor
|
|
780
|
+
# executable on a sandboxed PATH that reports the argv/env/pid/cwd it was handed —
|
|
781
|
+
# never a reading of the launcher's source. HOME/XDG/PATH are all redirected, so the
|
|
782
|
+
# install-state, the extensions root and the resolved binary are the fixture's.
|
|
783
|
+
run_ts scripts/check-copilot-launch.ts
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
check_copilot_receive_arm() {
|
|
787
|
+
# #82 RAIL 5 gate: drives the REAL receiver installer into a temp extensions dir, then
|
|
788
|
+
# forks the REAL extension.mjs with the SDK specifier resolved by a loader hook (the
|
|
789
|
+
# vendor's own mechanism). Binds arm-after-birth, watcher-owned marker, the self-fetch
|
|
790
|
+
# dispatch answer, a doorbell that carries the id and not the body, and every refusal.
|
|
791
|
+
# Needs the compiled bridge closure; hermetic otherwise (no Copilot, no model turn).
|
|
792
|
+
run_ts scripts/check-copilot-receive-arm.ts
|
|
793
|
+
}
|
|
794
|
+
|
|
740
795
|
check_hook_launch_topology() {
|
|
741
796
|
# #51 gate 1, deliberately built only AFTER the B/B2 verdict. Binds the SHIPPED
|
|
742
797
|
# hooks.json to real child topology: every leaf is exec form through the shipped
|
|
@@ -1098,7 +1153,10 @@ check_mux_fresh_call() {
|
|
|
1098
1153
|
# could not see: real bridge boot → tools/list schema/description, Rust-regex-family pattern
|
|
1099
1154
|
# validity on every emitted pattern (the #62 escape), and the schema riding the actual
|
|
1100
1155
|
# anthropic-messages request body. No fake tmux: the real-window axis is smoke-mux-fresh-call-live.
|
|
1101
|
-
|
|
1156
|
+
# copilot-fresh-preflight rides here rather than in its own gate: it exists only as
|
|
1157
|
+
# freshCall's pre-mutation branch (#82 RAIL 9), and splitting it would let the two halves
|
|
1158
|
+
# of one refusal be certified in different runs.
|
|
1159
|
+
run_vitest test/mux-fresh-call.test.ts test/copilot-fresh-preflight.test.ts test/fresh-call-surfaces.contract.test.ts test/fresh-call-provider.contract.test.ts
|
|
1102
1160
|
}
|
|
1103
1161
|
|
|
1104
1162
|
smoke_mux_fresh_call_live() {
|
|
@@ -1356,7 +1414,7 @@ smoke_acp_cortex_live() {
|
|
|
1356
1414
|
# (ACP rail Cortex verification boundary). Drives one real
|
|
1357
1415
|
# cortex ACP turn through the entwurf provider path (outbound entwurf_v2 +
|
|
1358
1416
|
# dual-HOME overlay facts + process-group reclaim — CP2).
|
|
1359
|
-
# HONEST-SKIP (exit 0) when LIVE!=1 OR `cortex` is not on PATH OR no
|
|
1417
|
+
# HONEST-SKIP (protocol exit 97, never 0) when LIVE!=1 OR `cortex` is not on PATH OR no
|
|
1360
1418
|
# connection is pinned — the live turn needs `cortex` installed with the
|
|
1361
1419
|
# operator's own web-login auth already present (there is no `cortex auth`
|
|
1362
1420
|
# subcommand — CP0 D6), reached through the overlay's narrow credential
|
|
@@ -1389,7 +1447,7 @@ smoke_entwurf_v2_matrix_live() {
|
|
|
1389
1447
|
# reject, no garbage). Model-in-loop is OUT (GPT Q2): "does the sender model call entwurf_v2"
|
|
1390
1448
|
# is a separate behavior test — this is a transport/lock/enqueue gate. Negative/timeout/contention
|
|
1391
1449
|
# stay deterministic. Honest skip when LIVE!=1 so the release-gate is runnable unattended.
|
|
1392
|
-
# Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.
|
|
1450
|
+
# Model: ENTWURF_LIVE_TARGET=<provider>/<model> (default openai-codex/gpt-5.6-luna).
|
|
1393
1451
|
# LIVE=1 ./run.sh smoke-entwurf-v2-matrix-live
|
|
1394
1452
|
entwurf_require_step_outcome
|
|
1395
1453
|
if [ "${LIVE:-}" != "1" ]; then
|
|
@@ -1628,13 +1686,13 @@ assert.equal(peerTui, piAi,
|
|
|
1628
1686
|
// floor tracks the devDep pin so a consumer can't install against a pi lacking
|
|
1629
1687
|
// the public trust exports the bridge imports at the pinned minor, AND an upper
|
|
1630
1688
|
// bound at the next minor stops a fresh install from silently pulling a future
|
|
1631
|
-
// pi (past the declared ceiling — 0.85+ at the current 0.84.
|
|
1689
|
+
// pi (past the declared ceiling — 0.85+ at the current 0.84.3 pin) whose
|
|
1632
1690
|
// internal export surface has drifted from the one we typecheck against.
|
|
1633
1691
|
// pi moves its public surface every minor (the 0.79→0.80 getModels→provider-
|
|
1634
1692
|
// factory churn is exactly this), so an open `>=` floor is exactly how the next
|
|
1635
1693
|
// installer re-acquires the drift. The floor is also the HARD MINIMUM a consumer
|
|
1636
|
-
// install resolves: at `>=0.84.
|
|
1637
|
-
// Expected shape: `>=<devDep> <0.<minor+1>` (e.g. `>=0.84.
|
|
1694
|
+
// install resolves: at `>=0.84.3` an existing 0.83.x host is upgraded, not kept.
|
|
1695
|
+
// Expected shape: `>=<devDep> <0.<minor+1>` (e.g. `>=0.84.3 <0.85`).
|
|
1638
1696
|
const [piMaj, piMin] = piAi.split('.').map(Number);
|
|
1639
1697
|
assert.equal(piMaj, 0,
|
|
1640
1698
|
`pi pin major must stay 0 for the next-minor ceiling rule (got ${piAi}); revisit check-dep-versions when pi reaches 1.x`);
|
|
@@ -2741,6 +2799,9 @@ check_pack() {
|
|
|
2741
2799
|
"mcp/entwurf-bridge/dist/scripts/doctor-pi-provider.js"
|
|
2742
2800
|
"mcp/entwurf-bridge/dist/scripts/new-session-id.js"
|
|
2743
2801
|
"mcp/entwurf-bridge/dist/scripts/meta-bridge-prune.js"
|
|
2802
|
+
# #81 — the boot probe doctor-pi-provider imports (and `entwurf probe-bridge-command` runs).
|
|
2803
|
+
# Without the twin the installed doctor dies on the import before printing a verdict.
|
|
2804
|
+
"mcp/entwurf-bridge/dist/scripts/probe-bridge-command.js"
|
|
2744
2805
|
# The generation verb. The hosts that need it are installed hosts on a
|
|
2745
2806
|
# previous-generation store; without this twin the prescription every
|
|
2746
2807
|
# v3-only rejection names would be dead exactly where it matters.
|
|
@@ -2753,6 +2814,9 @@ check_pack() {
|
|
|
2753
2814
|
# strip-types under node_modules). meta-session.js is shared with the store-doctor
|
|
2754
2815
|
# above; listed here too so the hook axis fails loud if the emit graph drops it.
|
|
2755
2816
|
"mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook.js"
|
|
2817
|
+
# #82 — the Copilot birth entry's compiled closure, for the same node_modules
|
|
2818
|
+
# strip-types refusal that forces the Claude one.
|
|
2819
|
+
"mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook-copilot.js"
|
|
2756
2820
|
"mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js"
|
|
2757
2821
|
"scripts/postinstall-chmod.cjs"
|
|
2758
2822
|
"pi/entwurf-capabilities.json"
|
|
@@ -2765,6 +2829,23 @@ check_pack() {
|
|
|
2765
2829
|
# It rides a per-FILE entry in the files array (not a whole directory), so one
|
|
2766
2830
|
# deleted line drops it from the tarball while every other gate stays green.
|
|
2767
2831
|
"pi/meta-bridge/entwurf-meta-receive/scripts/hook-launch.sh"
|
|
2832
|
+
# #82 — the Copilot BIRTH unit. It is a SECOND marketplace root, not a second
|
|
2833
|
+
# plugin inside the Claude one: the Claude installer assembles one root and copies
|
|
2834
|
+
# one plugin out of it, so a shared marketplace.json would publish a `source` the
|
|
2835
|
+
# assembly does not contain. Same per-FILE listing discipline as the Claude unit.
|
|
2836
|
+
"pi/meta-bridge-copilot/.claude-plugin/marketplace.json"
|
|
2837
|
+
"pi/meta-bridge-copilot/entwurf-meta-receive-copilot/.claude-plugin/plugin.json"
|
|
2838
|
+
"pi/meta-bridge-copilot/entwurf-meta-receive-copilot/hooks/hooks.json"
|
|
2839
|
+
"pi/meta-bridge-copilot/entwurf-meta-receive-copilot/scripts/copilot-hook-launch.sh"
|
|
2840
|
+
"pi-extensions/meta-bridge-hook-copilot.ts"
|
|
2841
|
+
"scripts/copilot-bridge-install.sh"
|
|
2842
|
+
"scripts/copilot-bridge-doctor.sh"
|
|
2843
|
+
# #82 RAIL 5 — the Copilot RECEIVER. A vendor EXTENSION (forked child, stdio
|
|
2844
|
+
# JSON-RPC), not a plugin, so it ships as its own unit and installs into the user
|
|
2845
|
+
# extensions dir. `extension.mjs` is the vendor's required entry NAME: a rename in
|
|
2846
|
+
# the tarball is not a degraded path, it is a unit Copilot never discovers.
|
|
2847
|
+
"pi/copilot-receive/entwurf-receive/extension.mjs"
|
|
2848
|
+
"scripts/copilot-receive-bridge.sh"
|
|
2768
2849
|
"pi-extensions/meta-bridge-hook.ts"
|
|
2769
2850
|
"pi-extensions/lib/meta-session.ts"
|
|
2770
2851
|
"pi-extensions/lib/session-id.js"
|
|
@@ -2832,7 +2913,41 @@ check_pack() {
|
|
|
2832
2913
|
return 1
|
|
2833
2914
|
}
|
|
2834
2915
|
|
|
2916
|
+
# The pin-leak filter for the install tree's .pnpm listing, shared by the real scan and its
|
|
2917
|
+
# self-test below. The version BOUNDARY is load-bearing: a pnpm .pnpm entry is
|
|
2918
|
+
# `<name>@<version>` followed by either `_<peer-hash>` or end-of-name (measured pnpm 11.20.0
|
|
2919
|
+
# on this tree), so an unbounded substring match would bless a lookalike such as `@0.84.30`
|
|
2920
|
+
# while announcing the pinned floor — a false-green oracle (found by independent review,
|
|
2921
|
+
# 2026-08-25).
|
|
2922
|
+
pack_install_leaked_pi() {
|
|
2923
|
+
grep '^@earendil-works+pi-' | grep -Ev '@0\.84\.3(_|$)' || true
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
# Matcher self-test on SYNTHETIC lookalikes: a healthy install tree cannot exercise the
|
|
2927
|
+
# false-green shape (it contains no 0.84.30), so the oracle is proven against a fixture
|
|
2928
|
+
# listing. Expected: the two lookalikes leak, the pinned version passes bare and with a
|
|
2929
|
+
# peer-hash suffix. Exposed as its own snapshot-safe subcommand because the heavy
|
|
2930
|
+
# check-pack-install cannot run inside the qualification snapshot (no install environment),
|
|
2931
|
+
# and a kill-proof needs a control-green gate there; check-pack-install still runs this
|
|
2932
|
+
# first so the heavy gate cannot proceed on a broken oracle.
|
|
2933
|
+
check_pack_pin_matcher() {
|
|
2934
|
+
local matcher_probe
|
|
2935
|
+
matcher_probe=$(printf '%s\n' \
|
|
2936
|
+
'@earendil-works+pi-ai@0.84.3' \
|
|
2937
|
+
'@earendil-works+pi-ai@0.84.3_@modelcontextprotocol+sdk@1.29.0_zod@4.3.6' \
|
|
2938
|
+
'@earendil-works+pi-ai@0.84.30' \
|
|
2939
|
+
'@earendil-works+pi-agent-core@0.84.2' | pack_install_leaked_pi)
|
|
2940
|
+
if [ "$matcher_probe" != '@earendil-works+pi-ai@0.84.30
|
|
2941
|
+
@earendil-works+pi-agent-core@0.84.2' ]; then
|
|
2942
|
+
fail "[QK:PACK-INSTALL-PIN-MATCHER-BOUNDED] the pin-leak matcher must flag the 0.84.30/0.84.2 lookalikes and pass 0.84.3 bare or with a peer-hash — got: ${matcher_probe:-<nothing leaked>}"
|
|
2943
|
+
return 1
|
|
2944
|
+
fi
|
|
2945
|
+
echo "[check-pack-pin-matcher] ok — the pin-leak matcher is version-bounded (lookalikes leak, pinned version passes bare and with a peer-hash)"
|
|
2946
|
+
}
|
|
2947
|
+
|
|
2835
2948
|
_check_pack_install_impl() {
|
|
2949
|
+
check_pack_pin_matcher || return 1
|
|
2950
|
+
|
|
2836
2951
|
# Heavy publish gate. Runs the remaining three checks in #13's
|
|
2837
2952
|
# publish checklist that check_pack (dry-run only) does not cover:
|
|
2838
2953
|
#
|
|
@@ -2940,6 +3055,8 @@ _check_pack_install_impl() {
|
|
|
2940
3055
|
"mcp/entwurf-bridge/dist/scripts/doctor-pi-provider.js"
|
|
2941
3056
|
"mcp/entwurf-bridge/dist/scripts/new-session-id.js"
|
|
2942
3057
|
"mcp/entwurf-bridge/dist/scripts/meta-bridge-prune.js"
|
|
3058
|
+
# #81 — the boot probe the installed doctor imports (see check-pack).
|
|
3059
|
+
"mcp/entwurf-bridge/dist/scripts/probe-bridge-command.js"
|
|
2943
3060
|
# The generation verb (see check-pack). The installed-command regression below
|
|
2944
3061
|
# opens a fresh generation on a 0-record sandbox through the real bin.
|
|
2945
3062
|
"mcp/entwurf-bridge/dist/scripts/meta-bridge-fresh-cut.js"
|
|
@@ -2948,6 +3065,9 @@ _check_pack_install_impl() {
|
|
|
2948
3065
|
# 0.12.5 — node_modules-safe plugin hook + lib (see check-pack). The installed
|
|
2949
3066
|
# hook regression below runs exactly this compiled JS from under node_modules.
|
|
2950
3067
|
"mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook.js"
|
|
3068
|
+
# #82 — the Copilot birth entry's compiled closure, for the same node_modules
|
|
3069
|
+
# strip-types refusal that forces the Claude one.
|
|
3070
|
+
"mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-hook-copilot.js"
|
|
2951
3071
|
"mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js"
|
|
2952
3072
|
"scripts/postinstall-chmod.cjs"
|
|
2953
3073
|
"pi/entwurf-capabilities.json"
|
|
@@ -2959,6 +3079,23 @@ _check_pack_install_impl() {
|
|
|
2959
3079
|
# both callers source. The install smoke below asserts the ASSEMBLED launcher is
|
|
2960
3080
|
# executable; this asserts the artifact it is assembled FROM actually shipped.
|
|
2961
3081
|
"pi/meta-bridge/entwurf-meta-receive/scripts/hook-launch.sh"
|
|
3082
|
+
# #82 — the Copilot BIRTH unit. It is a SECOND marketplace root, not a second
|
|
3083
|
+
# plugin inside the Claude one: the Claude installer assembles one root and copies
|
|
3084
|
+
# one plugin out of it, so a shared marketplace.json would publish a `source` the
|
|
3085
|
+
# assembly does not contain. Same per-FILE listing discipline as the Claude unit.
|
|
3086
|
+
"pi/meta-bridge-copilot/.claude-plugin/marketplace.json"
|
|
3087
|
+
"pi/meta-bridge-copilot/entwurf-meta-receive-copilot/.claude-plugin/plugin.json"
|
|
3088
|
+
"pi/meta-bridge-copilot/entwurf-meta-receive-copilot/hooks/hooks.json"
|
|
3089
|
+
"pi/meta-bridge-copilot/entwurf-meta-receive-copilot/scripts/copilot-hook-launch.sh"
|
|
3090
|
+
"pi-extensions/meta-bridge-hook-copilot.ts"
|
|
3091
|
+
"scripts/copilot-bridge-install.sh"
|
|
3092
|
+
"scripts/copilot-bridge-doctor.sh"
|
|
3093
|
+
# #82 RAIL 5 — the Copilot RECEIVER. A vendor EXTENSION (forked child, stdio
|
|
3094
|
+
# JSON-RPC), not a plugin, so it ships as its own unit and installs into the user
|
|
3095
|
+
# extensions dir. `extension.mjs` is the vendor's required entry NAME: a rename in
|
|
3096
|
+
# the tarball is not a degraded path, it is a unit Copilot never discovers.
|
|
3097
|
+
"pi/copilot-receive/entwurf-receive/extension.mjs"
|
|
3098
|
+
"scripts/copilot-receive-bridge.sh"
|
|
2962
3099
|
"pi-extensions/meta-bridge-hook.ts"
|
|
2963
3100
|
"pi-extensions/lib/meta-session.ts"
|
|
2964
3101
|
"pi-extensions/lib/session-id.js"
|
|
@@ -3021,7 +3158,7 @@ _check_pack_install_impl() {
|
|
|
3021
3158
|
printf '%s\n' '{ "name": "entwurf-install-smoke", "version": "0.0.0", "private": true }' > "$tmp/package.json"
|
|
3022
3159
|
|
|
3023
3160
|
# pi-agent-core is pinned even though we never import it: pi-coding-agent depends
|
|
3024
|
-
# on it by CARET (`^0.84.
|
|
3161
|
+
# on it by CARET (`^0.84.3`), so with no lockfile in this fresh temp project it
|
|
3025
3162
|
# floats to whatever pi published last — and that newer core then drags a NESTED
|
|
3026
3163
|
# pi-ai of its own. Measured 2026-07-21: pinning only the three we import left
|
|
3027
3164
|
# pi-agent-core@0.80.10 + pi-ai@0.80.10 in the tree while the gate still announced
|
|
@@ -3040,12 +3177,12 @@ _check_pack_install_impl() {
|
|
|
3040
3177
|
local install_log
|
|
3041
3178
|
install_log=$(cd "$tmp" && pnpm add \
|
|
3042
3179
|
"$tgz_path" \
|
|
3043
|
-
"@earendil-works/pi-ai@0.84.
|
|
3044
|
-
"@earendil-works/pi-coding-agent@0.84.
|
|
3045
|
-
"@earendil-works/pi-tui@0.84.
|
|
3046
|
-
"@earendil-works/pi-agent-core@0.84.
|
|
3047
|
-
"@earendil-works/pi-client@0.84.
|
|
3048
|
-
"@earendil-works/pi-protocol@0.84.
|
|
3180
|
+
"@earendil-works/pi-ai@0.84.3" \
|
|
3181
|
+
"@earendil-works/pi-coding-agent@0.84.3" \
|
|
3182
|
+
"@earendil-works/pi-tui@0.84.3" \
|
|
3183
|
+
"@earendil-works/pi-agent-core@0.84.3" \
|
|
3184
|
+
"@earendil-works/pi-client@0.84.3" \
|
|
3185
|
+
"@earendil-works/pi-protocol@0.84.3" \
|
|
3049
3186
|
"typebox@latest" \
|
|
3050
3187
|
--ignore-workspace --ignore-scripts 2>&1) || {
|
|
3051
3188
|
fail "[check-pack-install] pnpm add failed:"
|
|
@@ -3055,17 +3192,17 @@ _check_pack_install_impl() {
|
|
|
3055
3192
|
|
|
3056
3193
|
# A pin is a wish until the resolved tree is read back. Assert it: EVERY
|
|
3057
3194
|
# @earendil-works pi package present — direct or transitive, top level or nested —
|
|
3058
|
-
# must be the pinned 0.84.
|
|
3195
|
+
# must be the pinned 0.84.3. Anything else means an unpinned caret floated and the
|
|
3059
3196
|
# rest of this gate would be exercising a runtime nobody verified, while still
|
|
3060
|
-
# printing "pinned pi 0.84.
|
|
3197
|
+
# printing "pinned pi 0.84.3". Fail loud instead of proving the wrong floor.
|
|
3061
3198
|
local leaked_pi
|
|
3062
|
-
leaked_pi=$(ls "$tmp/node_modules/.pnpm" 2>/dev/null |
|
|
3199
|
+
leaked_pi=$(ls "$tmp/node_modules/.pnpm" 2>/dev/null | pack_install_leaked_pi)
|
|
3063
3200
|
if [ -n "$leaked_pi" ]; then
|
|
3064
|
-
fail "[check-pack-install] UNVERIFIED pi runtime resolved into the install tree (expected only 0.84.
|
|
3201
|
+
fail "[check-pack-install] UNVERIFIED pi runtime resolved into the install tree (expected only 0.84.3):"
|
|
3065
3202
|
printf '%s\n' "$leaked_pi" | sed 's/^/ /' >&2
|
|
3066
3203
|
return 1
|
|
3067
3204
|
fi
|
|
3068
|
-
echo "[check-pack-install] pi runtime tree pin verified: every @earendil-works pi package is 0.84.
|
|
3205
|
+
echo "[check-pack-install] pi runtime tree pin verified: every @earendil-works pi package is 0.84.3"
|
|
3069
3206
|
|
|
3070
3207
|
# Resolve the installed package.json and confirm pi.extensions
|
|
3071
3208
|
# arrived intact. If pi.extensions is empty or missing, the
|
|
@@ -3218,6 +3355,11 @@ _check_pack_install_impl() {
|
|
|
3218
3355
|
ls -l "$npmroot/node_modules/.bin" 2>/dev/null | sed 's/^/ /' >&2 || true
|
|
3219
3356
|
return 1
|
|
3220
3357
|
fi
|
|
3358
|
+
if [ ! -x "$npmroot/node_modules/.bin/entwurf-copilot-statusline" ]; then
|
|
3359
|
+
fail "[check-pack-install] npm-managed neutral install missing package bin entwurf-copilot-statusline"
|
|
3360
|
+
ls -l "$npmroot/node_modules/.bin" 2>/dev/null | sed 's/^/ /' >&2 || true
|
|
3361
|
+
return 1
|
|
3362
|
+
fi
|
|
3221
3363
|
wire_log=$(HOME="$npmhome" XDG_DATA_HOME="$npmhome/.local/share" XDG_STATE_HOME="$npmhome/.local/state" XDG_CACHE_HOME="$npmhome/.cache" "$npm_pkg/run.sh" install "$npmproj" 2>&1) || {
|
|
3222
3364
|
fail "[check-pack-install] npm-managed run.sh install failed (preflight rejected hoisted deps?):"
|
|
3223
3365
|
echo "$wire_log" | tail -15 | sed 's/^/ /' >&2
|
|
@@ -3388,6 +3530,48 @@ SH
|
|
|
3388
3530
|
fi
|
|
3389
3531
|
rm -rf "$nm_probe"
|
|
3390
3532
|
echo "[check-pack-install] installed hook is node_modules-safe compiled JS (hooks.json points at .js; runs under node_modules with plain node; raw .ts refused there by the strip-types fence)"
|
|
3533
|
+
|
|
3534
|
+
# --- #82: the Copilot birth unit's INSTALLED-PACKAGE branch ------------------
|
|
3535
|
+
# check-copilot-birth-hook drives the installer from a DEV CLONE, so it only ever
|
|
3536
|
+
# exercises the `.ts` branch. The installed-package branch — compiled
|
|
3537
|
+
# meta-bridge-hook-copilot.js, its rewritten `./lib/meta-session.js` import, the
|
|
3538
|
+
# registry copied to the plugin root — was covered by pack LISTS and by nothing that
|
|
3539
|
+
# RUNS it, which is the shape Hard Rule 11 exists to refuse (cross-review, terra +
|
|
3540
|
+
# glm independently, 2026-08-21).
|
|
3541
|
+
#
|
|
3542
|
+
# `--assemble-only` stops before the Copilot CLI, so this needs no Copilot and no fake
|
|
3543
|
+
# of one. A fake Copilot CLI would only prove our script calls our fake the way we
|
|
3544
|
+
# wrote it — the vendor contract is unmeasured, and the first real execution is the
|
|
3545
|
+
# §6 admission itself. This asserts the CITIZEN, not merely that a node process ran.
|
|
3546
|
+
local cop_asm="$npm_tmp/copilot-asm" cop_store cop_log
|
|
3547
|
+
cop_store="$(mktemp -d)"
|
|
3548
|
+
if ! cop_log=$(HOME="$mb_home" XDG_DATA_HOME="$mb_home/.local/share" ENTWURF_COPILOT_ASM="$cop_asm" PATH="$npmroot/node_modules/.bin:$PATH" "$npm_pkg/run.sh" install-copilot-bridge --assemble-only 2>&1); then
|
|
3549
|
+
fail "[check-pack-install] installed install-copilot-bridge --assemble-only failed:"
|
|
3550
|
+
echo "$cop_log" | tail -20 | sed 's/^/ /' >&2
|
|
3551
|
+
return 1
|
|
3552
|
+
fi
|
|
3553
|
+
local cop_unit="$cop_asm/entwurf-meta-receive-copilot"
|
|
3554
|
+
# Branch SELECTION, pinned: an installed package must assemble the compiled entry and
|
|
3555
|
+
# no raw .ts. Without this the fire below could pass on a layout that silently chose
|
|
3556
|
+
# the dev-clone branch.
|
|
3557
|
+
if [ ! -f "$cop_unit/meta-bridge-hook-copilot.js" ] || [ -f "$cop_unit/meta-bridge-hook-copilot.ts" ]; then
|
|
3558
|
+
fail "[check-pack-install] installed install-copilot-bridge did not select the compiled branch (want meta-bridge-hook-copilot.js, no raw .ts) in $cop_unit"
|
|
3559
|
+
return 1
|
|
3560
|
+
fi
|
|
3561
|
+
local cop_out
|
|
3562
|
+
# Fired the way Copilot fires it: NO ARGV, envelope on stdin.
|
|
3563
|
+
if ! cop_out="$(printf '%s' '{"sessionId":"pack-copilot-probe","cwd":"/tmp","source":"new"}' | env PI_CODING_AGENT_DIR="$cop_store" "$cop_unit/scripts/copilot-hook-launch.sh" 2>&1)"; then
|
|
3564
|
+
fail "[check-pack-install] the installed Copilot launcher failed: $(printf '%s' "$cop_out" | tr '\n' ' ' | cut -c1-200)"
|
|
3565
|
+
return 1
|
|
3566
|
+
fi
|
|
3567
|
+
local cop_records
|
|
3568
|
+
cop_records="$(grep -l '"backend": "copilot"' "$cop_store"/meta-sessions/*.meta.json 2>/dev/null | wc -l | tr -d ' ')"
|
|
3569
|
+
if [ "$cop_records" != "1" ]; then
|
|
3570
|
+
fail "[check-pack-install] the installed Copilot unit did not mint exactly one copilot citizen (found ${cop_records:-0}); log: $(tail -1 "$cop_store/meta-bridge-hook.log" 2>/dev/null)"
|
|
3571
|
+
return 1
|
|
3572
|
+
fi
|
|
3573
|
+
rm -rf "$cop_store"
|
|
3574
|
+
echo "[check-pack-install] installed Copilot birth unit assembles its compiled branch and mints a citizen from a no-argv launch"
|
|
3391
3575
|
python3 - "$mb_cfg/settings.json" "$mb_home/.claude.json" "$stable_asm" <<'PY'
|
|
3392
3576
|
import json, sys
|
|
3393
3577
|
settings = json.load(open(sys.argv[1]))
|
|
@@ -3590,6 +3774,60 @@ JS
|
|
|
3590
3774
|
return 1
|
|
3591
3775
|
fi
|
|
3592
3776
|
|
|
3777
|
+
# #82 RAIL 7 — the managed launch, from the INSTALLED package. Hard Rule 11: a green
|
|
3778
|
+
# clone is not a green tarball. `entwurf copilot` is a bash leaf, so its risk here is
|
|
3779
|
+
# not the strip-types fence but PACKAGING — `scripts/copilot-launch.sh` has to be in
|
|
3780
|
+
# the tarball and reachable from the installed `run.sh`, and a file-list assertion
|
|
3781
|
+
# cannot tell a shipped script from a shipped script that resolves its siblings wrongly
|
|
3782
|
+
# once it lives under node_modules. So the cell RUNS it, against a fake vendor on a
|
|
3783
|
+
# sandbox PATH and a fake receiver install-state, and reads what the vendor was handed.
|
|
3784
|
+
local cop_launch_home="$npm_tmp/cop-launch-home" cop_launch_xdg="$npm_tmp/cop-launch-xdg" cop_launch_bin="$npm_tmp/cop-launch-bin"
|
|
3785
|
+
local cop_unit_dir="$cop_launch_home/.copilot/extensions/entwurf-receive"
|
|
3786
|
+
local cop_state_dir="$cop_launch_xdg/entwurf/copilot-receive"
|
|
3787
|
+
mkdir -p "$cop_unit_dir" "$cop_state_dir" "$cop_launch_bin"
|
|
3788
|
+
printf '// fixture\n' > "$cop_unit_dir/extension.mjs"
|
|
3789
|
+
printf '{"schemaVersion":1,"unit":"entwurf-receive","path":"%s"}\n' "$cop_unit_dir" > "$cop_state_dir/install-state.json"
|
|
3790
|
+
# The stand-in is installed under the REAL name on a sandbox PATH: the launcher resolves
|
|
3791
|
+
# `copilot` and nothing else, so there is no env switch here to prove the wrong contract with.
|
|
3792
|
+
{
|
|
3793
|
+
printf '#!/usr/bin/env bash\n'
|
|
3794
|
+
printf 'echo "FLAG=[${COPILOT_CLI_ENABLED_FEATURE_FLAGS-<unset>}]"\n'
|
|
3795
|
+
printf 'for a in "$@"; do printf "ARG<%%s>\\n" "$a"; done\n'
|
|
3796
|
+
} > "$cop_launch_bin/copilot"
|
|
3797
|
+
chmod +x "$cop_launch_bin/copilot"
|
|
3798
|
+
# `env -u` for BOTH carriers, not just a reassignment: an operator running this gate with
|
|
3799
|
+
# their own COPILOT_CLI_ENABLED_FEATURE_FLAGS exported would otherwise inherit those tokens
|
|
3800
|
+
# into the oracle below and read a FALSE RED, and an inherited launch sentinel would trip
|
|
3801
|
+
# the recursion fence before the vendor was ever reached. The cell must measure the
|
|
3802
|
+
# installed launcher, not the shell that happened to start it.
|
|
3803
|
+
if ! op_out=$(env -u COPILOT_CLI_ENABLED_FEATURE_FLAGS -u ENTWURF_COPILOT_LAUNCH_ACTIVE \
|
|
3804
|
+
HOME="$cop_launch_home" XDG_DATA_HOME="$cop_launch_xdg" PATH="$cop_launch_bin:$PATH" \
|
|
3805
|
+
"$installed_entwurf" copilot -p hi 2>&1); then
|
|
3806
|
+
fail "[check-pack-install] installed 'entwurf copilot' FAILED to reach the vendor:"
|
|
3807
|
+
echo "$op_out" | tail -8 | sed 's/^/ /' >&2
|
|
3808
|
+
return 1
|
|
3809
|
+
fi
|
|
3810
|
+
# Assert MEANING: the scan flag this whole surface exists to set, the managed defaults,
|
|
3811
|
+
# and the operator's own argument, all arriving at the vendor from the installed tree.
|
|
3812
|
+
if ! printf '%s' "$op_out" | grep -q 'FLAG=\[EXTENSIONS\]'; then
|
|
3813
|
+
fail "[check-pack-install] installed 'entwurf copilot' did not hand the vendor COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS:"
|
|
3814
|
+
echo "$op_out" | tail -8 | sed 's/^/ /' >&2
|
|
3815
|
+
return 1
|
|
3816
|
+
fi
|
|
3817
|
+
for want in 'ARG<-p>' 'ARG<hi>' 'ARG<--model>' 'ARG<auto>' 'ARG<--yolo>'; do
|
|
3818
|
+
if ! printf '%s' "$op_out" | grep -qF "$want"; then
|
|
3819
|
+
fail "[check-pack-install] installed 'entwurf copilot' did not forward the managed argv (missing $want):"
|
|
3820
|
+
echo "$op_out" | tail -8 | sed 's/^/ /' >&2
|
|
3821
|
+
return 1
|
|
3822
|
+
fi
|
|
3823
|
+
done
|
|
3824
|
+
if printf '%s' "$op_out" | grep -qF 'ARG<copilot>'; then
|
|
3825
|
+
fail "[check-pack-install] installed 'entwurf copilot' leaked the dispatcher verb into the vendor's argv:"
|
|
3826
|
+
echo "$op_out" | tail -8 | sed 's/^/ /' >&2
|
|
3827
|
+
return 1
|
|
3828
|
+
fi
|
|
3829
|
+
echo "[check-pack-install] installed 'entwurf copilot' reached the vendor with the scan flag and the managed argv"
|
|
3830
|
+
|
|
3593
3831
|
# The generation verb must reach its verdict from under node_modules. On the
|
|
3594
3832
|
# sandbox 0-record agent dir it archives nothing and opens a fresh generation.
|
|
3595
3833
|
# The exit code alone can't tell a verdict from a fence crash, so read the line.
|
|
@@ -4463,6 +4701,23 @@ release_gate() {
|
|
|
4463
4701
|
# is gated behind SMOKE_RGG_POSITIVE=1 in the BEHAVIOR lane below.
|
|
4464
4702
|
run_step "smoke-resident-garden-guard (3c citizen: record birth / record-keyed socket / attach-on-reopen, 0-token)" gate env SMOKE_RGG_POSITIVE=0 bash "$self" smoke-resident-garden-guard
|
|
4465
4703
|
run_step "check-bridge" gate bash "$self" check-bridge
|
|
4704
|
+
# check-bridge booted the launcher THIS CHECKOUT ships; this boots the invocation the operator's
|
|
4705
|
+
# pi provider actually EXECS. Two different strings, and only the second one reaches a live ACP
|
|
4706
|
+
# session. 2026-08-19 measured the gap at full price: `~/.local/bin/entwurf-bridge` had been
|
|
4707
|
+
# relocated onto a pnpm cmd-shim (basedir derived from $0, so not relocatable), it exited 127, the
|
|
4708
|
+
# bundled bridge never booted, and the model had no `mcp__entwurf-bridge__*` tool — while
|
|
4709
|
+
# `command -v` answered yes throughout. #81's probe already settles that in under a second and
|
|
4710
|
+
# doctor-pi-provider consumes it; it was simply never a step, so the verdict first surfaced at
|
|
4711
|
+
# smoke-acp-bundled-mcp-live, sixteen LIVE steps and ~20 minutes of real model spend later.
|
|
4712
|
+
# `run_step`, not `run_live_step`: this doctor is not LIVE-gated and never emits 97, so it has no
|
|
4713
|
+
# prerequisite to decline. It exits 1 for a configured invocation that will not boot and for
|
|
4714
|
+
# state-owned drift; a host that never installed the circuit keeps its existing exit 0 note, and
|
|
4715
|
+
# the bundled smokes below still fail loud there. So this tightens nothing — it only moves an
|
|
4716
|
+
# existing red earlier. cwd is REPO_DIR regardless of `gate` (run_ts cds there), so the scope
|
|
4717
|
+
# judged is this checkout's `.pi/settings.json` shadowing the operator's global: deterministic,
|
|
4718
|
+
# but not in principle the smokes' global-only subject if the two ever diverge.
|
|
4719
|
+
# Position and classifier arm are pinned by [QK:PI-DOCTOR-IS-RELEASE-MUST].
|
|
4720
|
+
run_step "doctor-pi-provider (#81: the operator's CONFIGURED bridge invocation actually boots)" gate bash "$self" doctor-pi-provider
|
|
4466
4721
|
# D4-c: the v2 dispatch substrate sentinel (5d-5). A SINGLE run (NOT backend-looped — it proves
|
|
4467
4722
|
# production runEntwurfV2 deps + real pi control-socket RPC + real mailbox enqueue + v2 lock, not
|
|
4468
4723
|
# per-backend model behavior). Placed right after check-bridge: the MCP/protocol substrate must be
|
|
@@ -4654,6 +4909,18 @@ case "$cmd" in
|
|
|
4654
4909
|
check-hook-launch-topology)
|
|
4655
4910
|
check_hook_launch_topology
|
|
4656
4911
|
;;
|
|
4912
|
+
check-copilot-birth-hook)
|
|
4913
|
+
check_copilot_birth_hook
|
|
4914
|
+
;;
|
|
4915
|
+
check-copilot-statusline)
|
|
4916
|
+
check_copilot_statusline
|
|
4917
|
+
;;
|
|
4918
|
+
check-copilot-launch)
|
|
4919
|
+
check_copilot_launch
|
|
4920
|
+
;;
|
|
4921
|
+
check-copilot-receive-arm)
|
|
4922
|
+
check_copilot_receive_arm
|
|
4923
|
+
;;
|
|
4657
4924
|
check-meta-capability-source)
|
|
4658
4925
|
check_meta_capability_source
|
|
4659
4926
|
;;
|
|
@@ -5038,6 +5305,77 @@ case "$cmd" in
|
|
|
5038
5305
|
# zero claude-code meta-records is a SILENT MISS -> non-zero exit.
|
|
5039
5306
|
(cd "$REPO_DIR" && bash scripts/meta-bridge-doctor.sh "$@")
|
|
5040
5307
|
;;
|
|
5308
|
+
install-copilot-bridge)
|
|
5309
|
+
# #82: the Copilot BIRTH install. Deliberately not a mode of install-meta-bridge —
|
|
5310
|
+
# it assembles its OWN marketplace root (the Claude assembler copies one plugin out
|
|
5311
|
+
# of one root, so a shared marketplace.json would publish a missing `source`), it
|
|
5312
|
+
# bakes node+entry into the launcher rather than into the manifest (Copilot's exec
|
|
5313
|
+
# form is a single string with no argv beside it), and it wires NO MCP: a drain tool
|
|
5314
|
+
# for a mailbox nothing rings would advertise delivery this backend does not have.
|
|
5315
|
+
shift || true
|
|
5316
|
+
(cd "$REPO_DIR" && bash scripts/copilot-bridge-install.sh "$@")
|
|
5317
|
+
;;
|
|
5318
|
+
doctor-copilot-bridge)
|
|
5319
|
+
# #82: the fail-loud surface for the Copilot unit. Its red conditions differ from
|
|
5320
|
+
# the Claude doctor's on purpose: a Copilot session mints on its FIRST PROMPT, not
|
|
5321
|
+
# at session open, so "installed with zero records" is reported as NOT-YET rather
|
|
5322
|
+
# than as a silent miss. Red is a hook that RAN and failed.
|
|
5323
|
+
shift || true
|
|
5324
|
+
(cd "$REPO_DIR" && bash scripts/copilot-bridge-doctor.sh "$@")
|
|
5325
|
+
;;
|
|
5326
|
+
install-copilot-statusline)
|
|
5327
|
+
(cd "$REPO_DIR" && bash scripts/copilot-statusline-bridge.sh install "$@")
|
|
5328
|
+
;;
|
|
5329
|
+
uninstall-copilot-statusline)
|
|
5330
|
+
(cd "$REPO_DIR" && bash scripts/copilot-statusline-bridge.sh uninstall "$@")
|
|
5331
|
+
;;
|
|
5332
|
+
doctor-copilot-statusline)
|
|
5333
|
+
(cd "$REPO_DIR" && bash scripts/copilot-statusline-bridge.sh doctor "$@")
|
|
5334
|
+
;;
|
|
5335
|
+
smoke-copilot-statusline-state)
|
|
5336
|
+
(cd "$REPO_DIR" && bash scripts/smoke-copilot-statusline-state.sh)
|
|
5337
|
+
;;
|
|
5338
|
+
install-copilot-mcp)
|
|
5339
|
+
(cd "$REPO_DIR" && bash scripts/copilot-mcp-bridge.sh install "$@")
|
|
5340
|
+
;;
|
|
5341
|
+
uninstall-copilot-mcp)
|
|
5342
|
+
(cd "$REPO_DIR" && bash scripts/copilot-mcp-bridge.sh uninstall "$@")
|
|
5343
|
+
;;
|
|
5344
|
+
doctor-copilot-mcp)
|
|
5345
|
+
(cd "$REPO_DIR" && bash scripts/copilot-mcp-bridge.sh doctor "$@")
|
|
5346
|
+
;;
|
|
5347
|
+
smoke-copilot-mcp-state)
|
|
5348
|
+
(cd "$REPO_DIR" && bash scripts/smoke-copilot-mcp-state.sh)
|
|
5349
|
+
;;
|
|
5350
|
+
copilot)
|
|
5351
|
+
# #82 RAIL 7: the managed launch. `exec` and NO subshell/cd on purpose — the vendor
|
|
5352
|
+
# must inherit this terminal exactly: the caller's cwd, this pid, this tty, and its own
|
|
5353
|
+
# exit status. The sibling install/doctor verbs wrap themselves in `(cd "$REPO_DIR" && …)`
|
|
5354
|
+
# because they operate on the repo; this one operates on the operator's session, and a
|
|
5355
|
+
# subshell would make run.sh a parent that outlives nothing and owns nothing.
|
|
5356
|
+
#
|
|
5357
|
+
# `shift` is load-bearing here, not cosmetic: this dispatcher keeps the verb in "$@"
|
|
5358
|
+
# and each branch drops it for itself. The neighbouring install/doctor verbs get away
|
|
5359
|
+
# without one because their bridge scripts take a leading subcommand and ignore the
|
|
5360
|
+
# trailing noise; this branch forwards straight into the VENDOR's argv, where a stray
|
|
5361
|
+
# "copilot" would arrive as a prompt argument.
|
|
5362
|
+
shift || true
|
|
5363
|
+
exec bash "$REPO_DIR/scripts/copilot-launch.sh" "$@"
|
|
5364
|
+
;;
|
|
5365
|
+
install-copilot-receive)
|
|
5366
|
+
# #82 RAIL 5: install the RECEIVER extension into the Copilot USER extensions dir.
|
|
5367
|
+
# Artifact ownership only — it sets no launch flag (`run.sh copilot` owns one
|
|
5368
|
+
# invocation's environment; this owns the unit on disk), and it arms
|
|
5369
|
+
# nothing by itself: a session arms after birth, on a CLI launched with
|
|
5370
|
+
# COPILOT_CLI_ENABLED_FEATURE_FLAGS=EXTENSIONS.
|
|
5371
|
+
(cd "$REPO_DIR" && bash scripts/copilot-receive-bridge.sh install "$@")
|
|
5372
|
+
;;
|
|
5373
|
+
uninstall-copilot-receive)
|
|
5374
|
+
(cd "$REPO_DIR" && bash scripts/copilot-receive-bridge.sh uninstall "$@")
|
|
5375
|
+
;;
|
|
5376
|
+
doctor-copilot-receive)
|
|
5377
|
+
(cd "$REPO_DIR" && bash scripts/copilot-receive-bridge.sh doctor "$@")
|
|
5378
|
+
;;
|
|
5041
5379
|
install-agy-bridge)
|
|
5042
5380
|
# 봉인 7: the agy (Antigravity) MCP install ADAPTER (SEPARATE from the Claude
|
|
5043
5381
|
# marketplace install — only runner/reporting is shared). Registers ONE entwurf-bridge
|
|
@@ -5103,12 +5441,34 @@ case "$cmd" in
|
|
|
5103
5441
|
# Fail-loud doctor for agy hooks.json imprint wiring.
|
|
5104
5442
|
(cd "$REPO_DIR" && bash scripts/agy-hooks-bridge.sh doctor "$@")
|
|
5105
5443
|
;;
|
|
5444
|
+
check-probe-bridge-command)
|
|
5445
|
+
# #81: contract gate for the boot probe both doctors stake their verdict on — the reason
|
|
5446
|
+
# taxonomy (each value = a different operator repair) plus the one side effect the probe owns,
|
|
5447
|
+
# reaping the child it spawned. Hermetic stubs only; boots no bridge of ours.
|
|
5448
|
+
run_ts scripts/check-probe-bridge-command.ts
|
|
5449
|
+
;;
|
|
5450
|
+
probe-bridge-command)
|
|
5451
|
+
# #81: does a configured bridge command actually BOOT and serve MCP? `command -v` answering
|
|
5452
|
+
# yes is not that claim — a relocated launcher can resolve and still exit 127, which is how a
|
|
5453
|
+
# host ran with NO bridge in its ACP turns while every doctor printed ok. It waits for the
|
|
5454
|
+
# initialize RESPONSE before it sends notifications/initialized + `tools/list` (no tools/call),
|
|
5455
|
+
# so it takes no lock, writes no record, and delivers nothing. Both doctors route their boot
|
|
5456
|
+
# cell here so one leaf owns the verdict — agy for every configured {command,args,env}, pi for
|
|
5457
|
+
# every effective stdio invocation.
|
|
5458
|
+
shift || true
|
|
5459
|
+
run_ts scripts/probe-bridge-command.ts "$@"
|
|
5460
|
+
;;
|
|
5106
5461
|
doctor-pi-provider)
|
|
5107
|
-
# #46 Task 2:
|
|
5108
|
-
# mcpServers.entwurf-bridge). Uses config.ts
|
|
5109
|
-
#
|
|
5110
|
-
#
|
|
5111
|
-
# unowned user override (honest note).
|
|
5462
|
+
# #46 Task 2 + #81: fail-loud doctor for the pi provider ownership (entwurfProvider.
|
|
5463
|
+
# mcpServers.entwurf-bridge). Uses the config.ts SSOT for the EFFECTIVE (project-shadows-user)
|
|
5464
|
+
# entry — per-name merge then ONE normalize, exactly as resolveProviderConfig does; never a
|
|
5465
|
+
# re-implemented merge. Reports user/project/effective and distinguishes state-owned drift
|
|
5466
|
+
# (FAIL) from an unowned user override (honest note).
|
|
5467
|
+
# This doctor no longer merely reads files: it BOOTS every effective stdio invocation and
|
|
5468
|
+
# requires the entwurf verb set back, because `command -v` succeeding was never evidence that
|
|
5469
|
+
# pi gets a bridge. Runtime evidence and ownership are separate: an unowned override is not
|
|
5470
|
+
# repaired, but a dead one is still red. It writes no operator state, but it does exec the
|
|
5471
|
+
# configured command on this host. No agy/pi process is needed.
|
|
5112
5472
|
run_ts scripts/doctor-pi-provider.ts "$@"
|
|
5113
5473
|
;;
|
|
5114
5474
|
wire-agy-statusline)
|
|
@@ -5271,6 +5631,9 @@ case "$cmd" in
|
|
|
5271
5631
|
check-pack)
|
|
5272
5632
|
check_pack
|
|
5273
5633
|
;;
|
|
5634
|
+
check-pack-pin-matcher)
|
|
5635
|
+
check_pack_pin_matcher
|
|
5636
|
+
;;
|
|
5274
5637
|
check-pack-install)
|
|
5275
5638
|
check_pack_install
|
|
5276
5639
|
;;
|