@junghanacs/entwurf 0.12.10 → 0.13.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 +6 -3
- package/BASELINE.md +56 -163
- package/CHANGELOG.md +35 -0
- package/CONTRIBUTING.md +4 -2
- package/DELIVERY.md +117 -261
- package/README.md +74 -399
- package/VERIFY.md +59 -85
- package/demo/README.md +1 -1
- package/docs/acp-backend-rail.md +231 -0
- package/docs/external-mcp-host.md +132 -0
- package/docs/fresh-cut-policy.md +99 -0
- package/docs/setup-clean-host.md +123 -328
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +21 -48
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/acp-client.js +12 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +155 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/config.js +16 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/engraving.js +42 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/models.js +66 -7
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +190 -5
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/tool-surface.js +12 -4
- package/mcp/entwurf-bridge/src/index.ts +21 -48
- package/package.json +14 -9
- package/pi/settings.reference.json +1 -1
- package/pi-extensions/acp-provider.ts +20 -10
- package/pi-extensions/entwurf-control.ts +20 -49
- package/pi-extensions/lib/acp/acp-client.ts +22 -0
- package/pi-extensions/lib/acp/augment.ts +99 -2
- package/pi-extensions/lib/acp/backend-adapter.ts +190 -14
- package/pi-extensions/lib/acp/backend.ts +310 -37
- package/pi-extensions/lib/acp/config.ts +19 -5
- package/pi-extensions/lib/acp/engraving.ts +46 -2
- package/pi-extensions/lib/acp/event-mapper.ts +26 -16
- package/pi-extensions/lib/acp/models.ts +69 -7
- package/pi-extensions/lib/acp/overlay.ts +234 -5
- package/pi-extensions/lib/acp/tool-surface.ts +12 -4
- package/prompts/engraving.md +13 -5
- package/run.sh +386 -119
- package/scripts/check-acp-carrier-augment.ts +246 -10
- package/scripts/check-acp-cortex.ts +668 -0
- package/scripts/check-acp-prompt-lifecycle.ts +565 -0
- package/scripts/check-acp-provider-surface.ts +50 -6
- package/scripts/check-acp-sdk-surface.ts +60 -21
- package/scripts/check-acp-session-reuse.ts +64 -1
- package/scripts/check-acp-stop-reason.ts +342 -0
- package/scripts/check-entwurf-v2-surface.ts +41 -0
- package/scripts/check-gate-qualification.ts +7 -2
- package/scripts/check-probe-cli-shim.ts +879 -0
- package/scripts/check-probe-ordering.ts +2482 -0
- package/scripts/check-release-gate-outcomes.ts +332 -0
- package/scripts/check-shell-quote.ts +4 -4
- package/scripts/fixtures/probe-cli-shim +20 -0
- package/scripts/fixtures/probe-mcp-server.ts +168 -12
- package/scripts/lib/live-skip.ts +33 -0
- package/scripts/lib/probe-acp-turn.ts +228 -0
- package/scripts/lib/probe-cli-shim.ts +464 -0
- package/scripts/lib/probe-cli-target.ts +165 -0
- package/scripts/lib/probe-event-log.ts +383 -0
- package/scripts/lib/probe-verdict.ts +1213 -0
- package/scripts/lib/step-outcome.sh +88 -0
- package/scripts/mutants/acp-augment.json +106 -0
- package/scripts/mutants/acp-cortex.json +196 -0
- package/scripts/mutants/acp-prompt-lifecycle.json +100 -0
- package/scripts/mutants/acp-stop-reason.json +80 -0
- package/scripts/mutants/probe-ordering.json +1054 -0
- package/scripts/mutants/release-gate.json +105 -0
- package/scripts/mutants/v2-surface.json +26 -15
- package/scripts/smoke-acp-bundled-mcp-live.ts +4 -3
- package/scripts/smoke-acp-carrier-augment-live.ts +2 -2
- package/scripts/smoke-acp-cortex-live.ts +386 -0
- package/scripts/smoke-acp-long-turn-live.ts +185 -0
- package/scripts/smoke-acp-mcp-live.ts +2 -2
- package/scripts/smoke-acp-memory-containment-live.ts +2 -2
- package/scripts/smoke-acp-ordering-probe-live.ts +848 -0
- package/scripts/smoke-acp-overlay-live.ts +2 -2
- package/scripts/smoke-acp-provider-live.ts +2 -2
- package/scripts/smoke-acp-raw-turn-live.ts +3 -3
- package/scripts/smoke-acp-session-reuse-live.ts +2 -2
- package/scripts/smoke-acp-skill-live.ts +2 -2
- package/scripts/smoke-acp-socket-citizen-live.ts +4 -3
- package/scripts/smoke-acp-v2-send-live.ts +4 -3
- package/scripts/smoke-agy-native-push-live.ts +4 -3
- package/scripts/smoke-claude-native-resume-live.sh +13 -3
- package/scripts/smoke-entwurf-chain-live.ts +352 -0
- package/scripts/smoke-entwurf-v2-matrix-live.ts +2 -2
- package/scripts/smoke-entwurf-v2-spawn-resume-live.ts +2 -4
- package/scripts/smoke-meta-install-state.sh +4 -0
package/AGENTS.md
CHANGED
|
@@ -64,7 +64,9 @@ Detailed incident histories belong in CHANGELOG/issues/BASELINE and source-adjac
|
|
|
64
64
|
- The common turn sequence stays backend-invariant: spawn → initialize → newSession → enforceModel → prompt → event map.
|
|
65
65
|
- Rich operator/project context rides the **first user message augment**, not a large system prompt. The actual callable schema is the tool truth; prose never grants a tool.
|
|
66
66
|
- A backend may have no carrier or use launch-time model pinning; those asymmetries stay inside its adapter.
|
|
67
|
-
-
|
|
67
|
+
- A streaming assistant message starts `pending`. ACP terminal reasons are mapped explicitly; refusal, exhausted turn budget, unknown, or absent reasons end as errors, and the raw reason is preserved. Never restore a default-to-success branch.
|
|
68
|
+
- Bootstrap steps carry wall-clock bounds; a running prompt does not. A turn ends only when the agent answers, the operator aborts (ACP `session/cancel` first, bounded cleanup after), or the child dies. Elapsed time is not evidence, and a prompt-phase failure we author must never read as transient to pi's retry classifier — a cutoff plus blind retry replays the whole prompt from cold.
|
|
69
|
+
- Claude is the reference adapter. Cortex is the second landed adapter (0.13.0): session-scoped dual-HOME containment, overlay-private `mcp.json` projection (its ACP server ignores the wire `mcpServers` param), `CORTEX_HOME` presence refusal, per-turn set-model. Current contract: `docs/acp-backend-rail.md` “Cortex Code audit (D1–D10)”.
|
|
68
70
|
- entwurf never supplies, copies, proxies, decrypts, or bypasses vendor credentials/subscriptions. It uses the operator's existing local authenticated backend.
|
|
69
71
|
|
|
70
72
|
## Citizen Identity and Dispatch
|
|
@@ -110,10 +112,11 @@ pnpm check
|
|
|
110
112
|
./run.sh check-install-surface
|
|
111
113
|
./run.sh check-install-container # require Docker in release acceptance
|
|
112
114
|
|
|
113
|
-
LIVE=1 ./run.sh release-gate /path/to/scratch
|
|
115
|
+
LIVE=1 ./run.sh release-gate /path/to/scratch --cut
|
|
114
116
|
LIVE=1 ./run.sh smoke-acp-socket-citizen-live
|
|
115
117
|
LIVE=1 ./run.sh smoke-acp-bundled-mcp-live
|
|
116
118
|
LIVE=1 ./run.sh smoke-acp-v2-send-live
|
|
119
|
+
LIVE=1 ENTWURF_ACP_CORTEX_CONNECTION=<conn> ./run.sh smoke-acp-cortex-live # on-demand; outside the claude release floor
|
|
117
120
|
LIVE=1 AGY_CONVERSATION_ID=<id> ./run.sh smoke-agy-native-push-live
|
|
118
121
|
```
|
|
119
122
|
|
|
@@ -145,7 +148,7 @@ LIVE=1 AGY_CONVERSATION_ID=<id> ./run.sh smoke-agy-native-push-live
|
|
|
145
148
|
- Every `.ts` file belongs to one typecheck fence: root emit-capable config, MCP strip-types config, or scripts strip-types config. Do not hide files with `exclude`.
|
|
146
149
|
- Root pi extensions import TypeBox through `@earendil-works/pi-ai`; do not mix direct `@sinclair/typebox` types.
|
|
147
150
|
- MCP/scripts use explicit `.ts` imports where Node strip-types requires them. Installed operator surfaces route to compiled JS.
|
|
148
|
-
- pi runtime range is `>=0.
|
|
151
|
+
- pi runtime range is `>=0.83.0 <0.84` with devDep exact `0.83.0`; re-evaluate loader aliases and `/compat` at the minor ceiling. Re-measured at the 0.82.1→0.83.0 move: `packages/coding-agent/src/core/extensions/loader.ts` and `packages/ai/src/compat.ts` are byte-identical across the two tags, so the ceiling moved on measurement, not assumption.
|
|
149
152
|
- ACP pins are recorded in `package.json` and checked by `check-dep-versions`/`check-acp-sdk-surface`; do not describe a dependency bump as a behavioral fix without evidence.
|
|
150
153
|
|
|
151
154
|
## Working Style
|
package/BASELINE.md
CHANGED
|
@@ -6,28 +6,43 @@ silently drifted into a different identity / context surface. Questions
|
|
|
6
6
|
are deliberately open-ended — they probe what the agent actually sees,
|
|
7
7
|
not what it was told to claim.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
reference axes, not the shipped ACP baseline.
|
|
9
|
+
Claude is the reference ACP backend. Cortex Code has a separate compact baseline
|
|
10
|
+
because it has no system-prompt carrier and keeps its own native tool surface.
|
|
11
|
+
Antigravity (`agy`) is a native-push citizen rather than an ACP backend and therefore
|
|
12
|
+
has a separate citizen/round-trip baseline. Historical Codex/Gemini probes are not
|
|
13
|
+
part of this operator interview.
|
|
15
14
|
|
|
16
|
-
## Release-host baseline
|
|
15
|
+
## Release-host baseline
|
|
17
16
|
|
|
18
17
|
This table is the operator-facing support/certification view. It complements the
|
|
19
18
|
model interview below; a persuasive answer from the model cannot turn an unmeasured
|
|
20
|
-
host into a certified one.
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
|
25
|
-
|
|
26
|
-
|
|
|
27
|
-
|
|
|
28
|
-
|
|
|
29
|
-
|
|
|
30
|
-
|
|
|
19
|
+
host into a certified one. Verdicts are one of **certified** (a real host ran the
|
|
20
|
+
installed doctor green), **shape-only** (gates model the package, no live host),
|
|
21
|
+
or **unverified**.
|
|
22
|
+
|
|
23
|
+
| Surface | Verdict | Evidence |
|
|
24
|
+
|---|---|---|
|
|
25
|
+
| Node 24 Linux package consumer | shape-only | Required `artifact-consumer` CI |
|
|
26
|
+
| Claude Code >=2.1.217 exec form | **certified** — supported floor | Topology + floor gates, doctor oracle; B2 live NixOS session |
|
|
27
|
+
| Claude Code 2.1.138 | **unsupported** | Launcher refuses empty argv; no shell-form fallback |
|
|
28
|
+
| Maintainer NixOS installed package | **certified** for `0.12.8-repair.1` | 2026-07-25 registry install → doctor exit 0 (HISTORY) |
|
|
29
|
+
| Secondary Ubuntu installed package | **certified** for `0.12.8-repair.1` | 2026-07-25 same artifact, isolated agent dir → doctor exit 0 (HISTORY) |
|
|
30
|
+
| macOS Claude meta-bridge | unverified | Installer refuses Darwin; no `/proc` live join |
|
|
31
|
+
| WSL2 / Windows | unverified | None |
|
|
32
|
+
|
|
33
|
+
Notes the table cannot carry without becoming prose again:
|
|
34
|
+
|
|
35
|
+
- **shape-only is not a live proof.** The `artifact-consumer` job verifies a read-only
|
|
36
|
+
candidate `.tgz`, checkout-invisible non-root global install, PATH shims, a frozen
|
|
37
|
+
package root, the path+sha256 regular-file fence, and a strict doctor fixture. Its
|
|
38
|
+
planted Claude cache/owner/bridge are synthetic — no real Claude lifecycle runs there.
|
|
39
|
+
- **Both certified hosts are certified for the published repair artifact only**, including
|
|
40
|
+
physical `entwurf_v2` delivery and the live owner join. Stable cuts earn their own host
|
|
41
|
+
proof; hand-patched hooks and `plugin validate` output are never acceptance.
|
|
42
|
+
- **The maintainer host first went doctor-RED** on a managed dev-bin shadowing the registry
|
|
43
|
+
bridge, and now runs dev wiring again.
|
|
44
|
+
- **macOS is not permanently excluded.** Future native validation may reopen it, and the
|
|
45
|
+
package-level `os` field stays unrestricted.
|
|
31
46
|
|
|
32
47
|
**Operator acceptance rule:** on a claimed Claude host, reinstall from the released
|
|
33
48
|
artifact, restart every old Claude process, open a new session, and run the doctor
|
|
@@ -72,20 +87,16 @@ expected isolation-closed response, **FAIL** = listed failure mode,
|
|
|
72
87
|
> `check-acp-carrier-augment`) and the live `smoke-acp-memory-containment-live`;
|
|
73
88
|
> this document records the model-side observation.
|
|
74
89
|
|
|
75
|
-
##
|
|
90
|
+
## Claude-specific surface
|
|
76
91
|
|
|
77
|
-
|
|
78
|
-
is the 0.12 shipped ACP baseline; Codex/Gemini are historical probe reference.
|
|
79
|
-
Do not replace the Gemini column with agy: agy does not use this overlay/carrier
|
|
80
|
-
contract at all, and its shipped baseline is the native-citizen section below.
|
|
92
|
+
The two-round question bank below is the Claude reference baseline.
|
|
81
93
|
|
|
82
|
-
| Slot | Claude
|
|
83
|
-
|
|
84
|
-
| Config
|
|
85
|
-
|
|
|
86
|
-
|
|
|
87
|
-
|
|
|
88
|
-
| Memory write target (Q-L5W) | `CLAUDE.md`, hooks, agents | `~/.codex/memories`, AGENTS.md | `GEMINI.md`, `MEMORY.md`, autoMemory inbox |
|
|
94
|
+
| Slot | Expected Claude surface |
|
|
95
|
+
|---|---|
|
|
96
|
+
| Config dir (Q-L2) | `CLAUDE_CONFIG_DIR`, pointing at the entwurf overlay rather than `~/.claude/` |
|
|
97
|
+
| Read-class tools (Q-L3) | `Read`, `Bash` (ls/find/grep) |
|
|
98
|
+
| Project memory (Q-L4) | `CLAUDE.md` / `.claude/`, not inherited through the overlay |
|
|
99
|
+
| Native memory write (Q-L5W) | none; do not create `CLAUDE.md`, hooks, or agents as a memory substitute |
|
|
89
100
|
|
|
90
101
|
---
|
|
91
102
|
|
|
@@ -246,144 +257,26 @@ same-process concurrency.
|
|
|
246
257
|
|
|
247
258
|
---
|
|
248
259
|
|
|
249
|
-
##
|
|
250
|
-
|
|
251
|
-
Historical Gemini probe, retained for the probe lane only — **not** part of
|
|
252
|
-
the shipped Claude baseline. Gemini's `applySubstitutions` rewrites unknown
|
|
253
|
-
`${name}` tokens; the bridge inserts a U+200B between `$` and `{` in operator
|
|
254
|
-
engraving body so the regex misses while the visual text stays stable. The
|
|
255
|
-
former carrier-isolation canary literal is a doc-era artifact with **no code
|
|
256
|
-
surface on 0.12** — do not assert it as a current expectation.
|
|
260
|
+
## Cortex baseline
|
|
257
261
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
overlay, open a fresh Gemini ACP session, then ask `Q-H`:
|
|
262
|
+
Run these checks in a fresh `entwurf/cortex-*` session. Do not grade Cortex against
|
|
263
|
+
Claude's overlay or system-prompt carrier.
|
|
261
264
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
|
|
265
|
+
| ID | Check | PASS | FAIL |
|
|
266
|
+
|---|---|---|---|
|
|
267
|
+
| Q-CX-ID | Backend identity | Identifies Cortex and the selected enforced model; does not claim to be Claude Code. | Reports the Claude backend or an unenforced/default model. |
|
|
268
|
+
| Q-CX-TOOLS | Native surface | Reports Cortex-native tools; garden tools arrive only through `entwurf-bridge`. | Lists Claude's `Read/Bash/Edit/Write` allowlist as its native surface. |
|
|
269
|
+
| Q-CX-MCP | Bridge projection | `entwurf-bridge` is reachable through the overlay-private `cortex/mcp.json`; no ambient operator MCP catalog appears. | Bridge absent, or unrelated operator MCP servers leak in. |
|
|
270
|
+
| Q-CX-CARRIER | Context carrier | Says Cortex has no system-prompt engraving carrier; engraving/context arrived in the first-user augment. | Claims `_meta.systemPrompt` delivered the engraving. |
|
|
271
|
+
| Q-CX-HOME | Containment | Distinguishes isolated HOME from the real operator HOME restored only for the bridge; `CORTEX_HOME` is absent. | Claims broad operator home/config inheritance or a present `CORTEX_HOME`. |
|
|
269
272
|
|
|
270
|
-
|
|
271
|
-
|
|
273
|
+
The live `smoke-acp-cortex-live` and deterministic `check-acp-cortex` remain the
|
|
274
|
+
oracles. This interview tests whether the model describes that surface honestly.
|
|
272
275
|
|
|
273
276
|
---
|
|
274
277
|
|
|
275
278
|
# HISTORY (pointer)
|
|
276
279
|
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
Each host ran installed `entwurf install-meta-bridge`, opened a NEW real Claude Code
|
|
281
|
-
session with a live MCP child, and ran the installed `entwurf doctor-meta-bridge`
|
|
282
|
-
against an isolated clean `PI_CODING_AGENT_DIR`; both doctors reached **PASS**, including
|
|
283
|
-
the live MCP owner join and a physical `entwurf_v2` delivery. The maintainer host first
|
|
284
|
-
proved the oracle's value by failing when its managed dev-bin shadowed the registry
|
|
285
|
-
`entwurf-bridge`: the installed v2 hook wrote a v2 record while the checkout's v3 bridge
|
|
286
|
-
refused it. Removing the managed dev bin made PATH resolve the registry bridge, after
|
|
287
|
-
which the same native proof passed. The test-created v2 record from that failed mixed-path
|
|
288
|
-
attempt was preserved under `meta-sessions.proof-failed-20260725T165227/`; the maintainer's
|
|
289
|
-
V3 development wiring was restored after acceptance. This closes VERIFY's two-host
|
|
290
|
-
repair.1 prerequisite for a separately authorized stable `0.12.8`; it is host
|
|
291
|
-
corroboration of the published repair artifact, not evidence for the future stable
|
|
292
|
-
candidate, which still earns exact-SHA CI, LIVE, and preserved-artifact acceptance.
|
|
293
|
-
Exact pre-version closure checkpoint `28a52fe2d6e9ca29b657a33e5c80ff4debda2f0f`
|
|
294
|
-
passed GitHub Actions run [30149759311](https://github.com/junghan0611/entwurf/actions/runs/30149759311):
|
|
295
|
-
`check`, `install-surface`, and `artifact-consumer` all success. The host proof then found
|
|
296
|
-
a one-line `remove-dev-bin` dispatch defect, so the eventual stable landing HEAD must earn
|
|
297
|
-
a fresh exact-SHA run; this checkpoint is not reused as that acceptance.
|
|
298
|
-
|
|
299
|
-
2026-07-24 (night) upgrade-harness + review acceptance at exact HEAD
|
|
300
|
-
`cbda097` (branch `repair/v2-core-debt`, merged to main the same night — the
|
|
301
|
-
hard-cut branch chronicle lives in issue #50): the three-cell harness gained
|
|
302
|
-
the UPGRADE axis — `setup` / `install` / `install-meta-bridge` refuse a
|
|
303
|
-
pre-cut (v1/v2) meta-record store BEFORE their first write, prescribe on
|
|
304
|
-
three axes (pre-cut → migrate; problems → repair first; both → repair FIRST,
|
|
305
|
-
then migrate), and the proof seeds every host state from frozen fixture bytes
|
|
306
|
-
(`fixtures/meta-store`, sha256-manifested, excluded from the tarball).
|
|
307
|
-
Deterministic cells at this HEAD: `pnpm check` EXIT=0 (source cell
|
|
308
|
-
`check-upgrade-gate` 57/0), `check-pack-install` EXIT=0,
|
|
309
|
-
`ENTWURF_REQUIRE_DOCKER=1 check-install-container` EXIT=0 — candidate
|
|
310
|
-
`junghanacs-entwurf-0.12.8-repair.1.tgz` **sha256
|
|
311
|
-
`db17165f962c938d71ef97cb7a86252549dc91b00d5ec67f63ec65b41039e6dc`**,
|
|
312
|
-
11413738 bytes, image `sha256:f1158c7f34cf35a047bf0513c38282bb2fa253529e5ae404b32c6d93697410be`.
|
|
313
|
-
Live at this HEAD: `LIVE=1 release-gate` **MUST 16/1/0 + BEHAVIOR 1/0,
|
|
314
|
-
EXIT=1** — the single FAIL is `smoke-acp-bundled-mcp-live`, the known
|
|
315
|
-
bundled-MCP readiness race (ROADMAP 「🔴 OPEN」, GLG: observe, don't fix;
|
|
316
|
-
sample recorded with transcript; isolated re-run PASS 4/4). Every other MUST
|
|
317
|
-
passed at this HEAD, including `smoke-acp-v2-send-live` (send identity /
|
|
318
|
-
replyability) and the matrix honest-reject. **A release cut stays blocked on
|
|
319
|
-
that red by the gate's own words; the merge to main was GLG's explicit call
|
|
320
|
-
with the race documented as an open observation item.**
|
|
321
|
-
|
|
322
|
-
2026-07-24 dependency-uplift acceptance at exact HEAD
|
|
323
|
-
`7cbeb29b6afcfbaf4fc28da3b7929037c339113d` (branch `repair/v2-core-debt`): pi
|
|
324
|
-
runtime **0.80.7 → 0.82.0** and Claude ACP **claude-agent-acp 0.54.1 → 0.61.0 /
|
|
325
|
-
ACP SDK 1.1.0 → 1.3.0** as two separate cuts, with `@anthropic-ai/sdk` held at
|
|
326
|
-
**0.100.1** (measured through the real module graph: claude-agent-sdk 0.3.217's
|
|
327
|
-
`>=0.93.0` peer resolves to 0.100.1 there; dropping the direct pin under this
|
|
328
|
-
repo's `autoInstallPeers:false` leaves only 0.91.1 and the peer goes unmet).
|
|
329
|
-
Deterministic 3 cells all EXIT=0 on Node 24 Linux — checkout (`pnpm
|
|
330
|
-
build-bridge && pnpm check`), installed tree (`check-pack-install`: resolved
|
|
331
|
-
tree holds only `@earendil-works@0.82.0`, loader drove the pinned pi, installed
|
|
332
|
-
bin delivered a `.msg`), clean consumer (`ENTWURF_REQUIRE_DOCKER=1
|
|
333
|
-
check-install-container`, candidate `junghanacs-entwurf-0.12.8-repair.1.tgz`
|
|
334
|
-
**sha256 `ab5dee07585c8d7a4f8f174cedea0051489ae1a26766ff1baf8edd7377d5bac7`**,
|
|
335
|
-
11391060 bytes, image `sha256:f1158c7f34cf35a047bf0513c38282bb2fa253529e5ae404b32c6d93697410be`).
|
|
336
|
-
Live: `LIVE=1 ./run.sh release-gate` measured **MUST 17/0/0 + BEHAVIOR 1/0,
|
|
337
|
-
EXIT=0** at this HEAD — the first aggregate to include
|
|
338
|
-
`smoke-acp-v2-send-live`, which closes the SEND half of ACP citizenship (an ACP
|
|
339
|
-
model calls `entwurf_v2` and the `.msg` lands carrying the resident's own garden
|
|
340
|
-
id, `entwurf/<model>`, replyable — a gid never present in the prompt). Two
|
|
341
|
-
stale claims were retired against measurement rather than argument: the
|
|
342
|
-
extension-loader `/compat` shim survives 0.82.0 (root / `/compat` / `/oauth`
|
|
343
|
-
untouched; `/providers/all` is an addition, and the curated Claude anchors are
|
|
344
|
-
byte-identical across the bump), and the "one-shot bundled-MCP teardown hang"
|
|
345
|
-
that a gate comment used as its rationale does not reproduce on this
|
|
346
|
-
combination. What a plain `pi -p` genuinely lacks is garden identity, and only
|
|
347
|
-
without `--entwurf-control` — now documented as a provider/citizen boundary
|
|
348
|
-
instead of read as a defect.
|
|
349
|
-
|
|
350
|
-
2026-07-24 record-era aggregate floor: `LIVE=1 ./run.sh release-gate` measured
|
|
351
|
-
**MUST 16/0/0 + BEHAVIOR 1/0, EXIT=0** on the `repair/v2-core-debt` branch after
|
|
352
|
-
the #50 C1–C3 cuts and the observability repair — the first aggregate run since
|
|
353
|
-
2026-06-27 (every individual smoke had been green, but the two-tier summary and
|
|
354
|
-
exit code of the aggregate command itself had gone unverified for the whole
|
|
355
|
-
hard-cut window; three MUST live smokes were found dead on the pre-C2 address
|
|
356
|
-
contract and re-authored in the same pass). The step count moved 17→16 with the
|
|
357
|
-
v2-cutover smoke retirements. Evidence log: `/tmp/pi-tmux-release-gate.log`
|
|
358
|
-
(scratch `/tmp/entwurf-rg-scratch-20260724`).
|
|
359
|
-
|
|
360
|
-
2026-07-22 repair evidence: Linux artifact-consumer C is committed locally as
|
|
361
|
-
`328c66e` (not yet pushed at the time of this baseline update); B/B2 direct-native
|
|
362
|
-
observations and the exec-only production cut are documented in issue #51 and
|
|
363
|
-
VERIFY's host matrix. **Post-provenance C was re-proven rather than inheriting the
|
|
364
|
-
earlier green:** the first rerun correctly went RED because its stand-in Claude was
|
|
365
|
-
container PID 1, which the product rejects as an impossible/reparented owner. The
|
|
366
|
-
fixture now keeps an outer PID-1 shell and runs the consumer as pid 8; both default
|
|
367
|
-
pack-once and caller-preserved exact-tgz modes reached doctor PASS with marker
|
|
368
|
-
`ownerPid=8 (>1)` and identical artifact sha256. The preserved file's
|
|
369
|
-
inode/size/mtime/sha tuple was unchanged across acceptance. Evidence logs:
|
|
370
|
-
`/tmp/pi-tmux-entwurf-exact-final.log` and
|
|
371
|
-
`/tmp/pi-tmux-entwurf-default-final.log`; the digest belongs in the external cut log,
|
|
372
|
-
not inside this shipped file (embedding it would mutate the tarball it names).
|
|
373
|
-
This was the `0.12.7-1` gate candidate, **not** the approved release artifact. Exact
|
|
374
|
-
mode was later repeated for `0.12.8-repair.0`, and those accepted bytes were published
|
|
375
|
-
under `repair` on 2026-07-22. Field evidence then invalidated that release: its installed
|
|
376
|
-
MCP dist omitted `entwurf-capabilities.json`, so tools/list and the old doctor stayed
|
|
377
|
-
green while every `entwurf_v2` send died ENOENT. The repaired candidate must be
|
|
378
|
-
`0.12.8-repair.1` and must earn fresh exact-SHA CI, LIVE-gate, preserved-artifact, and
|
|
379
|
-
container evidence; none of repair.0's release evidence transfers. Maintainer/secondary-host
|
|
380
|
-
installed doctor GREEN remains deliberately pending until after repair.1 publication.
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
Per-release baselines — the 0.9.0 garden-native identity cut (17 PASS / 0 FAIL /
|
|
384
|
-
0 SKIP `/gnew`-inclusive gate, #28), and the older 0.8.x / 0.5.0 context-pressure
|
|
385
|
-
baselines — live in **CHANGELOG.md and git history**, including the gate names of
|
|
386
|
-
their era (several of which, e.g. `smoke-all` / `smoke-async-resume` /
|
|
387
|
-
`smoke-compaction-policy` / `sentinel` / `xt-tool-surface`, were retired in the
|
|
388
|
-
v2 cutover). The live calibration reference is the current release floor in
|
|
389
|
-
[VERIFY.md](./VERIFY.md) §0A — most recent: **2026-07-24 MUST 16/0/0 + BEHAVIOR 1/0**.
|
|
280
|
+
Per-release counts, digests, host observations, and incident chronology live in
|
|
281
|
+
[CHANGELOG.md](./CHANGELOG.md), release artifacts, issues, and git history. This
|
|
282
|
+
file keeps only the current operator interview and support verdicts.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,41 @@ All notable changes to this project will be documented here. Format follows [Kee
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.13.1 — 2026-07-31
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **ACP prompt lifecycle no longer applies a 600-second wall-clock cutoff to a running turn.** Bootstrap remains bounded; user abort sends ACP cancellation before bounded teardown, and child exit/stdio failure now preserves lifecycle phase, exit/signal, and stderr evidence without automatic cold replay.
|
|
12
|
+
- **The release gate now makes actual invocation auditable.** Every MUST step reports PASS, protocol SKIP, or FAIL; `--cut` refuses a MUST SKIP without misreporting it as a failed call. The aggregate includes the native resume, spawn substrate, and authenticated cross-harness delivery chain; Cortex remains an explicitly documented on-demand host-auth axis.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Claude's tiny non-empty engraving carrier owns its leading boundary.** The SDK fixed identity sentence and `# Engraving Here` now occupy separate blocks while preserving auto-memory containment, deterministic signature bytes, and the empty override opt-out.
|
|
17
|
+
- **The ACP provenance and v2 dispatch surfaces state their real boundaries.** First-user augment versus system carrier is rail-specific, and the `entwurf_v2` description fits the host tool-description cap.
|
|
18
|
+
|
|
19
|
+
### Verification
|
|
20
|
+
|
|
21
|
+
- The versioned release tree passed `pnpm check`, including **144/144** kill-qualified mutants across 10 lanes and `check-pack` at **309 files**.
|
|
22
|
+
- `LIVE=1 ./run.sh release-gate /tmp/entwurf-release-gate-0.13.1.LeOQDB --cut` passed: **MUST PASS=20 FAIL=0 SKIP=0**, **BEHAVIOR PASS=1 FAIL=0 SKIP=0**, `cut: OK`. Full log: `/tmp/entwurf-release-gate-0.13.1.LeOQDB/release-gate.log`.
|
|
23
|
+
- On-demand lifecycle acceptance `LIVE=1 ./run.sh smoke-acp-long-turn-live` passed on the final source set: a **733,635ms** turn exceeded the retired 600s cutoff with exactly one cold ACP bootstrap and no replay. Cortex is deliberately aggregate-excluded for this cut because the oracle has no Snowflake connection; its 0.13.0 thinkpad LIVE evidence is carry-forward, not a fresh 0.13.1 host certification.
|
|
24
|
+
- `check-pack-install` packed and installed `0.13.1` into a fresh consumer, proving the installed bridge boot/delivery and previous-generation lifecycle without touching the real data tree. The preserved exact candidate's checkout-invisible Docker consumer acceptance remains a `make` responsibility.
|
|
25
|
+
|
|
26
|
+
## 0.13.0 — 2026-07-30
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **Snowflake Cortex Code joins the ACP rail as the first non-claude backend** — the `cortexAdapter` contributed by hvkiefer (PR #40), landed together with the revisions the CP0 live audit of 2026-07-29 measured against Cortex Code v1.1.52 (`docs/acp-backend-rail.md` §11-8 records the ten defects D1–D10 and the agreed contract; the deltas are drift repair, not contributor error). As landed: the curated surface is the GLG-decided 4-row set (`cortex-auto`, `cortex-claude-opus-5`, `cortex-claude-sonnet-5`, `cortex-openai-gpt-5.4`) riding real pi-ai registry bases behind the reserved `cortex-` routing prefix; launch is `cortex acp serve` from PATH (+ `-c <connection>` via `entwurfProvider.cortexConnection` / `ENTWURF_ACP_CORTEX_CONNECTION`) with **no `-m` pin** — the model is enforced per turn through `session/set_config_option("model", <native id>)`, the same wire call as claude, so a curated id the running cortex no longer serves fails loud before the prompt. Containment is a **session-scoped dual-HOME overlay**: cortex's config/skill/hook surface is `homedir()`-anchored and `CORTEX_HOME` outranks `SNOWFLAKE_HOME`, so the adapter refuses an ambient `CORTEX_HOME` outright (empty string included), runs the child under an isolated HOME (global-scope leak measured to zero; explicit cwd project scope retained), passes through only the measured-minimum auth (`connections.toml`, optional `config.toml`, `cortex/cache/credential_cache` — symlink-through, never copied), authors `autoUpdate: false`, and — because cortex's ACP `newSession` ignores the wire `mcpServers` param — **projects** the envelope-enriched explicit `entwurfProvider.mcpServers` into the overlay-private `cortex/mcp.json`, restoring the real operator HOME on the `entwurf-bridge` entry alone so a cortex sibling sees the real garden (an isolated-HOME bridge measured an empty citizen roster); non-stdio entries fail loud before spawn. Cortex is system-prompt-carrier-less: the operator engraving rides the first-user augment. Coverage: the deterministic `check-acp-cortex` gate (in `pnpm check`) plus the `acp-cortex` mutant lane's twelve kill-qualified claims — ten on that gate, and two cross-gate: the production overlay call site passing `resolveSessionKey`'s authoritative value (`check-acp-session-reuse`) and the real compiled provider entry registering both adapters' curated rows (`check-acp-provider-surface`, so an entry that silently dropped every `cortex-` row can no longer go green) — and the on-demand CP2 live smoke `LIVE=1 ENTWURF_ACP_CORTEX_CONNECTION=<conn> ./run.sh smoke-acp-cortex-live` — a real cortex model turn delivering outbound `entwurf_v2` to a seeded peer as itself, plus overlay disk facts and process-group reclaim (an MCP-configured cortex child ignores stdin EOF) — deliberately outside the claude-only **aggregate** LIVE floor, so a host that runs no cortex cannot redden a claude release; that is a wiring decision, and a cut shipping cortex still owes a deliberate run of it.
|
|
31
|
+
- **A host that does not run Cortex is unaffected by this release.** The external `cortex` CLI is not an npm dependency, and neither package install nor provider registration looks for the executable: the four curated rows are enumerated deterministically from the compiled provider entry, and `cortex acp serve` is spawned only when a turn actually selects a `cortex-` model — so selecting one on a host without Cortex fails loud at that turn rather than degrading install or the rest of the provider. The deterministic `check-acp-cortex` gate runs on fake/injected seams and needs neither the CLI nor Snowflake auth; the aggregate release floor contains no Cortex LIVE step; and the dedicated smoke honest-skips without `LIVE=1`, without `cortex` on `PATH`, or without a connection on the adapter seam. Rows are deliberately **not** hidden by PATH detection — that would make the provider surface differ per host and dissolve the exact-six-row fence — so an explicit operator enable/disable control remains a separate future contract, not a silent behaviour of this cut.
|
|
32
|
+
- **The ACP ordering probe lands as a gated instrument, and the readiness question it exists to answer stays open.** The rail's open question — whether MCP tool availability precedes what `newSession` returns — had no observable signal, so the probe injects a controlled fixture startup delay and reads control + D1 + D2 paired runs off one shared NDJSON axis instead of reconstructing order from separate logs with drifting clocks. A raw client may stand in for the backend only while a gate holds it to the same calls, arguments, and order, so `check-probe-ordering` pins the sequence against `backend.ts` source, attributes every failure to its wire phase, drives the probe-mode fixture as a real child process, types the event log at its door, and replays the paired-verdict truth table through the pure classifier. The log's door is a gate too: the envelope belongs to the writer, `ts` derives from a single clock read, and per `(runId, pid)` writer the raw append order must have strictly increasing `seq` and a non-regressing clock — a JSON-valid line with an unknown marker, a broken sort axis, or a payload the classifier cannot judge takes the INVALIDATED path instead of moving a verdict. The runner now holds the child open past the turn until the marker lands, the child exits, or a deadline anchored on the fixture's own delay markers passes, and only a deadline close lets a missing marker read as evidence; every intervention reports ordering and callability as two axes so a settled comparison is not buried by an unsettled verdict, and each ordering value is named for the comparison it is (`prompt-request-ahead-of-wire` says we issued the request first, never that the server failed to wait). The delta-B name oracle cannot be the model, so that seam is a CLI shim at `CLAUDE_CODE_EXECUTABLE`: the consumer half (target preconditions by key presence, absolute/regular/executable/no-script-suffix assertions, path+sha256 roster pinning with a post-pair re-hash, snapshot channel doors, receive-axis single-prompt binding, structural-vs-reading severity split) and then the producer shim itself both land kill-qualified. **No readiness finding is claimed.** The first paired run under the door contract produced 57 events with zero malformed lines, so the parser is calibrated rather than merely strict, and rail §11-7-b carries the numbers — but the verdict is inconclusive, and an inconclusive verdict is not "nothing wrong". Artifacts predating the window protocol re-parse as INVALIDATED and remain forensic records only.
|
|
33
|
+
|
|
34
|
+
### Verification
|
|
35
|
+
|
|
36
|
+
- Pre-version landing HEAD `9f1c7dc9e1fa77103e29a6f1884af7759e1595eb` passed exact-SHA GitHub Actions run [30505001694](https://github.com/junghan0611/entwurf/actions/runs/30505001694): `check`, `install-surface`, and `artifact-consumer` all success. That run is also the third-party half of the optionality claim above, at the strength its sources actually carry: `.github/workflows/ci.yml` provisions only checkout, pnpm, and Node 24 — it installs no Cortex CLI and supplies no Snowflake auth — and the required Linux `artifact-consumer` job ran the candidate inside a clean `node:24-bookworm` container and passed. That is a workflow-configuration fact plus a passing consumer run; it is not a probe of the runner image's contents.
|
|
37
|
+
- The prepared tree passed an independent `pnpm check`, including `check-gate-qualification` at **111/111 committed mutants killed** (the `acp-cortex` lane contributing twelve). Then `LIVE=1 ./run.sh release-gate /tmp/entwurf-release-gate-0.13.0.drnRyR` completed all green: **MUST PASS=17 FAIL=0 SKIP=0** and **BEHAVIOR PASS=1 FAIL=0**, EXIT=0. Full log: `/tmp/entwurf-release-gate-0.13.0.drnRyR/release-gate.log`; per-step artifacts are preserved inside it.
|
|
38
|
+
- Cortex acceptance on the landing tree (2026-07-30, Linux/thinkpad, Cortex Code v1.1.52, connection on the adapter seam): the on-demand `smoke-acp-cortex-live` passed **23/23** — a deliberate rerun *after* the `resolveSessionKey` overlay-scope repair, so the shipped claim no longer rests on the earlier CP2 run's code. `check-pack-install` enumerated the **exact six curated rows (claude 2 + cortex 4)** out of the installed package's own model list, and `ENTWURF_REQUIRE_DOCKER=1 ./run.sh check-install-container` consumed candidate `sha256=63342aa8a144011dee86ebea8f0b778c7860e54dc0f1c710438983c679e8af87` on `node:24-bookworm` (`id=sha256:fcd0f74fb415c752…`, `repoDigest=node@sha256:5711a0d445a1af54…`).
|
|
39
|
+
- Cross-rail live round trips are **operator-session evidence, not a gate** (2026-07-29, same implementation set): a Cortex resident used the host pi citizen's garden id rather than inventing one — `agentId=entwurf/cortex-claude-sonnet-5`, `backend=pi`, reply envelope `origin=pi-session`, `replyable=true` — and exchanged real turns with native Claude Code (mailbox drain), pi native (control socket), and pi ACP Claude Sonnet (control socket). The record `20260729T204101-7aaa6f` remains on disk as corroboration.
|
|
40
|
+
- **Deferred to `make` as a release-blocking tag gate:** the preserved exact 0.13.0 candidate must be installed into a fresh temporary root and drive one cold `entwurf/cortex-claude-sonnet-5` turn from *those installed bytes* — unique nonce, exit 0, candidate SHA-256 unchanged before and after, resolved installed package root recorded. Until it runs, installed-artifact evidence and real-Cortex evidence have never met in one execution; a RED there stops the cut before the tag. Prepared-HEAD exact-SHA CI and preserved-candidate container acceptance remain deferred to `make` as usual.
|
|
41
|
+
|
|
7
42
|
## 0.12.10 — 2026-07-27
|
|
8
43
|
|
|
9
44
|
### Changed
|
package/CONTRIBUTING.md
CHANGED
|
@@ -4,7 +4,9 @@ This is a daily-driver bridge. Correctness beats feature breadth. Read this befo
|
|
|
4
4
|
|
|
5
5
|
## What this repo is
|
|
6
6
|
|
|
7
|
-
`entwurf` is a **garden-citizen dispatch bridge** — entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + a
|
|
7
|
+
`entwurf` is a **garden-citizen dispatch bridge** — entwurf-core (v2 dispatch) + a meta-bridge + a pi adapter + an **ACP plugin on a two-backend adapter rail** — that lets already-running harnesses address one another by garden id; pi is one adapter, not the subject. The ACP plugin borrows the backend's identity (system prompt preset, model behavior, tool implementations) and shapes the *operating surface* — tools, MCP, skills, permissions — to match pi's own policy **wherever that backend exposes a knob for it**. Where it does not, the plugin does not fake one: a cortex session keeps its own native tool surface and receives MCP through an overlay projection, so "shaped to pi's policy" is a Claude-strength claim, not a universal one. Claude is the reference ACP backend and Snowflake Cortex Code is the second (landed 0.13.0, `cortex-` prefixed ids — [docs/acp-backend-rail.md](./docs/acp-backend-rail.md#cortex-code-audit-d1d10)); Codex has native delivery-probe evidence but no managed citizen lane, and Gemini is not a shipped backend. That is the entire scope.
|
|
8
|
+
|
|
9
|
+
**How a backend joins the rail** (the shape a PR must take): one adapter object in `pi-extensions/lib/acp/backend-adapter.ts` + its own curated rows/overlay modules + its own `check-acp-*` gate and mutant lane. Backend-specific *behavior* must stay behind the adapter, and backend-specific settings ride the opaque `adapterSettings` seam rather than growing the common config. That is not a ban on ever touching the common layer (`backend.ts`'s turn loop, `acp-client.ts`, `event-mapper.ts`, `session-store.ts`, `config.ts`) — cortex's landing did change `backend.ts` to pass the authoritative session key through the generic `ensureOverlay` seam. The rule is narrower and stricter: a common-layer change must be **backend-invariant** (it reads no backend name and branches on no backend) and **separately gated**. A common file that grows an `if (backend === …)` is the thing to reject.
|
|
8
10
|
|
|
9
11
|
If a change moves the bridge toward "second harness" — prompt reconstruction, transcript hydration, ambient discovery, silent fallback — it does not belong here.
|
|
10
12
|
|
|
@@ -16,7 +18,7 @@ These are enforced by code, gates, and review. Do not weaken them in a PR; if yo
|
|
|
16
18
|
2. **Session persistence**: only `pi:<sessionId>` is persisted. `cwd:<cwd>` is never persisted.
|
|
17
19
|
3. **MCP injection**: only via `entwurfProvider.mcpServers`. No ambient `~/.mcp.json` scanning, no `~/.claude/settings.json` MCP inheritance.
|
|
18
20
|
4. **Operating surface, not config inheritance**: the user's filesystem Claude Code config (`~/.claude/settings.json` hooks, env, plugins, `permissions.defaultMode`) is intentionally *not* inherited. Skills come from `skillPlugins`, permissions from `permissionAllow`, deferred-tool surface from `disallowedTools`. The `CLAUDE_CONFIG_DIR` overlay enforces this even where the SDK reads filesystem independently of `settingSources`.
|
|
19
|
-
5. **Backend-specific knobs stay explicit and namespaced**: Codex/Gemini-era ACP knobs are not
|
|
21
|
+
5. **Backend-specific knobs stay explicit and namespaced**: retired Codex/Gemini-era ACP knobs are not carried on the current path. A backend that needs its own knob uses the `ENTWURF_ACP_*` namespace, and invalid values must throw, never fall back — cortex followed this with `ENTWURF_ACP_CORTEX_CONNECTION` (the renamed `PI_SHELL_ACP*` legacy var), and its settings key rides `adapterSettings`, not the common config.
|
|
20
22
|
6. **Bridge does not implement compaction**: When a backend compacts natively, the pi session and mapping survive that. Pi-side JSONL compaction must not be presented as backend-transcript reduction, and backend-specific compaction controls belong to the backend's own native interface. Legacy `PI_SHELL_ACP_*` compaction knobs must not reappear.
|
|
21
23
|
7. **Backend coverage honesty**: changes to operating surface, session lifecycle, or persistence must state which shipped/probed backend surfaces they cover. A claim that silently drops a covered backend is a regression; if one backend is genuinely not covered, record that carve-out explicitly.
|
|
22
24
|
8. **This bridge is not a second harness**: no prompt reconstruction, no transcript hydration, no tool result ledger, no Claude Code emulation.
|