@junghanacs/entwurf 0.13.1 → 0.14.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.
- package/AGENTS.md +59 -15
- package/BASELINE.md +3 -3
- package/CHANGELOG.md +74 -0
- package/CONTRIBUTING.md +13 -9
- package/DELIVERY.md +7 -6
- package/README.md +37 -28
- package/VERIFY.md +22 -14
- package/demo/README.md +1 -1
- package/demo/demo-baseline.sh +1 -3
- package/demo/demo.sh +2 -5
- package/docs/acp-backend-rail.md +9 -4
- package/docs/external-mcp-host.md +4 -5
- package/docs/setup-clean-host.md +8 -7
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +155 -28
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +8 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/classify-tmux-cwd.js +47 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-control-rpc.js +7 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-core.js +13 -14
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-resume-args.js +45 -40
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +117 -95
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +23 -57
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +16 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +5 -53
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-release.js +21 -36
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-runner.js +3 -15
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send-fallback.js +12 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-send.js +2 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-surface.js +30 -67
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-visible-resume.js +256 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +91 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +300 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-launch.js +202 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-placement.js +289 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-resume-call.js +141 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/resume-launch-identity.js +136 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/session-id.js +8 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/socket-discovery.js +3 -3
- package/mcp/entwurf-bridge/dist/scripts/meta-facts.js +51 -0
- package/mcp/entwurf-bridge/dist/scripts/new-session-id.js +9 -4
- package/mcp/entwurf-bridge/src/index.ts +173 -28
- package/mcp/entwurf-bridge/start.sh +2 -2
- package/mcp/entwurf-bridge/test.sh +23 -9
- package/mcp/entwurf-bridge/tsconfig.build.json +11 -2
- package/package.json +22 -11
- package/pi-extensions/entwurf-control.ts +227 -40
- package/pi-extensions/lib/acp/backend.ts +71 -12
- package/pi-extensions/lib/acp/overlay.ts +8 -6
- package/pi-extensions/lib/classify-tmux-cwd.ts +50 -0
- package/pi-extensions/lib/entwurf-control-rpc.ts +7 -5
- package/pi-extensions/lib/entwurf-core.ts +15 -15
- package/pi-extensions/lib/entwurf-resume-args.ts +41 -52
- package/pi-extensions/lib/entwurf-v2-contract-schema.ts +1 -1
- package/pi-extensions/lib/entwurf-v2-contract.ts +120 -99
- package/pi-extensions/lib/entwurf-v2-decider.ts +30 -91
- package/pi-extensions/lib/entwurf-v2-lock.ts +16 -7
- package/pi-extensions/lib/entwurf-v2-production.ts +4 -78
- package/pi-extensions/lib/entwurf-v2-release.ts +25 -49
- package/pi-extensions/lib/entwurf-v2-runner.ts +6 -21
- package/pi-extensions/lib/entwurf-v2-send-fallback.ts +12 -11
- package/pi-extensions/lib/entwurf-v2-send.ts +2 -7
- package/pi-extensions/lib/entwurf-v2-surface.ts +36 -76
- package/pi-extensions/lib/entwurf-v2-visible-resume.ts +370 -0
- package/pi-extensions/lib/meta-session.ts +93 -5
- package/pi-extensions/lib/mux-fresh-call.ts +381 -0
- package/pi-extensions/lib/mux-launch.ts +267 -0
- package/pi-extensions/lib/mux-placement.ts +387 -0
- package/pi-extensions/lib/mux-resume-call.ts +189 -0
- package/pi-extensions/lib/resume-launch-identity.ts +162 -0
- package/pi-extensions/lib/session-id.js +8 -5
- package/pi-extensions/lib/socket-discovery.ts +3 -3
- package/run.sh +471 -201
- package/scripts/agy-bridge-config.py +5 -1
- package/scripts/check-acp-backend-preflight.ts +1 -1
- package/scripts/check-acp-overlay.ts +13 -3
- package/scripts/check-acp-stream-hooks.ts +504 -0
- package/scripts/check-elapsed.sh +25 -0
- package/scripts/check-entwurf-bridge-boot.ts +51 -4
- package/scripts/check-entwurf-bridge-pi-free.ts +6 -5
- package/scripts/check-entwurf-control-rpc.ts +4 -3
- package/scripts/check-entwurf-resume-args.ts +72 -70
- package/scripts/check-entwurf-session-identity.ts +14 -10
- package/scripts/check-entwurf-v2-contract.ts +34 -59
- package/scripts/check-entwurf-v2-decider.ts +17 -177
- package/scripts/check-entwurf-v2-lock.ts +5 -2
- package/scripts/check-entwurf-v2-matrix.ts +3 -53
- package/scripts/check-entwurf-v2-production.ts +2 -91
- package/scripts/check-entwurf-v2-release.ts +10 -105
- package/scripts/check-entwurf-v2-runner.ts +4 -85
- package/scripts/check-entwurf-v2-send-fallback.ts +5 -6
- package/scripts/check-entwurf-v2-send.ts +0 -28
- package/scripts/check-entwurf-v2-surface.ts +157 -128
- package/scripts/check-entwurf-v2-visible-resume.ts +445 -0
- package/scripts/check-fresh-cut-gate.sh +1 -1
- package/scripts/check-gate-qualification.ts +99 -7
- package/scripts/check-install-container.sh +10 -2
- package/scripts/check-install-surface.ts +1 -1
- package/scripts/check-keyset-overlap.py +1 -1
- package/scripts/check-meta-facts.ts +249 -0
- package/scripts/check-meta-identity-consumers.ts +1 -1
- package/scripts/check-meta-session.ts +169 -0
- package/scripts/check-mux-launch-tmux.ts +316 -0
- package/scripts/check-mux-launch.ts +288 -0
- package/scripts/check-mux-launcher-fence.ts +264 -0
- package/scripts/check-mux-parent-artifact.ts +195 -0
- package/scripts/check-mux-placement-tmux.ts +322 -0
- package/scripts/check-mux-placement.ts +323 -0
- package/scripts/check-mux-resume-call.ts +283 -0
- package/scripts/check-probe-cli-shim.ts +25 -22
- package/scripts/check-probe-ordering.ts +84 -76
- package/scripts/check-release-gate-outcomes.ts +127 -7
- package/scripts/check-resume-launch-identity.ts +244 -0
- package/scripts/check-socket-discovery.ts +1 -1
- package/scripts/fixtures/mux-parent-transcript.scrubbed.jsonl +3 -0
- package/scripts/inventory-verification-surface.ts +349 -0
- package/scripts/lib/claude-launcher-fence.ts +322 -0
- package/scripts/lib/mutation-qualify.ts +109 -3
- package/scripts/meta-bridge-doctor.sh +6 -8
- package/scripts/meta-bridge-state.py +75 -1
- package/scripts/meta-facts.ts +60 -0
- package/scripts/mutants/acp-overlay.json +17 -0
- package/scripts/mutants/acp-stream-hooks.json +158 -0
- package/scripts/mutants/bridge-boot-resume.json +45 -0
- package/scripts/mutants/meta-facts.json +50 -0
- package/scripts/mutants/meta-identity.json +36 -0
- package/scripts/mutants/meta-retire.json +47 -0
- package/scripts/mutants/mux-boundary.json +196 -0
- package/scripts/mutants/mux-fresh-call.json +229 -0
- package/scripts/mutants/mux-launcher-fence.json +123 -0
- package/scripts/mutants/mux-parent-artifact.json +39 -0
- package/scripts/mutants/mux-resume-call.json +148 -0
- package/scripts/mutants/probe-ordering.json +0 -1037
- package/scripts/mutants/release-gate.json +35 -0
- package/scripts/mutants/resume-args.json +76 -0
- package/scripts/mutants/resume-launch-identity.json +96 -0
- package/scripts/mutants/v2-surface.json +58 -18
- package/scripts/mutants/v2-visible-resume.json +215 -0
- package/scripts/new-session-id.ts +9 -4
- package/scripts/smoke-acp-raw-turn-live.ts +1 -1
- package/scripts/smoke-agy-native-push-live.ts +6 -17
- package/scripts/smoke-entwurf-chain-live.ts +11 -3
- package/scripts/smoke-entwurf-v2-matrix-live.ts +1 -1
- package/scripts/smoke-meta-honesty.sh +1 -1
- package/scripts/smoke-meta-install-state.sh +169 -3
- package/scripts/smoke-mux-fresh-call-live.ts +365 -0
- package/scripts/smoke-mux-lifecycle-live.ts +1136 -0
- package/scripts/smoke-pi-attach.ts +1 -1
- package/scripts/smoke-user-scope-citizen.sh +1 -1
- package/scripts/tsconfig.json +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-preflight.js +0 -160
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn-production.js +0 -273
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn.js +0 -216
- package/pi-extensions/lib/entwurf-v2-spawn-production.ts +0 -373
- package/pi-extensions/lib/entwurf-v2-spawn.ts +0 -323
- package/scripts/check-acp-sdk-surface.ts +0 -275
- package/scripts/check-entwurf-v2-spawn-production.ts +0 -551
- package/scripts/check-entwurf-v2-spawn.ts +0 -399
- package/scripts/smoke-entwurf-v2-spawn-live.ts +0 -188
- package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +0 -467
package/README.md
CHANGED
|
@@ -16,10 +16,10 @@ Legacy package: [`@junghanacs/pi-shell-acp`](https://www.npmjs.com/package/@jung
|
|
|
16
16
|
Claude Code / Codex / agy / pi
|
|
17
17
|
→ garden id
|
|
18
18
|
→ entwurf_v2
|
|
19
|
-
→ control-socket |
|
|
19
|
+
→ control-socket | meta-mailbox | native-push
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
[`entwurf_v2`](#entwurf_v2--canonical-dispatch-verb) is the canonical dispatch surface over *existing* garden citizens — live control-socket send,
|
|
22
|
+
[`entwurf_v2`](#entwurf_v2--canonical-dispatch-verb) is the canonical dispatch surface over *existing* garden citizens — live control-socket send, meta-mailbox enqueue, and native-push into a live Antigravity conversation. It starts no process on any rail: the hidden background resume that used to answer a dormant target was withdrawn under the visible-first rule, so a dormant citizen rejects honestly here and is reopened by a separate lifecycle verb, `entwurf_resume_call`. The meta-record is the sole address authority (#50 C4): a record-less control socket is refused as a `record-less-socket` diagnostic, never dispatched. The v1 entwurf verbs are gone. Fresh siblings and resumes are separate verbs — `entwurf_fresh_call` opens a NEW sibling in the operator's own tmux session and learns its garden id from the callback it makes, while `entwurf_resume_call` reopens a DORMANT pi citizen under its own garden id in a visible window without running a turn; the non-Claude ACP lane landed earlier — Snowflake Cortex Code became the second backend in 0.13.0.
|
|
23
23
|
|
|
24
24
|
**Garden id is deliberate vocabulary.** It is not a decorative synonym for session id, worker, delegate, or subagent. The unfamiliar word is a guard: each harness keeps its own identity and transcript, while `entwurf` supplies a narrow addressable surface between siblings.
|
|
25
25
|
|
|
@@ -61,7 +61,7 @@ Claude's `install-meta-bridge` and agy's `install-agy-{bridge,statusline,hooks}`
|
|
|
61
61
|
|
|
62
62
|
A few words that look unusual for a coding tool.
|
|
63
63
|
|
|
64
|
-
- **Entwurf** (기투, projection-of-self) — sibling sessions with their own runtime boundary. Not "delegate," not "worker," not "sub-agent."
|
|
64
|
+
- **Entwurf** (기투, projection-of-self) — sibling sessions with their own runtime boundary. Not "delegate," not "worker," not "sub-agent." Opening a visible sibling (`entwurf_fresh_call`), live peer messaging (`entwurf_v2`) and reopening a dormant one (`entwurf_resume_call`) are first-class; the hidden background resume that preceded the last of those was withdrawn under the visible-first rule.
|
|
65
65
|
- **Garden / garden id** — the garden is the shared address space where independent harness sessions become citizens without losing their own runtime or transcript. A garden id is the stable address of one such citizen (for pi, a garden-native session id like `YYYYMMDDTHHMMSS-<6hex>`; for native harnesses, a meta-session id minted from an authoritative lifecycle hook — Claude `SessionStart`, agy `PreInvocation`). It is not a worker name and not proof that pi owns the session. The same-looking id may name a live control socket, a dormant pi record, a mailbox-backed native session, or a native-push conversation, so callers discover facts with `entwurf_peers` and deliver with `entwurf_v2` instead of choosing a transport by hand.
|
|
66
66
|
- **Engraving** — optional short operator text delivered through each backend's native identity carrier. Not a giant hidden prompt, not a tool catalog.
|
|
67
67
|
- **MCP** — in this repo, MCP is just the transport by which ACP-backed sessions receive pi capabilities that native pi exposes directly as extensions. It is not a general MCP platform. Explicit `entwurfProvider.mcpServers` only; no ambient `~/.mcp.json` scanning, no automatic retrieval. The same `entwurf-bridge` entry can also be wired into another host's MCP catalog (Claude Code, Codex, Antigravity, …) when the operator chooses. `entwurf_self` returns an authoritative pi-session or trusted meta-session identity envelope; `entwurf_v2` requires an authoritative sender by default (#50 C4) — a plain external MCP host with no identity lane is refused unless the operator explicitly wires the documented anonymous hatch, and even then it is never replyable.
|
|
@@ -100,8 +100,8 @@ entwurf check-bridge
|
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
This writes `.pi/settings.json` in the target project with the absolute path to
|
|
103
|
-
the installed `entwurf-bridge` launcher.
|
|
104
|
-
|
|
103
|
+
the installed `entwurf-bridge` launcher. (The old `~/.pi/agent/` target-registry
|
|
104
|
+
link is gone — #50 C3; nothing reads it.) The global install is the easiest path when
|
|
105
105
|
Claude Code's USER-scope MCP registration should work from every cwd.
|
|
106
106
|
|
|
107
107
|
### From npm — project-local install
|
|
@@ -114,6 +114,12 @@ npx entwurf install .
|
|
|
114
114
|
npx entwurf check-bridge
|
|
115
115
|
```
|
|
116
116
|
|
|
117
|
+
For an npm upgrade, rerun the install command in the same scope (use
|
|
118
|
+
`@junghanacs/entwurf@latest` when you want the registry's stable line explicitly),
|
|
119
|
+
then make the first check from that same scope: `entwurf check-bridge` for a global
|
|
120
|
+
install or `npx entwurf check-bridge` for a project-local install. Native-harness
|
|
121
|
+
installers and process restarts remain a separate post-upgrade step below.
|
|
122
|
+
|
|
117
123
|
For manual MCP registration from a project-local install, point the host at:
|
|
118
124
|
|
|
119
125
|
```text
|
|
@@ -139,12 +145,16 @@ pnpm install
|
|
|
139
145
|
|
|
140
146
|
A development clone runs the bridge source through Node's strip-types path;
|
|
141
147
|
an npm-installed package runs the prebuilt JS under `mcp/entwurf-bridge/dist/`
|
|
142
|
-
because Node refuses to strip `.ts` files under `node_modules`.
|
|
148
|
+
because Node refuses to strip `.ts` files under `node_modules`. The dev launcher's
|
|
149
|
+
source path means `./run.sh check-bridge` needs no build. After `git pull`, however,
|
|
150
|
+
run `pnpm install` when the lockfile changed and run `pnpm run build-bridge` before
|
|
151
|
+
artifact-consuming checks such as `./run.sh check-bridge-delivery`: `dist/` is
|
|
152
|
+
gitignored and may be absent or stale immediately after a checkout or pull.
|
|
143
153
|
|
|
144
154
|
### Pi adapter / ACP plugin lane
|
|
145
155
|
|
|
146
156
|
To use the `entwurf` provider inside pi, install a compatible pi binary
|
|
147
|
-
separately (`@earendil-works/pi-coding-agent >=0.
|
|
157
|
+
separately (`@earendil-works/pi-coding-agent >=0.84.1 <0.85`). Then point pi at
|
|
148
158
|
the npm-installed package or development clone:
|
|
149
159
|
|
|
150
160
|
```bash
|
|
@@ -159,8 +169,8 @@ For daily operator sessions, launch pi with `--entwurf-control` — no id
|
|
|
159
169
|
injection; the meta-record mints the garden address (see [Garden launcher](#garden-launcher)). Older pi
|
|
160
170
|
versions may silently miss the provider/extension surface, so treat the pi floor
|
|
161
171
|
as release-critical for the ACP/plugin lane. A host that only uses
|
|
162
|
-
`entwurf-bridge` from Claude Code / Codex / Antigravity does not need pi
|
|
163
|
-
|
|
172
|
+
`entwurf-bridge` from Claude Code / Codex / Antigravity does not need pi at all for
|
|
173
|
+
delivery: no `entwurf_v2` rail launches a pi process.
|
|
164
174
|
|
|
165
175
|
### Native harness install and doctors
|
|
166
176
|
|
|
@@ -218,8 +228,8 @@ host evidence boundaries are [VERIFY.md](./VERIFY.md) and [BASELINE.md](./BASELI
|
|
|
218
228
|
|
|
219
229
|
The curated model registry exposes unprefixed Claude ids plus `cortex-` rows.
|
|
220
230
|
Codex is not an ACP backend or a shipped managed citizen lane: it has verified
|
|
221
|
-
native-delivery probe evidence
|
|
222
|
-
|
|
231
|
+
native-delivery probe evidence only. No managed Codex support is claimed; lifecycle,
|
|
232
|
+
identity, installation, and doctors remain prerequisites for any such lane.
|
|
223
233
|
|
|
224
234
|
**Snowflake Cortex Code is the second ACP backend** (contract and audit:
|
|
225
235
|
[docs/acp-backend-rail.md](./docs/acp-backend-rail.md#cortex-code-audit-d1d10)). Curated ids are
|
|
@@ -233,7 +243,7 @@ HOME containment. Explicit MCP servers are projected into the overlay-private
|
|
|
233
243
|
`cortex/mcp.json`; only the bridge receives the real operator HOME needed for the
|
|
234
244
|
garden store.
|
|
235
245
|
|
|
236
|
-
`check-acp-cortex` runs in `pnpm check`. Real acceptance is deliberately on demand:
|
|
246
|
+
`check-acp-cortex` runs in `pnpm run check:full`. Real acceptance is deliberately on demand:
|
|
237
247
|
|
|
238
248
|
```bash
|
|
239
249
|
LIVE=1 ENTWURF_ACP_CORTEX_CONNECTION=<conn> entwurf smoke-acp-cortex-live
|
|
@@ -320,7 +330,7 @@ For the maintained multi-harness setup and skill/command packaging details, see
|
|
|
320
330
|
|
|
321
331
|
The Claude ACP backend keeps its native model / API / tools; entwurf shapes only what enters from pi. Claude honors an explicit `CLAUDE_CONFIG_DIR` export when set by the operator.
|
|
322
332
|
|
|
323
|
-
**Claude** uses `_meta.systemPrompt` for the engraving carrier (kept short and pure — billing-safe; rich operator context rides the first user message instead, see [Context carriers](#context-carriers)) and `CLAUDE_CONFIG_DIR` for a whitelist overlay so auth/runtime entries stay available while operator memory, hooks, agents, history, local settings, and project memory remain hidden. The overlay writes an explicit empty `hooks: {}` because Claude SDK organic compaction needs the configured-empty shape; no operator hook definitions are inherited. The four-tool baseline
|
|
333
|
+
**Claude** uses `_meta.systemPrompt` for the engraving carrier (kept short and pure — billing-safe; rich operator context rides the first user message instead, see [Context carriers](#context-carriers)) and `CLAUDE_CONFIG_DIR` for a whitelist overlay so auth/runtime entries stay available while operator memory, hooks, agents, history, local settings, and project memory remain hidden. The overlay writes an explicit empty `hooks: {}` because Claude SDK organic compaction needs the configured-empty shape; no operator hook definitions are inherited. It also pins `permissions.defaultMode: "bypassPermissions"` so an unattended ACP turn cannot suspend on an interactive permission prompt; explicit `tools` / `disallowedTools` still constrain the callable surface and backend authentication remains the operator's. The four-tool baseline is `Read`, `Bash`, `Edit`, and `Write`; `permissionAllow` carries their allow declarations, and `Skill` is added automatically when `skillPlugins` is non-empty. Operator context cap override: `ENTWURF_ACP_CLAUDE_CONTEXT=<int>`.
|
|
324
334
|
|
|
325
335
|
Codex is not an ACP backend here. Its native delivery probe remains separate from
|
|
326
336
|
the governed ACP adapter rail and does not yet constitute a managed garden citizen.
|
|
@@ -332,7 +342,8 @@ entwurf owns **no** memory layer at all — the ACP plugin's boundary explicitly
|
|
|
332
342
|
## Smoke commands
|
|
333
343
|
|
|
334
344
|
```bash
|
|
335
|
-
pnpm check #
|
|
345
|
+
pnpm check # everyday core (prints wall time; <=60s on the reference host)
|
|
346
|
+
pnpm run check:full # full deterministic floor (adds the hermetic + package/install tiers)
|
|
336
347
|
./run.sh check-bridge # entwurf-bridge direct MCP smoke (no backend auth)
|
|
337
348
|
./run.sh smoke-agy-install-state # agy MCP + exact permission ownership lifecycle (install/uninstall/doctor/inverse)
|
|
338
349
|
./run.sh smoke-agy-statusline-state # agy ambient garden-id install surface
|
|
@@ -359,8 +370,9 @@ LIVE=1 ./run.sh release-gate /tmp/scratch --cut # the single cut gate (MUST + BE
|
|
|
359
370
|
LIVE=1 ENTWURF_ACP_CORTEX_CONNECTION=<conn> ./run.sh smoke-acp-cortex-live # Cortex is on-demand: the aggregate does not re-certify it
|
|
360
371
|
```
|
|
361
372
|
|
|
362
|
-
`pnpm check`
|
|
363
|
-
|
|
373
|
+
`pnpm run check:full` includes the AGY permission contract matrix; the committed-mutant
|
|
374
|
+
gate qualification is scheduled separately (`./run.sh check-gate-qualification` — the CI
|
|
375
|
+
`check` job runs it on every push, and release-gate carries it as a MUST step). A gate a
|
|
364
376
|
release touches must kill its known defect for the claimed `[QK:<claim>]` reason —
|
|
365
377
|
the descriptions above name what each smoke covers, and no check count is quality
|
|
366
378
|
evidence on its own. Gate qualification needs the git work surface, while the matrix
|
|
@@ -402,9 +414,9 @@ For a real consumer arranging many skills, see [agent-config](https://github.com
|
|
|
402
414
|
|
|
403
415
|
**Entwurf is one dispatch capability with native-pi and MCP surfaces.** Native pi exposes it directly as extension tools; ACP-backed and external native-harness sessions reach it through `entwurf-bridge`. The purpose is not to invent a different sub-agent system, but to preserve the same sibling-based model across harnesses.
|
|
404
416
|
|
|
405
|
-
A sibling has its own runtime boundary and its own provider/model identity — not a worker, delegate, or sub-agent.
|
|
417
|
+
A sibling has its own runtime boundary and its own provider/model identity — not a worker, delegate, or sub-agent. Today every transport targets an *existing* garden citizen, and none of them starts a process. `entwurf_v2` routes from rail-specific liveness: live pi fire-and-forget → control socket; dormant pi → an honest reject; active self-fetch → meta-mailbox; probe-alive agy → native-push. A **control-socket-domain** dispatch takes the per-target lock, which now serializes concurrent live sends at one garden id; mailbox and native-push use their own deliverability evidence and remain lock-free.
|
|
406
418
|
|
|
407
|
-
A two-pane recording covers the surface end-to-end — sibling resume, cross-process MCP dispatch across a different cwd, and a live peer greeting
|
|
419
|
+
A two-pane recording covers the pre-0.12 v1 surface end-to-end — sibling resume, cross-process MCP dispatch across a different cwd, and a live peer greeting. It is **archived evidence**: it shows a resume verb this repo no longer has (see `demo/README.md`).
|
|
408
420
|
|
|
409
421
|
<details>
|
|
410
422
|
<summary>Watch (2131×1142 GIF, click to expand)</summary>
|
|
@@ -415,29 +427,26 @@ A two-pane recording covers the surface end-to-end — sibling resume, cross-pro
|
|
|
415
427
|
|
|
416
428
|
Live peer messaging carries a sender envelope `{ sessionId, agentId, cwd, timestamp, origin?, replyable? }`; `entwurf_self` returns that authoritative envelope for the current pi session or trusted meta-session. Plain external MCP hosts are non-replyable. A garden-native meta-session carries a trusted `meta-session` envelope, but **`replyable` is a fact its own rail decides, not a consequence of being trusted** — a self-fetch citizen needs a live armed receiver, a native-push citizen needs an alive adapter probe, and a pi session needs its control socket. `entwurf_self` also reports which rail a meta-session reply would ride, because a native-push citizen has no mailbox to name. `wants_reply` is an etiquette marker rendered as a `(wants reply)` badge — not a transport contract, no wait, no polling. **v2 never gates on it:** a `wants_reply` from an external/non-replyable caller is passed through and surfaced honestly beside that sender's `replyable: false`, not rejected — the decider routes on target + intent, never on sender replyability. (The retired v1 `entwurf_send` did reject it; that behaviour went with the verb.)
|
|
417
429
|
|
|
418
|
-
In ACP-backed and external native-harness sessions, `entwurf-bridge` exposes
|
|
430
|
+
In ACP-backed and external native-harness sessions, `entwurf-bridge` exposes seven tools: `entwurf_v2`, `entwurf_peers`, `entwurf_fresh_call`, `entwurf_resume_call`, `entwurf_self`, `entwurf_inbox_read`, and the explicit/manual `entwurf_register_native` fallback. Native pi exposes the shared capability directly through the extension surface (`entwurf_v2`, `entwurf_peers`, `entwurf_fresh_call`, `entwurf_resume_call` tools; the socket-scan `/entwurf-sessions` command is gone — #50 C4). **For garden-id delivery/reply use `entwurf_v2`** — the canonical surface that classifies the target and routes to live-pi / Claude-Code-meta-mailbox / Antigravity-native-push, and refuses a dormant target instead of waking it. **To open a sibling that does not exist yet use `entwurf_fresh_call`** — it launches one fixed backend (`pi` or `claude-code`) as a visible window in the operator's own tmux session, requires an explicit model, accepts one optional literal absolute `cwd` (omit it or pass `""` to use the caller's cwd), passes the model and selected directory through the runtime's visible launch path, and hands it a first task; the sibling's first action is a nonce callback whose sender envelope carries its garden id. The launch receipt records the requested model/cwd plus tmux coordinates and never claims that the runtime accepted them or completed delivery. (The v1 verbs `entwurf` / `entwurf_resume` / `entwurf_send` are gone.) Garden-native operator commands require `--entwurf-control`. There is no spawn target allowlist — the target registry is gone (#50 C3): `entwurf_v2` and `entwurf_resume_call` address an existing record-backed citizen, while `entwurf_fresh_call` takes its explicit backend/model/task and optional cwd directly rather than resolving a model tuple from a registry file. **To reopen a DORMANT pi citizen use `entwurf_resume_call {target}`** — the record supplies transcript, model, provider and cwd, so it takes no prompt, no task and no model override; it runs no turn, returns a LAUNCH receipt and a separate OBSERVATION receipt (only the second says the citizen is back), refuses a non-pi target as `target-not-pi`, and on an unobserved socket leaves the visible window open and releases its lock rather than retrying.
|
|
419
431
|
|
|
420
432
|
### `entwurf_v2` — canonical dispatch verb
|
|
421
433
|
|
|
422
|
-
`entwurf_v2` / `runEntwurfV2` is the canonical v2 dispatch verb over **existing** garden targets — record-backed citizens only (#50 C4: the record is the sole address authority; a record-less control socket rejects pre-probe as `record-less-socket`, a diagnostic state, never a delivery target). You give a target garden id plus an intent (`fire-and-forget`
|
|
434
|
+
`entwurf_v2` / `runEntwurfV2` is the canonical v2 dispatch verb over **existing** garden targets — record-backed citizens only (#50 C4: the record is the sole address authority; a record-less control socket rejects pre-probe as `record-less-socket`, a diagnostic state, never a delivery target). You give a target garden id plus an intent (`fire-and-forget` — the axis is single-valued since the visible-first cut); one decider reads the target's liveness as a fact and picks the transport from a frozen table keyed on **both** the target's state **and** the intent — never on state alone — then reports one outcome under the v2 lock policy. A **control-socket-domain** dispatch takes a per-target lock; mailbox and native-push are lock-free, with deliverability guarded by their own receiver/probe evidence:
|
|
423
435
|
|
|
424
436
|
| target state | intent | transport |
|
|
425
437
|
|---|---|---|
|
|
426
438
|
| live pi | fire-and-forget | control-socket send |
|
|
427
|
-
|
|
|
428
|
-
|
|
|
429
|
-
| dormant pi | fire-and-forget | **reject** (`dormant-fire-forget-unsupported`) |
|
|
439
|
+
| dormant pi | fire-and-forget | **reject** (`dormant-fire-forget-unsupported` — nothing is launched) |
|
|
440
|
+
| any pi | indeterminate probe | **reject** (`indeterminate-no-spawn` — an unestablished probe is not a measured death) |
|
|
430
441
|
| active self-fetch receiver | fire-and-forget | meta-mailbox enqueue + doorbell |
|
|
431
442
|
| inactive / terminated self-fetch receiver | fire-and-forget | **reject** (`mailbox-undeliverable` — no `.msg`, no doorbell) |
|
|
432
|
-
| self-fetch | owned-outcome | **reject** (no owned result over a mailbox) |
|
|
433
443
|
| live native-push conversation | fire-and-forget | native-push direct injection |
|
|
434
444
|
| dead / indeterminate native-push conversation | fire-and-forget | **reject** (`native-push-target-dead` / `native-push-probe-indeterminate`) |
|
|
435
|
-
| native-push | owned-outcome | **reject** (`native-push-no-resume-authority`) |
|
|
436
445
|
| record-less control socket (no meta-record) | any | **reject** (`record-less-socket` — pre-probe; diagnostic state, #50 C4) |
|
|
437
446
|
|
|
438
447
|
**`entwurf_v2` is the canonical surface for garden-id delivery.** When you have a garden id and want to reach whoever it names — message, reply, or hand-off — `entwurf_v2` is the one surface that reads whether the target is live pi, dormant pi, mailbox-backed Claude Code, or native-push Antigravity and routes correctly; *when unsure which transport, use `entwurf_v2`*. This prevents callers from guessing a rail from the shape of an id.
|
|
439
448
|
|
|
440
|
-
What v2 provides is a **deterministic dispatch substrate** that moves the "which transport?" decision out of the fallible caller/model and into the decider, with transport-appropriate locking and an honest reject (no `✓ delivered`, no `.msg` garbage) when a target cannot receive.
|
|
449
|
+
What v2 provides is a **deterministic dispatch substrate** that moves the "which transport?" decision out of the fallible caller/model and into the decider, with transport-appropriate locking and an honest reject (no `✓ delivered`, no `.msg` garbage) when a target cannot receive. It still does **not** mint siblings, and it does not relaunch one either: every row above either reaches a citizen that is already running or refuses. Reopening a dormant pi citizen is `entwurf_resume_call`, a separate lifecycle verb that never routes through this decider. Fresh creation is the separate `entwurf_fresh_call` verb. It opens one fixed Pi or Claude Code runtime visibly in the caller's tmux session with a required explicit model passed in that runtime's measured CLI dialect and one optional literal absolute `cwd`; omitted or `""` means the caller's cwd. It returns only a synchronous launch receipt and lets the sibling report its new address asynchronously through the sender envelope of a nonce callback. Use this cwd input for a new cross-repository sibling; do not resume a dormant citizen as a cwd substitute. The meta-mailbox row requires an **active** self-fetch receiver; native-push requires a record-backed, probe-alive native conversation and never borrows mailbox state. The [mux launch lane](./docs/mux-launch-rail.md) owns placement, fixed-runtime launch, and the two narrow compositions above it (fresh-call and resume-call placement); delivery does not import launch, and mux is not a delivery transport.
|
|
441
450
|
|
|
442
451
|
A live pi target is *reached* over its control socket, but the socket is dispatch-internal transport, never identity (#50 C4). A control socket that no meta-record claims — a pre-record-era resident, an unreadable store, or a stale/planted file — is refused for **every** intent as `record-less-socket`, and the reject names the fix (restart the resident so `session_start` births its record, or quiesce and run the fresh-cut). `entwurf_peers` reports the same state as an aggregated `record-less-socket` diagnostic rather than a peer row.
|
|
443
452
|
|
|
@@ -451,7 +460,7 @@ A `--entwurf-control` session needs **no special launcher** (#50 C2): pi mints i
|
|
|
451
460
|
pi --entwurf-control
|
|
452
461
|
```
|
|
453
462
|
|
|
454
|
-
**Resuming an existing garden session.**
|
|
463
|
+
**Resuming an existing garden session.** Use `entwurf_resume_call {target}`. It reopens a DORMANT pi citizen under the SAME garden id in a visible window in the caller's own tmux session, resolving the transcript, model, provider and cwd from the record — so it takes only the target id, and it runs no turn: the window comes back with the conversation and waits, and talking to it is still `entwurf_v2`. Two receipts arrive and mean different things: a LAUNCH receipt (tmux made a window and was asked to start pi) and an OBSERVATION receipt (the control socket answered under the same id, or `resume-unobserved`). Unobserved is a real outcome, not an error to retry — the window is visible, so read it. A citizen that is already live is refused; so is a non-pi target (`target-not-pi`), because only pi stands a control socket up. The predecessor, `entwurf_v2 intent=owned-outcome`, resumed by launching a hidden window-less background child and was withdrawn under the visible-first rule; delivery still starts no process. Identity preconditions live in `resume-launch-identity.ts`, gated by `check-resume-launch-identity`.
|
|
455
464
|
|
|
456
465
|
**Starting a new session in-process — pi's own `/new`.** Since the #50 C2 cut there is nothing to replace it with: `/new`, `/fork`, `/clone` and RPC session replacement are pi's again. The replacement session fires `session_start`, which upserts its own meta-record and rebinds the control socket to that record's garden id; the old socket is dropped. pi's session id (a uuidv7) is recorded as the citizen's `nativeSessionId` and is never an address. Gate: `run.sh smoke-resident-garden-guard` REPLACEMENT section (0-token RPC E2E).
|
|
457
466
|
|
|
@@ -475,7 +484,7 @@ The footer uses ACP `usage_update.used / size` (backend prompt/tools/cache/sessi
|
|
|
475
484
|
|
|
476
485
|
Owns: provider registration (`entwurf/...`), ACP subprocess lifecycle + `resume > load > new`, prompt forwarding + ACP event mapping, the bridge surface that exposes pi capabilities such as entwurf to ACP-backed sessions, pi-facing MCP injection via `entwurfProvider.mcpServers`, and bridge-local cleanup and diagnostics.
|
|
477
486
|
|
|
478
|
-
Does not: reconstruct full history, hydrate backend transcripts into pi history, emulate Claude Code or Codex, run broad multi-agent orchestration (entwurf is narrow,
|
|
487
|
+
Does not: reconstruct full history, hydrate backend transcripts into pi history, emulate Claude Code or Codex, run broad multi-agent orchestration (entwurf is narrow, record-addressed, identity-locked), or run a second session model competing with pi.
|
|
479
488
|
|
|
480
489
|
Only `pi:<sessionId>` mappings are persisted (`~/.pi/agent/cache/entwurf/sessions/`) — enough to re-attach pi to the same remote ACP session, never enough to act as a second harness. Backend stores (`~/.claude/`, `~/.codex/`) are interoperability side effects, not authority.
|
|
481
490
|
|
package/VERIFY.md
CHANGED
|
@@ -5,7 +5,7 @@ invariants live in gates; this file defines evidence strength, release acceptanc
|
|
|
5
5
|
and the manual judgements a gate cannot make.
|
|
6
6
|
|
|
7
7
|
> **Current surface.** `entwurf-bridge` exposes `entwurf_v2`, `entwurf_peers`,
|
|
8
|
-
> `entwurf_self`, `entwurf_inbox_read`, and `entwurf_register_native`. The ACP
|
|
8
|
+
> `entwurf_fresh_call`, `entwurf_resume_call`, `entwurf_self`, `entwurf_inbox_read`, and `entwurf_register_native`. The ACP
|
|
9
9
|
> backends are Claude and Snowflake Cortex Code. Antigravity is a separate shipped
|
|
10
10
|
> native-push citizen lane; Codex has delivery-probe evidence but no managed citizen
|
|
11
11
|
> lane. Retired v1 verbs and bridge implementations belong only in CHANGELOG/git.
|
|
@@ -40,19 +40,27 @@ Verification here is not a benchmark. In production we exchange short turns and
|
|
|
40
40
|
|
|
41
41
|
### The canonical floor — two entry points
|
|
42
42
|
|
|
43
|
-
- **Deterministic floor:** `pnpm check` — the
|
|
44
|
-
- **Discriminating power of that floor:** `./run.sh check-gate-qualification` (
|
|
45
|
-
- **Live floor:** `LIVE=1 ./run.sh release-gate <scratch-project-dir> --cut` — `pnpm check` + the v2-native live gates + the ACP plugin acceptance floor. It reports a **two-tier summary**:
|
|
46
|
-
- **MUST tier** (release-blocking — owns the exit code; "green" applies only here): `pnpm check`, `
|
|
43
|
+
- **Deterministic floor — two tiers (#70):** `pnpm check` is the everyday CORE — toolchain (lint + typecheck), the vitest lanes, and the pure-unit / behavioral-contract / source-topology gates plus the cheap static coherence checks. It prints its own total wall time; acceptance is ≤60s on the reference host `oracle` (an operator measurement, never a hard wall-clock gate on arbitrary hosts). `pnpm run check:full` is the FULL deterministic floor — the core plus the hermetic-integration and package/install tiers — and is what the frozen-candidate protocol, push CI, release-gate, and `prepublishOnly` run. Exact membership is the named `check:*` group scripts in `package.json` (the executable SSOT — this document records meaning and principles, not the command list); a gate changes tier by semantic-class decision, never by getting faster or slower. Both tiers exclude the separately scheduled `check-gate-qualification`.
|
|
44
|
+
- **Discriminating power of that floor:** `./run.sh check-gate-qualification` (scheduled, not ambient: standalone when a lane changes a gate/mutant/matrix, in the CI `check` job on every push, and as a release-gate MUST step — no longer inside the default check chains) re-plants committed defect mutants (`scripts/mutants/*.json`, one per closed defect class) in an isolated snapshot repo and requires each to turn its gate red **bounded and at its claimed `[QK:<claim>]` signature** — a wrong-reason red fails, a baseline-red control voids the whole group, and the runner is negative-controlled on every run (zero-match/multi-match/survived/wrong-reason/hang/control-red/impurity). This measures whether the deterministic gates still *block* what they claim to block; it is **not a new evidence level** (L0–L5 are untouched) and never substitutes for LIVE evidence. Per-cut records cite claim IDs + killed mutant IDs — "N checks passed" alone is not evidence. `check-agy-permission-matrix` complements it with the enumerated permission contract space (literal cells + stated exclusion rules, oracle independent of the SUT).
|
|
45
|
+
- **Live floor:** `LIVE=1 ./run.sh release-gate <scratch-project-dir> --cut` — `pnpm run check:full` + the v2-native live gates + the ACP plugin acceptance floor. It reports a **two-tier summary**:
|
|
46
|
+
- **MUST tier** (release-blocking — owns the exit code; "green" applies only here): `pnpm run check:full`, `check-gate-qualification`, `smoke-entwurf-v2-matrix-live`, `check-bridge`, the resident-garden-guard zero-token half (record birth / record-keyed socket / attach-on-reopen), the `smoke-acp-*-live` ACP plugin smokes (socket-citizen / raw-turn / overlay / provider / session-reuse / carrier-augment / memory-containment / rgg / mcp / skill / bundled-mcp / v2-send), the axis wired in on 2026-07-31 that the aggregate had simply never listed (`smoke-claude-native-resume-live`), and `smoke-entwurf-chain-live` — the cross-harness delivery chain (native Claude Code → pi GPT → pi ACP Sonnet → mailbox terminus) proving sender identity and replyability at every hop plus a real read receipt at the end. (`smoke-session-id-name` is gone — #50 C3: its `--session-id`/`--name` substrate has no entwurf consumer anymore.)
|
|
47
47
|
- **BEHAVIOR tier** (advisory, non-blocking): the resident-garden-guard positive (a model-in-loop `entwurf_self` turn). A BEHAVIOR FAIL is surfaced with its artifact path but **never blocks the cut**. The lane holds what the model *chooses*, never what our wiring fails to deliver — a gate that TELLS the model which tool to call stays MUST, because its failure is ours — measured 2026-07-24, when the tool turned out to be absent from the session schema in both observed failures (the bundled-MCP readiness gap recorded in `scripts/smoke-acp-v2-send-live.ts`).
|
|
48
|
-
- **Every MUST step is invoked and reports its own outcome
|
|
48
|
+
- **Every MUST step is invoked and reports its own outcome.** Prerequisite-bearing LIVE MUST steps ride the P1 STEP OUTCOME protocol (`scripts/lib/step-outcome.sh`): exit 0 = PASS, exit 97 = SKIP (a prerequisite the step does not have, printed as an `[entwurf:skip]` line), anything else = FAIL. The two non-skippable static steps (`pnpm run check:full`, `check-gate-qualification`) are inline: 0 = PASS, nonzero = FAIL, no SKIP arm — they have no prerequisite to decline. A skip is never counted as a pass — that hole is what let a cortex-less host read as cortex acceptance. Without `--cut` this is the unattended diagnostic: SKIPs are reported and the run still exits 0. **`--cut` makes it acceptance and any MUST SKIP is red**, which is how "a real cut needs `LIVE=1` with `SKIP=0`" stopped being prose. A green MUST gate is **necessary, not sufficient** — GLG authorizes the cut.
|
|
49
49
|
- **When cost-bearing MUST gates run (fixed 2026-07-23, the F6/F7 lesson):** a commit that touches a rail a MUST-tier live gate covers runs that gate **before cross-review is requested** — never parked behind "run it at approval time". Deferring a wired gate to a human decision is what let F6/F7 ship reviewed-and-approved; the wiring exists so the verdict never depends on who pressed enter. "배선이 없어 못 한 것은 OK, 배선이 있는데 안 돌린 것은 우리가 남긴 구멍이다." Model-in-loop cost is spent via the subscription-backed `entwurf` provider where the gate allows it, a free-tier native model otherwise; cost is a reason to pick the cheap target, not to skip the gate.
|
|
50
50
|
|
|
51
|
-
> **Cortex is an on-demand axis, not an aggregate one.** Its rail needs an external Snowflake connection and login that the host owns, not the repo — so wiring it into the aggregate would block every cut taken on a host without that account. **The
|
|
51
|
+
> **Cortex is an on-demand axis, not an aggregate one.** Its rail needs an external Snowflake connection and login that the host owns, not the repo — so wiring it into the aggregate would block every cut taken on a host without that account. **The release aggregate does not re-certify Cortex**; `LIVE=1 ENTWURF_ACP_CORTEX_CONNECTION=<conn> ./run.sh smoke-acp-cortex-live` stays a required direct call whenever a cut changes Cortex rail code or an operator elects to certify that host. Its honest-skip behaviour is unchanged: run it without the connection and it reports protocol SKIP, never a pass.
|
|
52
52
|
>
|
|
53
53
|
> A cut that touches the prompt-lifecycle contract (no wall clock on a running turn) owes one long-turn acceptance the aggregate floor is too short to carry: `LIVE=1 ./run.sh smoke-acp-long-turn-live` drives a real turn whose tool work outlasts the retired 600s cutoff and requires exactly one cold ACP bootstrap in the transcript. It takes >12 minutes by construction and is on-demand, not part of `release-gate`.
|
|
54
54
|
>
|
|
55
|
-
> The
|
|
55
|
+
> **The integrated mux lifecycle IS a release-gate MUST.** `LIVE=1 ./run.sh smoke-mux-lifecycle-live` enters through a real MCP `tools/call` on the shipped bridge launcher and follows one citizen the whole way: fresh-call launch receipt, the sibling's own nonce callback whose SENDER ENVELOPE is the address, an `entwurf_v2` control-socket send that lands in the sibling's own transcript, `entwurf_resume_call` REFUSED while that citizen is live, a stable-handle close proving pane and socket gone with the record preserved, delivery to the dormant citizen refused honestly, then the public `entwurf_resume_call` — whose LAUNCH and OBSERVATION receipts stay apart — and finally an `entwurf_v2` send the resumed session answers with a fact it was told BEFORE the window closed. That last step is the point: a socket answering under the same garden id proves a process stood up at that address, and only the recall proves the same conversation came back. Both pi provider shapes are driven to it (native `openai-codex/gpt-5.6-terra` and recorded-ACP `entwurf/claude-sonnet-5`, the only shape that re-injects a bridge extension), and the Claude Code cell ends where its capability ends: its resume is refused as `target-not-pi` with no window opened and no lock residue (the per-gid coordination lock is released).
|
|
56
|
+
>
|
|
57
|
+
> One cell cannot be fully fenced, and that is recorded rather than glossed: the recorded-ACP pi cell runs under the operator's REAL home, because its provider spawns `claude` as a child that authenticates from there — measured, a fenced HOME kills that turn with `Authentication required` before the model is ever reached, and `CLAUDE_CONFIG_DIR` alone does not fix it. That is the same trade `smoke-acp-bundled-mcp-live` already makes. While that cell runs, its citizen's control socket and per-gid lock exist under the operator's own `~/.pi/entwurf-control` and `~/.pi/entwurf-v2-locks`; its meta store stays fixture, so no garden record is minted outside the fixture, and the run ends by proving all six real roots hold the entry sets they started with, with no fixture garden id and no leftover lock.
|
|
58
|
+
>
|
|
59
|
+
> Be honest about its cost, because it is a MUST: it spends real model turns on the operator's configured runtimes (two pi siblings, each resumed once, plus one Claude Code sibling), it READS the operator's real runtime config, and the siblings' native session transcripts stay in the real pi agent dir — they are not cleaned up, and they are part of the evidence a resume was real. The fence is per-axis rather than absolute: the four meta roots (records, mailbox, receivers, senders) are fixture for every cell, so no garden record is ever minted outside it; the native pi cell's control socket and v2 lock are fixture too; the ACP pi cell's are REAL and transient (see the paragraph above); and the Claude cell runs its runtime under the real HOME while its mailbox and meta stay fixture. The run ends by proving the operator's SIX real roots — the four meta roots plus `~/.pi/entwurf-control` and `~/.pi/entwurf-v2-locks` — hold the entry sets they started with, with no fixture garden id anywhere, and that proof now runs on the failure path as well as the green one. Missing prerequisites decline with the protocol SKIP (97), which `release-gate --cut` refuses rather than rounding up.
|
|
60
|
+
>
|
|
61
|
+
> **Fresh-call LIVE is on-demand, not part of `release-gate`.** `LIVE=1 ./run.sh smoke-mux-fresh-call-live` opens configured Pi and Claude Code siblings, spends two model turns, and preserves their native transcripts; run it directly whenever a cut changes mux fresh-call/launch behavior. Its private tmux servers and fixture-bound entwurf write axes make it deterministic about garden-record/socket residue, but those real native turns should not appear unexpectedly in every aggregate cut.
|
|
62
|
+
>
|
|
63
|
+
> The aggregate release gate does not own a live agy conversation id, so agy's real native-push round trip is a separate acceptance axis: three fail-loud doctors plus `LIVE=1 AGY_CONVERSATION_ID=<id> ./run.sh smoke-agy-native-push-live`, followed by a fresh-conversation sender/reply check after package install. Its deterministic install/sender gates are already inside `pnpm run check:full`; do not misreport the aggregate gate as live agy evidence.
|
|
56
64
|
>
|
|
57
65
|
> Authoritative per-cut counts and digests live in BASELINE/CHANGELOG, not inline
|
|
58
66
|
> here; embedding them in the protocol makes a correct guide stale after every cut.
|
|
@@ -63,7 +71,7 @@ Do not collapse source, package, fixture, and native-host evidence into one “g
|
|
|
63
71
|
|
|
64
72
|
| Axis | Required proof | Limit |
|
|
65
73
|
|---|---|---|
|
|
66
|
-
| Source | `pnpm check` | Does not prove an installed consumer. |
|
|
74
|
+
| Source | `pnpm run check:full` + `./run.sh check-gate-qualification` | Does not prove an installed consumer. |
|
|
67
75
|
| Packed install | `check-pack-install` | Real tarball, but checkout-visible. |
|
|
68
76
|
| Linux artifact consumer | required `check-install-container` CI job against one preserved candidate | Fixtures prove package/oracle shape, not a real Claude lifecycle. |
|
|
69
77
|
| Exact release commit | all required CI jobs green at the exact SHA | A different green SHA is not transferable evidence. |
|
|
@@ -78,7 +86,7 @@ consumer image outside this standing protocol.
|
|
|
78
86
|
|
|
79
87
|
### Verifying the two capabilities a gate cannot fully judge
|
|
80
88
|
|
|
81
|
-
- **Garden-id delivery:** discover a target with `entwurf_peers`, then `entwurf_v2
|
|
89
|
+
- **Garden-id delivery:** discover a target with `entwurf_peers`, then `entwurf_v2 fire-and-forget` — the intent axis is single-valued since the visible-first cut. It reaches a live pi target over its control socket, a deliverable self-fetch citizen through the mailbox, and a probe-alive native-push conversation by direct injection. A DORMANT in-domain citizen rejects as `dormant-fire-forget-unsupported` — delivery never wakes it; reopen it with the separate lifecycle verb `entwurf_resume_call {target}`, then dispatch again. A wrong target state is rejected, never auto-fixed and never launched into.
|
|
82
90
|
- **ACP continuity:** a direct `pi --provider entwurf --model claude-sonnet-5` turn, or the `smoke-acp-session-reuse-live` gate (process-scoped reuse + recall). Multi-turn reuse is proven by that gate, not by any v1 resume tool.
|
|
83
91
|
- **agy citizenship:** in a fresh agy conversation, the first `PreInvocation` must yield a garden id, `entwurf_self` must report `agentId=meta-session/antigravity` and `replyable:true` only while the native probe is alive, and a reply to that same garden id must direct-inject into the same conversation. No mailbox/receiver-marker evidence counts on this rail.
|
|
84
92
|
|
|
@@ -199,7 +207,7 @@ Pass (carrier honesty): the subject distinguishes engraving from pi-context-augm
|
|
|
199
207
|
|
|
200
208
|
- **Layer 0 — self-awareness:** ask environment self-awareness / MCP visibility / upstream-instruction awareness, guessing prohibited. Pass: recognizes native tool family, says "I don't know" honestly, answers MCP visibility only as configured, describes upstream instruction type without reproducing internal prompts. Fail: claims a nonexistent tool, conflates pi-custom and native tools, hallucinates MCP visibility, or conflates the two carriers (§1A.0).
|
|
201
209
|
- **Layer 1 — native tool use:** throw file-reading / structure-analysis / regression-hunting tasks. Pass: Read/Edit/Bash/Grep/Glob selection is natural; no detour through MCP or recursive `pi`. Fail: strange detours for simple reads; speaks from memory without reading.
|
|
202
|
-
- **Layer 2 — MCP boundary:** by default the
|
|
210
|
+
- **Layer 2 — MCP boundary:** by default the seven entwurf MCP tools are not visible (they appear only when `entwurf-bridge` is registered). Pass: says invisible tools are not visible; explains the native-vs-MCP boundary; treats `entwurf_register_native` as binding an already-running conversation, never as fresh spawn. Fail: pretends to use an unseen tool; mimics entwurf via recursive `pi`.
|
|
203
211
|
- **Layer 3 — focus across turns:** inject a fact, then accumulate turns mixing retrieval/exploration. Pass (post-0.4.1): after **8 turns** holds **3+ early facts** incl. **one verbatim string injected before turn 5**; no repeated exploration, no self-contradiction, no tool-strategy drift. Fail: forgets early reads; paraphrases instead of returning the verbatim string. Note: entwurf exposes no user-facing compaction; use the backend's `usage_update` footer as an overflow-risk signal (it follows the ACP backend's `used/size`, not pi's visible-transcript estimate).
|
|
204
212
|
- **Layer 4 — vs direct Claude Code:** requires a verifier holding **both** the `entwurf` and a direct path (human-in-loop, or both transport handles). Compare latency / native tool accuracy / detours / boundary confusion / quality around turns 10–15. Repeated tool confusion, long-turn forgetting, or boundary workarounds are a fail.
|
|
205
213
|
|
|
@@ -265,11 +273,11 @@ Pass: user/assistant turns accumulate normally; the transcript is not broken/emp
|
|
|
265
273
|
|
|
266
274
|
The minimum passing bar:
|
|
267
275
|
|
|
268
|
-
1. **Deterministic floor green:** `pnpm check` passes (
|
|
276
|
+
1. **Deterministic floor green:** `pnpm run check:full` passes (the core tier plus the hermetic-integration and package/install tiers, incl. `check-pack`), plus a `./run.sh check-gate-qualification` green on the same candidate.
|
|
269
277
|
2. **All three CI jobs green on the exact release commit:** `check`, `install-surface`, and the required Linux `artifact-consumer`; preserve the latter's tarball digest and image identity.
|
|
270
278
|
3. **Live floor MUST green:** `LIVE=1 ./run.sh release-gate <dir> --cut` exits 0 reporting `MUST PASS=N FAIL=0 SKIP=0`; with `--cut` a single SKIP is red, so the exit code itself now carries this condition. A BEHAVIOR FAIL is advisory, not blocking.
|
|
271
279
|
4. **Native-host doctor green where the Claude meta-bridge is claimed:** a new post-install Claude session exists, live evidence is present, and the installed `doctor-meta-bridge` exits 0. `NOT CERTIFIED` is a release failure for that host, not a skip.
|
|
272
|
-
5. **Honest self-recognition:** the bridged model identifies its actual harness/backend, lists `entwurf-bridge` as the single MCP server with its
|
|
280
|
+
5. **Honest self-recognition:** the bridged model identifies its actual harness/backend, lists `entwurf-bridge` as the single MCP server with its seven current tools, and presents a backend-native (not normalized) tool surface.
|
|
273
281
|
6. **Carrier separation honored:** engraving vs pi-context-augment kept distinct (§1A.0); no bridge-identity narrative attributed to the engraving carrier.
|
|
274
282
|
7. **agy shipped lane accepted:** all three agy doctors are green; automatic birth/statusline/sender identity and same-gid native-push reply are confirmed in a fresh conversation. `agentId=meta-session/antigravity` is correct; model display is not part of that contract. Same-pid concurrent conversation invocation is not claimed.
|
|
275
283
|
8. **Boundary preservation across backends/machines:** for every shipped or explicitly probed backend, regardless of install path or host, no cross-backend tool-surface contamination and no confabulation about pi internals.
|
|
@@ -285,7 +293,7 @@ Passing establishes a **release verification floor**, not an 8-hour/day operatio
|
|
|
285
293
|
|
|
286
294
|
- **`ENTWURF_CHILD_STDERR_LOG`** mirrors child stderr to a file for bootstrap-path visibility — but it must be present at **bridge-process spawn time**; `export` from a shell already bound to a running bridge does not propagate. Restart the parent session with it exported, then `grep -E '\[entwurf:(bootstrap|model-switch|cancel|shutdown)\]' "$ENTWURF_CHILD_STDERR_LOG"`.
|
|
287
295
|
- **Retired dedicated smokes, live code invariants** (manual/troubleshooting only — *not* part of the release floor):
|
|
288
|
-
- *Model-switch lock* — entwurf sessions are locked to their starting model. Gate: `check-model-lock` (in `pnpm check
|
|
296
|
+
- *Model-switch lock* — entwurf sessions are locked to their starting model. Gate: `check-model-lock` (in `pnpm check`, core tier). The dedicated live `smoke-model-switch` was retired in v2; the invariant lives in `pi-extensions/model-lock.ts` (extension guard) + `session-store.ts` `SessionModelLockedError` (the `decideBootstrap` fail-loud model lock).
|
|
289
297
|
- *Cancel / abort cleanup* — `onAbort` → `cancelActivePrompt()` (session stays reusable); the stream catch closes the bridge only on `stopReason === "error"`. Dedicated `smoke-cancel` retired; invariant in code.
|
|
290
298
|
|
|
291
299
|
### Evidence preservation when a problem occurs
|
package/demo/README.md
CHANGED
|
@@ -137,7 +137,7 @@ SCENE_DELAY=30 FINAL_PAUSE=10 bash demo.sh
|
|
|
137
137
|
|
|
138
138
|
## Prerequisites
|
|
139
139
|
|
|
140
|
-
- `pi` on PATH (current floor 0.
|
|
140
|
+
- `pi` on PATH (current floor 0.84.1)
|
|
141
141
|
- `entwurf` provider configured + auth ready for the selected sender/peer models
|
|
142
142
|
- `asciinema` installed
|
|
143
143
|
- `agg` installed (optional — only for GIF conversion)
|
package/demo/demo-baseline.sh
CHANGED
|
@@ -76,12 +76,10 @@ tmux kill-session -t "$SESSION" 2>/dev/null || true
|
|
|
76
76
|
# entwurf siblings can address it if a follow-up demo needs it.
|
|
77
77
|
COMMON_ENV="ENTWURF_DEBUG=1 PI_EMACS_AGENT_SOCKET=$EMACS_SOCKET"
|
|
78
78
|
COMMON_ARGS="--entwurf-control --emacs-agent-socket $EMACS_SOCKET"
|
|
79
|
-
new_session_id() { bash "$REPO_ROOT/run.sh" new-session-id; }
|
|
80
79
|
|
|
81
80
|
# ---------- start driver (single pane) ----------
|
|
82
|
-
DRIVER_LAUNCH_ID=$(new_session_id)
|
|
83
81
|
tmux new-session -d -s "$SESSION" -n demo -x 220 -y 50 \
|
|
84
|
-
"$COMMON_ENV pi --
|
|
82
|
+
"$COMMON_ENV pi --model $DRIVER_MODEL $COMMON_ARGS 2>>$DRIVER_LOG"
|
|
85
83
|
DRIVER_PANE=$(tmux list-panes -s -t "$SESSION" -F '#{pane_id}' | head -1)
|
|
86
84
|
|
|
87
85
|
# Give pi time to print its banner and reach the prompt.
|
package/demo/demo.sh
CHANGED
|
@@ -77,7 +77,6 @@ tmux kill-session -t "$SESSION" 2>/dev/null || true
|
|
|
77
77
|
# Plain `2>>` is POSIX sh — works under tmux's default /bin/sh.
|
|
78
78
|
COMMON_ENV="ENTWURF_DEBUG=1 PI_EMACS_AGENT_SOCKET=$EMACS_SOCKET"
|
|
79
79
|
COMMON_ARGS="--entwurf-control --emacs-agent-socket $EMACS_SOCKET"
|
|
80
|
-
new_session_id() { bash "$REPO_ROOT/run.sh" new-session-id; }
|
|
81
80
|
|
|
82
81
|
# Snapshot pre-existing control sockets so we can detect which one this demo's
|
|
83
82
|
# peer pane creates. Without this, Scene 3 could greet an unrelated live pi
|
|
@@ -107,9 +106,8 @@ wait_for_new_socket() {
|
|
|
107
106
|
# the operator's tmux `base-index` / `pane-base-index` settings.
|
|
108
107
|
|
|
109
108
|
# ---------- start peer (top pane) — equivalent to: piat / piag / piat5 ----------
|
|
110
|
-
PEER_LAUNCH_ID=$(new_session_id)
|
|
111
109
|
tmux new-session -d -s "$SESSION" -n demo -x 220 -y 50 \
|
|
112
|
-
"$COMMON_ENV pi --
|
|
110
|
+
"$COMMON_ENV pi --model $PEER_MODEL $COMMON_ARGS 2>>$PEER_LOG"
|
|
113
111
|
PEER_PANE=$(tmux list-panes -s -t "$SESSION" -F '#{pane_id}' | head -1)
|
|
114
112
|
|
|
115
113
|
PEER_ID=$(wait_for_new_socket "$PRE_SOCKETS") || {
|
|
@@ -122,9 +120,8 @@ echo "Peer sessionId: $PEER_ID pane=$PEER_PANE"
|
|
|
122
120
|
POST_PEER_SOCKETS=$(ls "$SOCK_DIR"/*.sock 2>/dev/null | sort || true)
|
|
123
121
|
|
|
124
122
|
# ---------- start sender (bottom pane, split below) — equivalent to: pias / piao ----------
|
|
125
|
-
SENDER_LAUNCH_ID=$(new_session_id)
|
|
126
123
|
SENDER_PANE=$(tmux split-window -t "$PEER_PANE" -v -P -F '#{pane_id}' \
|
|
127
|
-
"$COMMON_ENV pi --
|
|
124
|
+
"$COMMON_ENV pi --model $SENDER_MODEL $COMMON_ARGS 2>>$SENDER_LOG")
|
|
128
125
|
|
|
129
126
|
SENDER_ID=$(wait_for_new_socket "$POST_PEER_SOCKETS") || {
|
|
130
127
|
echo "ERROR: sender session never registered a control socket. Check $SENDER_LOG." >&2
|
package/docs/acp-backend-rail.md
CHANGED
|
@@ -159,8 +159,10 @@ caller-session `_meta`, and cross-machine certification.
|
|
|
159
159
|
|
|
160
160
|
A backend can return `newSession` before its declared MCP server is callable. This was
|
|
161
161
|
observed intermittently on the Claude rail and directly on Cortex's private `mcp.json`
|
|
162
|
-
path. Neither `claude-agent-acp` 0.
|
|
162
|
+
path. Neither `claude-agent-acp` 0.66.0 nor the Cortex landing adds a client-side
|
|
163
163
|
readiness fence, and `mcpServerStatus()` is not called by the common loop.
|
|
164
|
+
(Re-measured at the 0.65.0 → 0.66.0 bump: the goal extension is not a fence,
|
|
165
|
+
and `mcpServerStatus` appears nowhere in the 0.66.0 adapter source.)
|
|
164
166
|
|
|
165
167
|
### 11-7-a/b. Instrument and first measurement
|
|
166
168
|
|
|
@@ -183,7 +185,10 @@ exit/signal behavior, bounds NDJSON framing, scrubs only the exact probe env all
|
|
|
183
185
|
and timestamps snapshot/prompt hand-offs inside the downstream write callback. One
|
|
184
186
|
post-wire init snapshot may support the controlled-absence row; malformed, duplicate,
|
|
185
187
|
pre-wire, unarmed, or target-mismatched snapshots invalidate the run rather than proving
|
|
186
|
-
absence.
|
|
188
|
+
absence. `check-probe-cli-shim` is the detailed producer oracle: its 20 direct
|
|
189
|
+
`[CHECK:*]` assertions remain, while their verification-infra replants were deliberately
|
|
190
|
+
removed by #70. `probe-ordering.json` retains only the product-subject no-production-prompt-cutoff
|
|
191
|
+
replant consumed by `check-probe-ordering`.
|
|
187
192
|
|
|
188
193
|
Current probe contract and gates:
|
|
189
194
|
|
|
@@ -200,7 +205,7 @@ fail when the callable surface is absent. Do not add sleeps or infer readiness f
|
|
|
200
205
|
Deterministic floor:
|
|
201
206
|
|
|
202
207
|
```bash
|
|
203
|
-
pnpm check
|
|
208
|
+
pnpm run check:full
|
|
204
209
|
./run.sh check-acp-provider-surface
|
|
205
210
|
./run.sh check-acp-sdk-surface
|
|
206
211
|
./run.sh check-acp-session-reuse
|
|
@@ -227,5 +232,5 @@ not this standing contract.
|
|
|
227
232
|
|
|
228
233
|
- causal MCP-readiness diagnosis and, only with proof, a backend-invariant fence;
|
|
229
234
|
- broader installed-host and cross-machine Cortex evidence;
|
|
230
|
-
- Codex managed native-citizen
|
|
235
|
+
- any future Codex managed native-citizen lane—separate from ACP; 0.14.0 does not ship one;
|
|
231
236
|
- persisted ACP resume/load, which is not implemented by today's in-memory reuse.
|
|
@@ -9,16 +9,15 @@ the one-line registration; everything an operator needs to actually wire a host
|
|
|
9
9
|
- **plain external MCP host**: no garden meta-record / sender marker. It can call the read surfaces (`entwurf_peers`, `entwurf_inbox_read`), but `entwurf_v2` sends are **refused by default** (#50 C4: "if we don't know who sent it, we don't send it"). The operator may wire the explicit hatch below; the send then goes out external/non-replyable.
|
|
10
10
|
- **garden-native native session**: a trusted lifecycle hook minted a garden id and sender marker — `SessionStart` for Claude Code, `PreInvocation` for agy. It is not a pi control-socket session, but it can be replyable by garden id when its own mailbox/probe rail says so.
|
|
11
11
|
|
|
12
|
-
**Which verb an external agent should reach for:** to deliver to / reply to a garden id, use **`entwurf_v2`** — it is the canonical delivery surface and the only one that reads whether the target is live pi, dormant pi, mailbox-backed Claude Code, or native-push Antigravity and routes correctly. Discover targets with `entwurf_peers`, confirm your own identity with `entwurf_self`, drain a mailbox with `entwurf_inbox_read`, and use `entwurf_register_native` only as the explicit/manual fallback for binding an already-running agy conversation (normal agy birth is automatic through the installed hook). Fresh sibling
|
|
12
|
+
**Which verb an external agent should reach for:** to deliver to / reply to a garden id, use **`entwurf_v2`** — it is the canonical delivery surface and the only one that reads whether the target is live pi, dormant pi, mailbox-backed Claude Code, or native-push Antigravity and routes correctly. Discover targets with `entwurf_peers`, confirm your own identity with `entwurf_self`, drain a mailbox with `entwurf_inbox_read`, and use `entwurf_register_native` only as the explicit/manual fallback for binding an already-running agy conversation (normal agy birth is automatic through the installed hook). Open a NEW sibling with **`entwurf_fresh_call {backend, model, task, cwd?}`**, and reopen a DORMANT pi citizen under its own garden id with **`entwurf_resume_call {target}`**. Fresh call accepts one optional literal absolute `cwd`: omit it or pass `""` for the caller's cwd; otherwise it must name an existing directory and may not contain `#`. Use that input for a new cross-repository sibling — resume preserves a dormant Pi citizen's recorded continuity and is not a cwd substitute. Fresh call needs its selected runtime (`pi` or `claude`) on the server's PATH; resume call always needs `pi`. Both start a runtime, while delivery does not. (The old v1 verbs `entwurf` / `entwurf_resume` / `entwurf_send` are gone.)
|
|
13
13
|
|
|
14
14
|
Observed: Claude Code, Codex CLI, and Antigravity CLI all reach the read surfaces through this MCP bridge from a plain external host — `entwurf_peers` is a pure fact projection, while `entwurf_inbox_read` is a **mutating drain** (it archives the messages and stamps the read-receipt), so "read" here does not mean side-effect-free; **sending** needs an identity lane. Claude becomes symmetric/replyable through its mailbox-backed meta-session; agy becomes symmetric/replyable through its record-backed sender marker plus live native-push probe. Codex has no managed citizen lifecycle yet, so a Codex host cannot send without the explicit anonymous hatch below.
|
|
15
15
|
|
|
16
16
|
Prerequisites on the host running the external MCP client:
|
|
17
17
|
|
|
18
|
-
- `pi` on PATH (for the `owned-outcome` spawn-bg resume path).
|
|
19
18
|
- A live pi session launched with `--entwurf-control` populates `~/.pi/entwurf-control/<gardenId>.sock` — the key is the **record's** garden id, never a transcript/session id (`PI_SESSION_ID` only carries the id record birth already established). Required for `entwurf_v2` control-socket dispatch and `entwurf_peers`.
|
|
20
19
|
|
|
21
|
-
> **PATH boundary.** MCP servers are often launched by GUI/editor daemons and may not inherit the interactive shell's PATH.
|
|
20
|
+
> **PATH boundary.** MCP servers are often launched by GUI/editor daemons and may not inherit the interactive shell's PATH. No `entwurf_v2` rail launches a process, so this does not affect delivery — but `entwurf_fresh_call` and `entwurf_resume_call` do open a fixed runtime. If that runtime works in your terminal but an external-host call fails with `spawn pi ENOENT` or `spawn claude ENOENT`, pass a full PATH in the MCP server `env`, set `ENTWURF_BRIDGE_ENV_FILE` to a small shell file that exports PATH, or point the host at a wrapper that can find the runtime. `start.sh` sources only the explicit `ENTWURF_BRIDGE_ENV_FILE`; it never reads personal dotfiles automatically.
|
|
22
21
|
|
|
23
22
|
Example env file:
|
|
24
23
|
|
|
@@ -46,7 +45,7 @@ External/meta-session semantics:
|
|
|
46
45
|
|
|
47
46
|
- `entwurf_v2` from a plain external host is **refused by default** (no authoritative sender — #50 C4). With the explicit `ENTWURF_BRIDGE_ALLOW_ANONYMOUS_SENDER=1` hatch it delivers with `origin: "external-mcp"` / `replyable: false`; there is still no reply address.
|
|
48
47
|
- `entwurf_v2` from a trusted meta-session delivers with `origin: "meta-session"`, and `replyable` is **derived from that sender's own rail — not granted by being trusted**: a self-fetch sender (Claude Code) is replyable only while its receiver is live and armed, and a native-push sender (Antigravity) only while its adapter probe finds the live conversation. Identity survives either way; only `replyable` drops to `false`. When it is `true`, `wants_reply: true` is allowed and the receiver can reply to the sender's garden id.
|
|
49
|
-
- `entwurf_v2`
|
|
48
|
+
- `entwurf_v2` never launches a process, so no delivery path needs `pi` on PATH. A dormant pi target is refused as `dormant-fire-forget-unsupported`: the hidden background resume that used to answer there was withdrawn under the visible-first rule, and re-opening the session is the separate `entwurf_resume_call` verb — which DOES need `pi` on PATH, because it starts one.
|
|
50
49
|
- `entwurf_self` returns the same authoritative identity for pi sessions **and** trusted meta-sessions. A plain external host with no pi env and no trusted sender marker still fails because there is no reply address to report.
|
|
51
50
|
|
|
52
51
|
#### Claude Code
|
|
@@ -114,7 +113,7 @@ entwurf doctor-agy-hooks
|
|
|
114
113
|
|
|
115
114
|
The three adapters deliberately own different atoms:
|
|
116
115
|
|
|
117
|
-
- bridge: one `entwurf-bridge` server in `~/.gemini/config/mcp_config.json`, plus one narrow permission string per tool the normal agy workflow calls — `mcp(entwurf-bridge/entwurf_v2)`, `mcp(entwurf-bridge/entwurf_peers)`, `mcp(entwurf-bridge/entwurf_self)` — in `~/.gemini/antigravity-cli/settings.json`. agy defaults every `mcp` action to Ask, so a tool that ships without its own rule stops for a y/n on every call; `entwurf_inbox_read` is deliberately not granted (native-push has no inbox)
|
|
116
|
+
- bridge: one `entwurf-bridge` server in `~/.gemini/config/mcp_config.json`, plus one narrow permission string per tool the normal agy workflow calls — `mcp(entwurf-bridge/entwurf_v2)`, `mcp(entwurf-bridge/entwurf_peers)`, `mcp(entwurf-bridge/entwurf_self)` — in `~/.gemini/antigravity-cli/settings.json`. agy defaults every `mcp` action to Ask, so a tool that ships without its own rule stops for a y/n on every call; `entwurf_inbox_read` is deliberately not granted (native-push has no inbox), neither is the manual `entwurf_register_native` fallback, and neither are `entwurf_fresh_call` / `entwurf_resume_call` (both launch into the caller's own tmux session, which an agy conversation is not);
|
|
118
117
|
- statusline: the complete `statusLine` subtree pointing at the bare stable bin `entwurf-agy-statusline`;
|
|
119
118
|
- hooks: one named `PreInvocation` hook pointing at the bare stable bin `entwurf-agy-imprint`.
|
|
120
119
|
|
package/docs/setup-clean-host.md
CHANGED
|
@@ -11,7 +11,7 @@ only on Linux because its strict live-owner join uses `/proc`.
|
|
|
11
11
|
| Node | **`>=24.0.0`** | package and bridge runtime |
|
|
12
12
|
| npm | bundled with Node | package installation |
|
|
13
13
|
| entwurf | `@junghanacs/entwurf` | all lanes |
|
|
14
|
-
| pi | optional, `@earendil-works/pi-coding-agent >=0.
|
|
14
|
+
| pi | optional, `@earendil-works/pi-coding-agent >=0.84.1 <0.85` | ACP provider, control sockets |
|
|
15
15
|
| Claude Code | optional, **`>=2.1.217`** — the exec-form hook floor | Claude ACP auth/runtime and mailbox-backed native citizen |
|
|
16
16
|
| Antigravity `agy` | optional, operator-installed and authenticated | native-push citizen |
|
|
17
17
|
| Cortex Code | optional, operator-installed and authenticated | Cortex ACP backend |
|
|
@@ -49,14 +49,14 @@ npx entwurf check-bridge
|
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
`check-bridge` is auth-free. It proves the installed prebuilt MCP server boots and
|
|
52
|
-
lists the
|
|
52
|
+
lists the seven garden tools; it does not prove a backend model turn or native hook.
|
|
53
53
|
|
|
54
54
|
## 2. Optional pi adapter / ACP plugin
|
|
55
55
|
|
|
56
56
|
Install the exact release floor, then wire the project:
|
|
57
57
|
|
|
58
58
|
```bash
|
|
59
|
-
npm install -g @earendil-works/pi-coding-agent@0.
|
|
59
|
+
npm install -g @earendil-works/pi-coding-agent@0.84.1
|
|
60
60
|
pi --version
|
|
61
61
|
|
|
62
62
|
cd ~/entwurf-smoke
|
|
@@ -64,10 +64,10 @@ entwurf install .
|
|
|
64
64
|
pi -e "$(npm root -g)/@junghanacs/entwurf" --list-models entwurf
|
|
65
65
|
```
|
|
66
66
|
|
|
67
|
-
The supported range is `>=0.
|
|
68
|
-
release onto a 0.
|
|
67
|
+
The supported range is `>=0.84.1 <0.85`. It is a hard minimum: installing this
|
|
68
|
+
release onto a 0.83.x pi host upgrades the runtime rather than keeping the older
|
|
69
69
|
minor. A host using only the external MCP bridge can skip pi until it needs a
|
|
70
|
-
control socket
|
|
70
|
+
control socket; no delivery rail launches a pi process.
|
|
71
71
|
|
|
72
72
|
For daily garden-native pi sessions:
|
|
73
73
|
|
|
@@ -174,7 +174,8 @@ and exit-code contract is [fresh-cut-policy.md](./fresh-cut-policy.md).
|
|
|
174
174
|
## 7. Release acceptance versus host acceptance
|
|
175
175
|
|
|
176
176
|
- `entwurf check-bridge`: installed MCP bytes boot; no backend auth.
|
|
177
|
-
- `pnpm check`: source deterministic
|
|
177
|
+
- `pnpm check` / `pnpm run check:full`: tiered source deterministic floors (everyday
|
|
178
|
+
core / full candidate floor); maintainer checkout only.
|
|
178
179
|
- `check-install-container`: checkout-invisible Linux package-consumer shape using
|
|
179
180
|
fixtures; not a native lifecycle proof.
|
|
180
181
|
- `doctor-meta-bridge`: one installed real Claude host, only with a new live session.
|