@junghanacs/entwurf 0.12.9 → 0.12.10
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 +134 -248
- package/BASELINE.md +1 -1
- package/CHANGELOG.md +19 -0
- package/DELIVERY.md +4 -3
- package/README.md +26 -13
- package/VERIFY.md +3 -2
- package/demo/demo.sh +7 -1
- package/docs/setup-clean-host.md +10 -4
- package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +159 -66
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/overlay.js +5 -3
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-core.js +26 -9
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-deliverability.js +10 -6
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-fact-provider.js +15 -17
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-facts.js +13 -13
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-resume-args.js +31 -41
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-self-address.js +8 -9
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-contract.js +32 -25
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-decider.js +4 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-lock.js +5 -4
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-production.js +9 -11
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-v2-spawn-production.js +3 -1
- package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +17 -20
- package/mcp/entwurf-bridge/src/index.ts +190 -82
- package/package.json +5 -3
- package/pi-extensions/entwurf-control.ts +69 -27
- package/pi-extensions/lib/acp/overlay.ts +5 -3
- package/pi-extensions/lib/entwurf-core.ts +26 -9
- package/pi-extensions/lib/entwurf-deliverability.ts +10 -6
- package/pi-extensions/lib/entwurf-fact-provider.ts +15 -17
- package/pi-extensions/lib/entwurf-facts.ts +13 -13
- package/pi-extensions/lib/entwurf-resume-args.ts +40 -46
- package/pi-extensions/lib/entwurf-self-address.ts +8 -9
- package/pi-extensions/lib/entwurf-v2-contract-schema.ts +7 -2
- package/pi-extensions/lib/entwurf-v2-contract.ts +32 -25
- package/pi-extensions/lib/entwurf-v2-decider.ts +8 -8
- package/pi-extensions/lib/entwurf-v2-lock.ts +5 -4
- package/pi-extensions/lib/entwurf-v2-production.ts +14 -11
- package/pi-extensions/lib/entwurf-v2-spawn-production.ts +3 -1
- package/pi-extensions/lib/meta-session.ts +17 -20
- package/run.sh +48 -41
- package/scripts/agy-bridge-config.py +249 -49
- package/scripts/agy-bridge.sh +59 -14
- package/scripts/check-acp-carrier-augment.ts +34 -2
- package/scripts/check-acp-sdk-surface.ts +22 -11
- package/scripts/check-agy-permission-matrix.py +655 -0
- package/scripts/check-entwurf-deliverability.ts +9 -6
- package/scripts/check-entwurf-fact-provider.ts +7 -7
- package/scripts/check-entwurf-facts.ts +12 -12
- package/scripts/check-entwurf-resume-args.ts +22 -60
- package/scripts/check-entwurf-self-address.ts +187 -4
- package/scripts/check-entwurf-v2-contract.ts +2 -2
- package/scripts/check-entwurf-v2-production.ts +5 -5
- package/scripts/check-entwurf-v2-spawn-production.ts +6 -2
- package/scripts/check-entwurf-v2-surface.ts +327 -14
- package/scripts/check-gate-qualification.ts +785 -0
- package/scripts/check-meta-identity-consumers.ts +1 -1
- package/scripts/check-shell-quote.ts +2 -1
- package/scripts/lib/mutation-qualify.ts +794 -0
- package/scripts/mutants/acp-augment.json +30 -0
- package/scripts/mutants/agy-permission.json +144 -0
- package/scripts/mutants/meta-identity.json +17 -0
- package/scripts/mutants/self-address.json +59 -0
- package/scripts/mutants/v2-surface.json +87 -0
- package/scripts/smoke-acp-raw-turn-live.ts +1 -1
- package/scripts/smoke-acp-v2-send-live.ts +33 -18
- package/scripts/smoke-agy-install-state.sh +205 -20
- package/scripts/smoke-entwurf-v2-matrix-live.ts +3 -2
- package/pi-extensions/lib/entwurf-mailbox-guard.ts +0 -100
- package/scripts/check-entwurf-mailbox-guard.ts +0 -266
package/AGENTS.md
CHANGED
|
@@ -1,285 +1,171 @@
|
|
|
1
1
|
# AGENTS.md — Maintainer Guidelines for entwurf
|
|
2
2
|
|
|
3
|
-
For agents that own this repo: invariant principles
|
|
4
|
-
|
|
5
|
-
> **Direction (read first).** This repo is the **entwurf capability package**:
|
|
6
|
-
> a v2 garden-citizen dispatch substrate (entwurf-core) + a meta-bridge + an
|
|
7
|
-
> ACP plugin + the pi adapter that hosts it today. v1 entwurf verbs are done
|
|
8
|
-
> and gone; v2 is the spine. ACP is **not** the project's center — it is one
|
|
9
|
-
> **plugin** that enters as a provider/model on a host `--entwurf-control`
|
|
10
|
-
> pi session — which is *already* a v2 socket-citizen — rather than minting
|
|
11
|
-
> citizens of its own (#38: *"ACP is a plugin, not the boundary."*).
|
|
12
|
-
> Package/repo/runtime identity is now `entwurf`; pi remains an
|
|
13
|
-
> adapter/runtime contract, not the center. The deferred #38 coordinate is a
|
|
14
|
-
> later physical extraction of entwurf-core into a separate repo, not this
|
|
15
|
-
> rename. Fresh sibling minting (the old v1 `entwurf` verb) stays deferred —
|
|
16
|
-
> see the branch NEXT.
|
|
3
|
+
For agents that own this repo: invariant principles and reproducible verification, not release-story archaeology.
|
|
17
4
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
`entwurf`를 만질 때 먼저 이 형상을 붙든다.
|
|
21
|
-
이 저장소는 스위스 아미 나이프가 아니다. 두 번째 하네스도 아니다.
|
|
22
|
-
이것은 **담금질된 드라이버 한 자루**다. 작고, 명시적이고, 자기가 맡은 접점에서만 강해야 한다.
|
|
23
|
-
|
|
24
|
-
영문 원칙만 읽으면 이것이 스펙처럼 보일 수 있다. 여기서는 그렇게 읽지 마라.
|
|
25
|
-
이 섹션은 기능 목록이 아니라 **판단의 중심축**이다.
|
|
26
|
-
|
|
27
|
-
### 먼저 붙들 정체성
|
|
28
|
-
|
|
29
|
-
- **entwurf가 주어이고 pi는 한 adapter다.** pi는 지금 이 repo가 가장 깊게 붙어 있는 하네스지만 4번째 하네스일 뿐이다. 이 repo는 pi의 세션 모델, transcript, UI, tool semantics와 경쟁하지 않는다.
|
|
30
|
-
- **다른 하네스의 세션은 형제다.** Claude Code, Codex, Antigravity는 학교가 달라도 모두 frontier 친구들이다. native bridge는 증명된 lifecycle/transport가 있는 세션만 garden id로 호명 가능한 citizen으로 등록할 뿐, 누구를 다른 누구로 위장시키지 않는다.
|
|
31
|
-
- **표면은 달라도 능력의 존엄은 낮추지 않는다.** 어떤 backend에서 `mcp__...`가 직접 보이지 않는다고 해서, 곧바로 그 backend를 "못하는 존재"로 취급하지 마라. 먼저 capability를 보고, 그 capability가 어떤 surface로 열리는지 확인하라.
|
|
32
|
-
- **substrate는 결정적 dispatch만 맡는다.** target liveness를 fact로 읽고, intent와 곱해 transport를 고른다. 그 이상 마술을 부리면 안 된다.
|
|
33
|
-
- **명시는 주변기류보다 강하다.** 숨겨진 transcript hydration, ambient MCP scanning, invisible tool claims, giant magical system prompt, 근거 없는 서사를 만들지 마라.
|
|
34
|
-
- **하네스의 도구 표면을 좁히는 것은 결핍이 아니라 규율이다.** entwurf가 backend를 몰 때(ACP Claude · pi-native 분신) 서브에이전트도 투두 도구도 없이 좁은 tool surface를 yolo로 돈다(ACP backend는 격리된 overlay 안에서) — pi에서 배운 **힣의 드라이버**다. backend가 못해서가 아니라, 한 자루 드라이버가 두 번째 오케스트레이터로 번지지 않게 하는 강제다. 이걸 강제해야 "힣의 드라이버를 쓴다"고 말할 수 있다. (backlog 형태는 `ROADMAP.md` tool narrowing.)
|
|
35
|
-
- **entwurf는 부속품이 아니라 분신을 연다.** spawn-bg resume된 세션은 runtime-isolated peer다. worker처럼 다루거나 권한 경계를 흐리지 마라.
|
|
36
|
-
- **증거가 말을 훈육한다.** README / AGENTS / CHANGELOG / VERIFY / BASELINE / runtime smoke가 받쳐주지 않으면, 작업을 중지하고 사용자에게 질문하라!
|
|
37
|
-
|
|
38
|
-
### 이 섹션을 읽는 올바른 방식
|
|
39
|
-
|
|
40
|
-
이 문단의 목적은 에이전트가 다음 질문을 **스스로** 하게 만드는 것이다.
|
|
41
|
-
|
|
42
|
-
- 나는 지금 tool 이름을 보고 있는가, 아니면 capability를 보고 있는가?
|
|
43
|
-
- 나는 backend의 비대칭을 정직하게 기록하고 있는가, 아니면 그것을 핑계로 형제성을 포기하고 있는가?
|
|
44
|
-
- 나는 사용자가 묻지 않아도 될 것을 되묻고 있는가?
|
|
45
|
-
- 나는 지금 두 번째 하네스를 만들고 있는가, 아니면 드라이버 한 자루를 더 단단하게 만들고 있는가?
|
|
46
|
-
|
|
47
|
-
### 금지할 오독
|
|
5
|
+
> **Direction.** This repo is the **entwurf capability package**: a v2 garden-citizen dispatch substrate, native-harness bridges, an ACP plugin, and the pi adapter that hosts that plugin today. `entwurf` is the subject; pi is one harness adapter. ACP is a plugin, not the boundary (#38). V1 verbs are gone. V2 addresses existing citizens; fresh sibling creation remains deferred. Current work and ordering live in [NEXT.md](./NEXT.md).
|
|
48
6
|
|
|
49
|
-
|
|
50
|
-
- surface 차이를 capability 포기로 번역하는 것
|
|
51
|
-
- 문서에 적힌 asymmetry를 면책조항처럼 사용하는 것
|
|
52
|
-
- `entwurf`를 하네스 런타임이나 범용 AI 작업실로 설명하는 것 — pi가 하네스 중 하나이고, 이 repo는 garden-citizen dispatch capability다
|
|
53
|
-
- MCP를 자동 맥락 검색이나 ambient tool scanning처럼 설명하는 것 — explicit injection만 허용된다
|
|
54
|
-
- `entwurf_v2`를 "새 분신을 만드는 도구"로 설명하는 것 — v2의 4 transport(control-socket / spawn-bg resume / meta-mailbox / native-push)는 전부 **기존** garden citizen 대상이다. fresh sibling 생성은 별개 능력이다
|
|
55
|
-
- 사용자가 이미 철학과 방향을 준 문제를 다시 사용자에게 되묻는 것
|
|
56
|
-
|
|
57
|
-
릴리즈 이야기와 개별 기능은 주변을 돈다.
|
|
58
|
-
중심은 언제나 이것이다: **thin substrate / explicit MCP / sibling-based entwurf / deterministic dispatch / observability / evidence-first language / capability dignity across sibling sessions**.
|
|
59
|
-
|
|
60
|
-
## What This Repo Is
|
|
61
|
-
|
|
62
|
-
An **entwurf garden-citizen dispatch substrate** + a **meta-bridge** + an **ACP plugin** + a **pi adapter**. Pi stays a harness/runtime, not the project center; every addressed session keeps its own identity.
|
|
7
|
+
## North Star — One Forged Screwdriver
|
|
63
8
|
|
|
64
|
-
|
|
65
|
-
- **v2 dispatch (`entwurf_v2`)**: one verb that delivers to / wakes an *already-identified* garden citizen. A pure decider reads transport-specific liveness facts and picks from a frozen table keyed on **target state × intent**: live pi + fire-and-forget → **control-socket**; dormant pi + owned-outcome → **spawn-bg resume**; active self-fetch + fire-and-forget → **meta-mailbox**; probe-alive native-push + fire-and-forget → **native-push**. Every complementary pair is an honest reject. It does **not** mint new siblings.
|
|
66
|
-
- **ACP plugin** (one pi-adapter ingress): registers the package provider `entwurf` as a pi session provider/model and drives the chosen ACP backend (Claude first; vendor/governed CLIs like Cortex next) under an isolated config overlay. It owns the backend process, the overlay, and the per-backend ACP dialect — **not** socket-citizenship. The host `--entwurf-control` pi session that selected the ACP model is *already* a v2 socket-citizen; the plugin does **not** mint a socket / peers / citizen layer. It is not the substrate and not a second harness. v1 entwurf verbs (`entwurf` / `entwurf_resume` / `entwurf_send`) are gone for good; the ACP plugin is a fresh build on the v2 core (0.11.0's `acp-bridge.ts` is a behavior oracle, not architecture to re-center). See §ACP Plugin Boundary.
|
|
9
|
+
`entwurf`는 스위스 아미 나이프나 두 번째 하네스가 아니다. 이것은 **담금질된 드라이버 한 자루**다: 작고, 명시적이고, 맡은 접점에서만 강해야 한다.
|
|
67
10
|
|
|
68
|
-
|
|
11
|
+
- **entwurf가 주어이고 pi는 한 adapter다.** pi는 가장 깊게 붙은 하네스지만 다른 하네스보다 높은 정체성 계층이 아니다.
|
|
12
|
+
- **다른 하네스의 세션은 형제다.** Claude Code, Codex, Antigravity, pi는 각자의 transcript/auth/runtime을 소유한다. 증명된 lifecycle과 transport가 있을 때 같은 garden address space의 citizen이 된다.
|
|
13
|
+
- **능력을 surface 이름으로 재단하지 않는다.** 도구 이름이나 transport 비대칭은 capability 차이이지 존재의 등급이 아니다.
|
|
14
|
+
- **substrate는 결정적 dispatch만 맡는다.** record에서 identity를 읽고, rail별 liveness와 caller intent로 transport를 고른다. 숨은 hydration, ambient MCP scanning, 근거 없는 tool claim을 만들지 않는다.
|
|
15
|
+
- **좁은 tool surface는 규율이다.** entwurf가 backend를 몰 때 sub-agent/todo 없이 한 자루 드라이버로 움직인다. 두 번째 orchestrator로 자라지 않게 한다.
|
|
16
|
+
- **entwurf는 부속품이 아니라 분신을 연다.** resumed/spawned session은 runtime-isolated peer이지 disposable worker가 아니다.
|
|
17
|
+
- **증거가 말을 훈육한다.** README, source, gates, VERIFY, BASELINE이 받치지 않는 강한 주장은 멈춘다.
|
|
69
18
|
|
|
70
|
-
|
|
19
|
+
판단할 때 묻는다:
|
|
71
20
|
|
|
72
|
-
|
|
21
|
+
1. tool 이름을 보는가, capability를 보는가?
|
|
22
|
+
2. backend 비대칭을 정직하게 기록하는가, 형제성을 포기하는 핑계로 쓰는가?
|
|
23
|
+
3. 두 번째 하네스를 만드는가, 드라이버 한 자루를 단단하게 만드는가?
|
|
24
|
+
4. 이미 주어진 방향을 되묻는가, 실행 가능한 다음 증거를 만드는가?
|
|
73
25
|
|
|
74
|
-
|
|
26
|
+
## Architecture
|
|
75
27
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
78
|
-
-
|
|
28
|
+
- **entwurf-core (v2)** owns garden-id addressing, peer facts, liveness interfaces, dispatch decisions, rail choice, and delivery evidence.
|
|
29
|
+
- **Record authority** owns citizen identity. Every addressable pi, Claude Code, Antigravity, or future Codex citizen uses the same V3 `MetaIdentity` schema. `backend` selects capability/rail behavior; it does not create an identity hierarchy.
|
|
30
|
+
- **pi adapter** attaches a pi session to a record at `session_start`, hosts the record-keyed control socket, and exposes the native pi tool surface.
|
|
31
|
+
- **Native bridges** register already-running native sessions without taking over their transcript or auth: Claude Code is mailbox/self-fetch; Antigravity is probe-backed native-push; Codex has probe evidence but no shipped managed citizen lane.
|
|
32
|
+
- **ACP plugin** registers provider `entwurf` inside a pi host session and drives a backend under an isolated overlay. The host pi session is already a record-backed socket citizen; the plugin does not mint another citizen/socket/peer layer.
|
|
33
|
+
- **One delivery verb:** `entwurf_v2` addresses an existing garden id. Current routes are live control-socket send, dormant spawn-bg resume, active self-fetch mailbox enqueue, and probe-alive native-push. Complementary state×intent pairs reject honestly. Fresh creation is a separate future capability.
|
|
79
34
|
|
|
80
35
|
## Hard Rules
|
|
81
36
|
|
|
82
|
-
1. **One surface name, hard
|
|
83
|
-
2. **
|
|
84
|
-
3. **
|
|
85
|
-
4. **
|
|
86
|
-
5. **
|
|
87
|
-
6. **
|
|
88
|
-
7. **
|
|
89
|
-
8. **
|
|
90
|
-
9. **
|
|
91
|
-
10. **
|
|
92
|
-
11. **
|
|
93
|
-
12. **
|
|
94
|
-
13. **
|
|
37
|
+
1. **One surface name, hard cut.** Runtime/provider/routing identity is `entwurf`. No permanent aliases, legacy readers, or hidden dual routing. One-shot migration or documented break only.
|
|
38
|
+
2. **The record is the sole garden address authority.** A socket, env var, marker, filename, model id, or transcript id is never an independent address axis. `PI_SESSION_ID` is only a child-process carrier for the garden id already established by pi's record birth.
|
|
39
|
+
3. **All citizens share one identity contract; rails differ by capability.** The control-socket liveness domain currently contains backend `pi`; self-fetch and native-push have different predicates. Branch on capability/domain, not on a privileged notion of “pi citizen.”
|
|
40
|
+
4. **Dispatch is computed from live facts.** Never store liveness. Never infer send/resume from session type before resolving the target and probing its rail.
|
|
41
|
+
5. **Rejects are real.** Wrong intent, dead/drifted identity, undeliverable mailbox, ambiguous address, or indeterminate probe returns a reject and mutates nothing. No cosmetic success or silent fallback.
|
|
42
|
+
6. **MCP is explicit.** Only explicit `mcpServers` wiring. No ambient `~/.mcp.json` scan or automatic retrieval.
|
|
43
|
+
7. **Meta-record store contract is one contract.** Record body is authority; filename must agree with the body; every active entry is a regular non-symlink file readable by the live V3 schema; `nativeSessionId` ownership is unique. Identity writers and doctor certify the whole active store before writing. Address-bearing reads use `readAddressableMetaIdentity`; targeted relay reads keep the documented per-entry contract. `readStoreRecordFile`/`O_NOFOLLOW` and the lstat policy layer are both load-bearing—do not merge or bypass them. No legacy reader/migrator: quiesce and run `entwurf meta-bridge-fresh-cut` when the generation is unreadable. Source and gates: `meta-session.ts`, `check-meta-*`, `check-fresh-cut-gate`.
|
|
44
|
+
8. **GC reclaims process resources, never memory/data.** Records and transcripts are preserved or archived; they are not casually deleted.
|
|
45
|
+
9. **This is not a second harness.** No prompt reconstruction, transcript hydration, tool-result ledger, credential mediation, or harness emulation. Each backend owns auth and transcript state.
|
|
46
|
+
10. **Native-push is its own rail.** It is not a mailbox or pi socket in disguise. Antigravity replyability is record-backed plus probe-alive; no receiver marker, watch state, or resume authority is invented for it.
|
|
47
|
+
11. **Package proof must model a consumer.** Operator entrypoints reach compiled JS when installed; `run_ts` is the single TS crossing. Keep `check-install-surface`, `check-pack-install`, and the checkout-invisible `check-install-container` distinct. A green clone is not a green tarball or consumer.
|
|
48
|
+
12. **Offline verification never rewires the operator.** Sandbox `HOME`, `PI_CODING_AGENT_DIR`, and every writable `XDG_*` root. LIVE gates alone may touch the real host and must say so. Keep static tripwires and dynamic outer self-fences; neither substitutes for the other.
|
|
49
|
+
13. **Doctors report runtime truth and ownership truth separately.** Runtime coverage does not prove entwurf owns the configuration; broken ownership does not erase visibly working runtime configuration. Final verdict remains red when either required axis fails.
|
|
50
|
+
14. **Native hook ownership is structural.** Claude hooks use the shipped exec-form launcher and provenance token; marker writers/readers share `isPlausibleOwnerPid`; no shell-form fallback, ancestry guess, or retired pid carrier. entwurf requires Claude Code `>=2.1.217` and enforces that floor itself because upstream gives no fail-loud — an older Claude validates the exec manifest, then drops `args` at runtime and reports success. The number is derived from `package.json` `entwurf.claudeCodeFloor`, never retyped as a second source. Currently certified axis is Linux desktop/workstation. Source/gates: `hook-launch.sh`, `meta-session.ts`, `check-hook-launch-topology`, `check-claude-floor-coherence`, `check-meta-doctor-oracle`.
|
|
51
|
+
15. **Crash, don't warn.** Bad config/path/model/store state throws. Empty catches are only for bounded environment probing; operator diagnostics go to stderr.
|
|
52
|
+
|
|
53
|
+
Detailed incident histories belong in CHANGELOG/issues/BASELINE and source-adjacent comments, not in this prompt. When a concise rule and old archaeology disagree, verify source + gate and repair the stale prose.
|
|
95
54
|
|
|
96
55
|
## ACP Plugin Boundary
|
|
97
56
|
|
|
98
|
-
`entwurf-core` (the v2 substrate) is the center; **ACP is one plugin**, never the boundary (#38). Plugins supply read-only facts the core already asks for; they do not become the core, a memory layer, or a second harness (#39).
|
|
99
|
-
|
|
100
57
|
| Layer | Owns |
|
|
101
58
|
|---|---|
|
|
102
|
-
| **entwurf-core
|
|
103
|
-
| **ACP plugin** |
|
|
104
|
-
| **ACP plugin
|
|
105
|
-
|
|
106
|
-
- **Sibling equality is a citizen-level property, not a rail-level one.** Every sibling is addressable (peers-visible, garden-id-addressed, `entwurf_v2`-reachable, replyable when its rail proves a return path). The *rail* differs by lifecycle: an ACP-backed pi resident is a **socket-citizen**; Claude Code is a **mailbox-citizen**; agy is a **native-push citizen**. Missing a mailbox on socket/native-push rails is right-sizing, not discrimination.
|
|
107
|
-
- **Durable memory is the authored common record** (`~/org`, botlog, agenda, Denote, andenken). entwurf lets peers move across that record layer; it never replaces it.
|
|
108
|
-
- **ACP enters as a model/provider, not a socket layer.** The ACP plugin registers as a pi session's provider/model and spawns the backend under an overlay; **socket-citizenship is supplied by the host `--entwurf-control` pi session**, not minted by the plugin. The plugin never builds a new socket registry, peers layer, or citizen protocol — over-designing one is the failure mode to avoid (`socket-discovery` is model-agnostic, so an ACP-model session is already a citizen).
|
|
109
|
-
|
|
110
|
-
### Operating boundaries (trust invariants — survive any re-implementation, #15)
|
|
111
|
-
|
|
112
|
-
These claims must stay true on every install surface; they are the first thing a re-implementation silently drops, so they are pinned here:
|
|
113
|
-
|
|
114
|
-
- `entwurf` does **not** provide, resell, or bypass Claude/vendor credentials, tokens, or subscription access. It connects only to the operator's **existing local authenticated backend** through an explicit plugin boundary.
|
|
115
|
-
- No auth bypass, no subscription sharing, no hidden transcript restoration.
|
|
116
|
-
- Expert escape hatches are **explicit and documented**, never accidental backdoors.
|
|
117
|
-
- The plugin **fails loud / fails closed** when an invariant is broken.
|
|
59
|
+
| **entwurf-core** | identity/fact interfaces · dispatch table · delivery evidence · rail choice |
|
|
60
|
+
| **ACP plugin** | backend process lifecycle · isolated overlay · tool narrowing · per-backend ACP dialect · turn evidence |
|
|
61
|
+
| **ACP plugin does not own** | citizen registration · socket registry · peer protocol · memory DB · planner/orchestrator · auth |
|
|
118
62
|
|
|
119
|
-
|
|
63
|
+
- One `entwurf` provider, model-id routing, adapter resolved once at turn entry. Backend-specific settings remain opaque behind `adapterSettings`.
|
|
64
|
+
- The common turn sequence stays backend-invariant: spawn → initialize → newSession → enforceModel → prompt → event map.
|
|
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
|
+
- A backend may have no carrier or use launch-time model pinning; those asymmetries stay inside its adapter.
|
|
67
|
+
- Claude is the reference adapter. Cortex enters only after the current rail conditions in `docs/acp-backend-rail.md` and `NEXT.md` are satisfied.
|
|
68
|
+
- entwurf never supplies, copies, proxies, decrypts, or bypasses vendor credentials/subscriptions. It uses the operator's existing local authenticated backend.
|
|
120
69
|
|
|
121
|
-
|
|
70
|
+
## Citizen Identity and Dispatch
|
|
122
71
|
|
|
123
|
-
|
|
72
|
+
### One record axis
|
|
124
73
|
|
|
125
|
-
|
|
126
|
-
pnpm typecheck # 3-config tsc fence (root + mcp + scripts)
|
|
127
|
-
pnpm check # full static floor: lint + typecheck + every check-*/smoke-* below
|
|
128
|
-
./run.sh check-entwurf-v2-matrix # the decider's state×intent table, read as an SSOT (REAL decideDispatch)
|
|
129
|
-
./run.sh check-entwurf-v2-decider # + -contract / -lock / -release / -send / -send-fallback / -mailbox / -runner / -production / -surface / -spawn / -spawn-production
|
|
130
|
-
./run.sh check-meta-session # + -v3-record / -mailbox-state-write / -receiver-marker / -capability-source / -identity-consumers / -listing (one live schema; no legacy readers — see check-fresh-cut-gate for the generation boundary)
|
|
131
|
-
./run.sh check-meta-doctor-oracle # detection power of the release oracle: healthy fixture reaches `doctor: PASS`, 21 planted defects each turn it FAIL naming their own cause
|
|
132
|
-
./run.sh check-native-push-adapter # agy probe/route leaf; separate from pi socket and mailbox liveness
|
|
133
|
-
./run.sh check-agy-sender-identity # record-backed pid/start-key sender resolution + ambiguity refusal
|
|
134
|
-
./run.sh smoke-agy-install-state # MCP + exact permission ownership + honest inverse (140)
|
|
135
|
-
./run.sh smoke-agy-statusline-state # ambient garden identity install surface (69)
|
|
136
|
-
./run.sh smoke-agy-hooks-state # PreInvocation birth/sender hook install surface (44)
|
|
137
|
-
./run.sh check-entwurf-bridge-boot # the MCP entwurf-bridge stands up + exposes the v2/native-register tool set
|
|
138
|
-
./run.sh check-install-surface # structural strip-types fence: run_ts is the only crossing, every operator command has a compiled twin, offline smokes never write the real $HOME
|
|
139
|
-
./run.sh check-install-container # Linux artifact CONSUMER (#51 C, own CI job): one candidate .tgz, read-only, into a checkout-invisible node:<engines-major> cell — non-root `npm install -g`, PATH shim, frozen package root, MCP tools/list, install-meta-bridge under a path+sha256 byte-fence, strict doctor. Default pack-once temp; ENTWURF_CANDIDATE_TGZ consumes an exact preserved file without re-pack. SKIP without Docker; ENTWURF_REQUIRE_DOCKER=1 makes that RED
|
|
140
|
-
./run.sh check-bridge /path/to/project # entwurf-bridge direct MCP smoke (tools/list + protocol/negative-path)
|
|
141
|
-
./run.sh check-auth-boundary # ACP plugin no-auth sentinel present + no legacy-ENV apiKey literal (trust invariant, code-level)
|
|
142
|
-
./run.sh check-acp-provider-surface # provider registers curated Claude anchor + streamSimple wired to the real streamShellAcp backend
|
|
143
|
-
# The legacy v1 ACP gates (sentinel / session-messaging / xt-tool-surface) and the
|
|
144
|
-
# v1-only meta smokes (smoke-meta-mailbox / smoke-meta-sender-identity, both calling
|
|
145
|
-
# the gone entwurf_send tool) were REMOVED in the 0.12 cutover (2026-06-27). Any
|
|
146
|
-
# re-test of those axes belongs on the entwurf_v2 surface as a fresh gate.
|
|
147
|
-
```
|
|
74
|
+
A `--entwurf-control` pi session is a citizen for the same reason a native bridge session is: it has a V3 meta-record.
|
|
148
75
|
|
|
149
|
-
|
|
76
|
+
- pi owns its native session id, filename, transcript, name, `/new`, `/fork`, `/clone`, and `/resume` lifecycle.
|
|
77
|
+
- `birthPiCitizen` upserts `(backend:"pi", nativeSessionId)` and receives the stable `gardenId` from the record.
|
|
78
|
+
- The control socket is `~/.pi/entwurf-control/<gardenId>.sock`; a record-less socket is a diagnostic, never a citizen.
|
|
79
|
+
- `PI_SESSION_ID` and `PI_AGENT_ID` propagate the record-established identity to child MCP processes. They are carriers, not a second authority.
|
|
80
|
+
- If record birth fails, no socket starts and no `PI_SESSION_ID` is exported.
|
|
81
|
+
- Reopening the same pi native session attaches to the same record; in-process replacement creates/attaches the replacement's own record.
|
|
82
|
+
- Dormant resume requires record existence, transcript-header ↔ `record.nativeSessionId` integrity, and model preservation.
|
|
150
83
|
|
|
151
|
-
|
|
152
|
-
LIVE=1 ./run.sh release-gate /path/to/scratch # two-tier: MUST (release-blocking, owns exit code) + BEHAVIOR (advisory)
|
|
153
|
-
LIVE=1 ./run.sh smoke-acp-socket-citizen-live # S1: a real ACP-model --entwurf-control resident is a first-class socket-citizen (peers + get_info), turn-free (no backend, no stub fire)
|
|
154
|
-
LIVE=1 AGY_CONVERSATION_ID=<id> ./run.sh smoke-agy-native-push-live # real agy probe/register/direct-inject evidence; conversation-id gated, outside aggregate release-gate
|
|
155
|
-
```
|
|
84
|
+
### Capability domains, not rank
|
|
156
85
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
Uses `entwurf` instead of `delegate` to avoid ecosystem collisions. spawn-bg resume creates a sibling, not a worker.
|
|
166
|
-
|
|
167
|
-
- **Surface** — MCP `entwurf-bridge`: `entwurf_v2`, `entwurf_self`, `entwurf_peers`, `entwurf_inbox_read`, `entwurf_register_native` (explicit/manual fallback for an already-running native conversation). pi-native (`pi-extensions/entwurf-control.ts`): `entwurf_v2`, `entwurf_peers` tools (#50 C4 removed the socket-scan `/entwurf-sessions` command). The v1 `entwurf` / `entwurf_resume` / `entwurf_send` tools and the `/entwurf` / `/entwurf-send` / `/entwurf-status` commands are **removed**.
|
|
168
|
-
- **`entwurf_v2` is the one delivery verb.** Given a garden id, it classifies the target (live pi vs. dormant pi vs. mailbox meta-session vs. native-push citizen — a bare garden id does not reveal this) and routes correctly. It does **not** mint a fresh sibling: spawn-bg resumes an *already-identified* citizen, while native-register binds an *already-running* conversation. Fresh creation was the v1 `entwurf` verb and remains deferred.
|
|
169
|
-
- **`entwurf_peers`** is a read-only fact surface (liveness / capability / identity / cwd-history). Do not bake verb-routing (`resumable`/`sendable`) into the fact layer; routing is the decider's job.
|
|
170
|
-
- **`entwurf_self`** returns the authoritative identity envelope (pi-session env, or a trusted meta-session sender marker) and is identity-required. Its socketPath/mailboxPath lines are the CALLER's own transport diagnostics, not an identity surface — that is why they survive #50 C4 while `entwurf_peers` forbids every socket-shaped key/path (the peers listing points at OTHER citizens, where a socket path is an address claim).
|
|
171
|
-
- The target registry (`pi/entwurf-targets.json` + `setup:links`) is **gone** (#50 C3): v2 never spawns from a model tuple — `entwurf_v2` resumes an already-identified record-backed citizen, and dormant-resume authorization is record existence + the transcript-header ↔ `record.nativeSessionId` integrity check (the old `requireEntwurf` name-tag and resume-marker env are deleted). Bridge-extension routing survives as `getRegistryRouting` (caller-supplied tuple, ← resolve-acp-bridge). Identity Preservation Rule: no model override on resume.
|
|
172
|
-
- `PI_SHELL_ACP_V2_ONLY=1` was the v1-refusal flag; with v1 removed on this branch its guard (`entwurf-v2-only.ts`) is gone too. `runEntwurfV2` was always flag-clean.
|
|
173
|
-
|
|
174
|
-
> **Source-agnostic does not mean harness-agnostic.** 어디서 던지든 — GLG / sibling / external MCP host — entwurf 의 *target* 은 garden citizen 이다. spawn-bg resume 의 spawn surface 는 pi 자식 프로세스만 띄운다 (`pi --entwurf-control` keep-alive resident). 외부 MCP host 가 닿을 때도 target 은 이미 식별된 citizen 이어야 한다. *Model* 은 free axis (어느 형제 학교 모델이든), *spawn target* 은 harness 정합 axis.
|
|
175
|
-
|
|
176
|
-
> **Naming pair.** *Entwurf* (기투, projection-of-self) — a resident agent throws siblings forward (resume / messaging). The resident-side counterpart is *Mitsein* (공존, being-with), defined in the resident's own knowledge base (cwd-scoped, not a global persona). This repo owns the entwurf substrate; resident-side conventions live where the resident wakes.
|
|
177
|
-
|
|
178
|
-
### Resident identity — the record is the address (#50 C2)
|
|
179
|
-
|
|
180
|
-
A `--entwurf-control` session is a garden citizen because it has a **meta-record**, not
|
|
181
|
-
because its session id has a particular shape. pi mints its own id (a uuidv7 is normal);
|
|
182
|
-
`birthPiCitizen` upserts `(backend:"pi", nativeSessionId)` at `session_start`, the record
|
|
183
|
-
mints the `gardenId`, and everything addressable hangs off that one string.
|
|
184
|
-
|
|
185
|
-
- **Launch:** `pi --entwurf-control …`. No `--session-id` injection — that was the old
|
|
186
|
-
launcher's job and it is gone, together with `run.sh new-session-id`'s role in launching
|
|
187
|
-
(the generator itself stays; the record uses it to mint garden ids).
|
|
188
|
-
- **In-process new/resume:** pi's own. `/new`, `/fork`, `/clone` and RPC session replacement
|
|
189
|
-
all just fire `session_start`, which attaches the new session as its own citizen and
|
|
190
|
-
rebinds the socket to its address. The `/gnew` command, the pre-switch cancels and the
|
|
191
|
-
garden-format hard exit are deleted — there is no id to police (LOCKED PROTOCOL 2).
|
|
192
|
-
- **Socket:** `~/.pi/entwurf-control/<gardenId>.sock`, keyed on the RECORD's id. A socket
|
|
193
|
-
carrying pi's session id is the pre-cut address and a gate failure.
|
|
194
|
-
- **`PI_SESSION_ID`** carries the gardenId, so every child MCP process reads back a
|
|
195
|
-
routable address (`entwurf_self`), never pi's internal id.
|
|
196
|
-
- **Failure is loud, not cosmetic:** if the record cannot be written (unreadable store,
|
|
197
|
-
duplicate native id, an unreadable store naming the fresh-cut verb) the control server is
|
|
198
|
-
refused, `PI_SESSION_ID` stays unset, and the reason is on stderr. An unaddressable
|
|
199
|
-
resident must not survive quietly — that is the guard's surviving purpose.
|
|
200
|
-
- **Status label = 🪛 (the forged screwdriver, the North Star), NOT the word "entwurf".**
|
|
201
|
-
`🪛 ready` before the first assistant turn (session file not on disk → model changeable),
|
|
202
|
-
`🪛 <gardenId>` after (file written → model locked).
|
|
203
|
-
- **The resident session NAME is pi's.** The `control`-tagged garden name mirror, its
|
|
204
|
-
`entwurf`-tag refusal and the sessionId-bound resume-marker exemption are gone with the id
|
|
205
|
-
they mirrored. Dormant-resume authorization is record existence (LOCKED PROTOCOL 6) plus
|
|
206
|
-
the transcript-header ↔ `record.nativeSessionId` integrity check (#50 C3).
|
|
207
|
-
- Gates: `smoke-pi-attach` (deterministic, in `pnpm check`: record birth · record-keyed
|
|
208
|
-
socket · attach-on-reopen · artifact delivers to the socket) + `smoke-resident-garden-guard`
|
|
209
|
-
(LIVE, the same contract driven through a real `pi` process).
|
|
86
|
+
- **control-socket domain (currently `pi`)**: socket liveness, per-target lock, live send, and the dormant cell that selects spawn-bg.
|
|
87
|
+
- **spawn-bg resume** is a **separate relaunch transport**, not the control-socket rail: the dormant socket-liveness branch selects it, and the launch leaf (`resolveResumeLaunchIdentity`) is what checks backend authority. There is no separate spawn-domain predicate today — do not describe it as its own domain until one exists.
|
|
88
|
+
- **self-fetch domain (currently Claude Code)**: active receiver + mailbox deliverability; no owned resume.
|
|
89
|
+
- **native-push domain (currently Antigravity)**: adapter probe + direct injection; no mailbox or owned resume.
|
|
90
|
+
- `origin: "pi-session" | "meta-session" | "external-mcp"` records sender provenance. It is not the citizen identity schema and not a hierarchy.
|
|
91
|
+
- `entwurf_peers` reports record citizens and liveness facts only. It never embeds routing verbs or socket addresses for peers.
|
|
92
|
+
- `entwurf_self` is identity-required. For pi, its env carrier must have been planted from record birth; native marker identity must be backed by the matching record. Replyability is derived from the active rail, never hardcoded.
|
|
210
93
|
|
|
211
94
|
### Send-is-throw
|
|
212
95
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
-
|
|
216
|
-
- The sender envelope rides every send by default: `{ sessionId, agentId, cwd, timestamp, origin?, replyable? }`. `origin` distinguishes pi-session senders (`replyable: true`) and trusted meta-session senders. Claude meta replyability is mailbox-backed; native-push replyability is record-backed + probe-alive. `entwurf_self` is authoritative-identity-required.
|
|
217
|
-
- **Human-greeted 담당자** is a first-class pattern: GLG may open a session in repo B, greet it directly, then hand its garden id to repo A. Spawned siblings and human-opened peers share the same messaging semantics; only the creation sequence differs.
|
|
218
|
-
|
|
219
|
-
## File Structure
|
|
220
|
-
|
|
221
|
-
| File | Purpose |
|
|
222
|
-
|------|---------|
|
|
223
|
-
| `pi-extensions/acp-provider.ts` | ACP plugin entry: registers the package provider `entwurf` + curated Claude model surface; wires `streamSimple` to the real ACP backend |
|
|
224
|
-
| `pi-extensions/lib/acp/*.ts` | ACP plugin internals: curated Claude surface + no-auth sentinel (`models.ts`), Claude config overlay (`overlay.ts`), tool surface + exclude-tools preflight (`tool-surface.ts`), ACP→pi event mapper (`event-mapper.ts`), pi Context→ACP prompt (`context.ts`), spawn-per-turn `streamSimple` backend (`backend.ts`) |
|
|
225
|
-
| `pi-extensions/entwurf-control.ts` | control plane: record attach at session_start, `--entwurf-control` socket (keyed on the record gardenId), RPC, `entwurf_v2` / `entwurf_peers` tools |
|
|
226
|
-
| `pi-extensions/lib/pi-citizen-birth.ts` | the #50 C2 attach seam: pi session → meta-record upsert → control-socket address |
|
|
227
|
-
| `pi-extensions/model-lock.ts` | package-provider model lock (pi.extension) |
|
|
228
|
-
| `pi-extensions/meta-bridge-hook.ts` | Claude Code `SessionStart` hook: register a mailbox-backed garden meta-session |
|
|
229
|
-
| `pi-extensions/lib/entwurf-v2-*.ts` | v2 substrate: contract / lock / decider / matrix / release / send / mailbox / native-push / runner / production / surface / spawn(+production) |
|
|
230
|
-
| `pi-extensions/lib/native-push/` | Antigravity adapter probe/route, direct-inject hand, explicit native registration core |
|
|
231
|
-
| `pi-extensions/lib/meta-*.ts` | V3-only meta-record authority (`meta-session.ts`), mailbox state, receiver/sender identity — one live schema, no legacy readers |
|
|
232
|
-
| `scripts/agy-{bridge,statusline-bridge,hooks-bridge}.*` | three state-backed agy install/doctor/inverse surfaces |
|
|
233
|
-
| `scripts/agy-imprint.ts` | agy `PreInvocation` automatic birth + record-backed sender marker |
|
|
234
|
-
| `pi-extensions/lib/entwurf-core.ts` | shared core (session-file lookup, identity read, explicit-extension args); some v1 exports now dead pending routing cleanup |
|
|
235
|
-
| `protocol.js` | dependency-free shared wire constants (`<project-context` marker); single source for tsc emit + strip-types MCP paths |
|
|
236
|
-
| `run.sh` | install (incl. `install-meta-bridge`), check-*/smoke-* gates, release-gate |
|
|
237
|
-
| `mcp/entwurf-bridge/` | MCP server exposing `entwurf_v2`, `entwurf_self`, `entwurf_peers`, `entwurf_inbox_read` |
|
|
238
|
-
|
|
239
|
-
## Typecheck Boundary
|
|
96
|
+
- Delivery returns an ack/receipt, not the peer's turn result. If a reply is wanted, say so and set `wants_reply`; that flag is etiquette, not ownership.
|
|
97
|
+
- Sender envelope: `{ sessionId, agentId, cwd, timestamp, origin?, replyable? }`.
|
|
98
|
+
- Human-opened and spawned/resumed siblings use the same addressing and messaging semantics.
|
|
240
99
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
| Config | Covers | Runtime model |
|
|
244
|
-
|---|---|---|
|
|
245
|
-
| `tsconfig.json` (root) | `pi-extensions/**` | emit-capable. The root config must not set `noEmit`. |
|
|
246
|
-
| `mcp/tsconfig.json` (extends root) | `mcp/entwurf-bridge/**`, plus the `pi-extensions/lib/*` it imports | `node --experimental-strip-types`. Adds `allowImportingTsExtensions` + `noEmit` because the bridge imports the shared lib with explicit `.ts` suffixes — Node's strip-types resolver requires the suffix on the wire. |
|
|
247
|
-
| `scripts/tsconfig.json` (extends root) | `scripts/**` (verification scripts), plus the `pi-extensions/lib/*` it imports | `node --experimental-strip-types`. Same trade-off: explicit `.ts` imports + `allowImportingTsExtensions` + `noEmit`. Scripts are runtime gates, not build inputs. |
|
|
100
|
+
## Verification
|
|
248
101
|
|
|
249
|
-
|
|
102
|
+
Two axes are required: deterministic/package gates and opt-in LIVE evidence.
|
|
250
103
|
|
|
251
|
-
|
|
104
|
+
```bash
|
|
105
|
+
pnpm typecheck
|
|
106
|
+
pnpm check
|
|
107
|
+
./run.sh check-entwurf-v2-matrix
|
|
108
|
+
./run.sh check-meta-session
|
|
109
|
+
./run.sh check-entwurf-bridge-boot
|
|
110
|
+
./run.sh check-install-surface
|
|
111
|
+
./run.sh check-install-container # require Docker in release acceptance
|
|
112
|
+
|
|
113
|
+
LIVE=1 ./run.sh release-gate /path/to/scratch
|
|
114
|
+
LIVE=1 ./run.sh smoke-acp-socket-citizen-live
|
|
115
|
+
LIVE=1 ./run.sh smoke-acp-bundled-mcp-live
|
|
116
|
+
LIVE=1 ./run.sh smoke-acp-v2-send-live
|
|
117
|
+
LIVE=1 AGY_CONVERSATION_ID=<id> ./run.sh smoke-agy-native-push-live
|
|
118
|
+
```
|
|
252
119
|
|
|
253
|
-
-
|
|
254
|
-
- **
|
|
255
|
-
- **
|
|
256
|
-
-
|
|
120
|
+
- `pnpm check` is the static floor and includes the detailed `check-*`/offline smoke matrix.
|
|
121
|
+
- **Kill-proof discipline (gate qualification).** A gate is a test only if re-planting a closed defect turns it red for the claimed reason. `check-gate-qualification` proves that automatically: committed mutants in `scripts/mutants/` must be KILLED at their `[QK:<claim>]` signature inside an isolated snapshot repo (control→mutant→restore→control; the real checkout is never written). Gates a release touches carry such manifests; assertion counts are never evidence — claim IDs + killed mutant IDs are. `check-agy-permission-matrix` holds the enumerated permission contract space; matrix cells change by axis/rule edits, never by appending cases.
|
|
122
|
+
- **When changing a contract/gate:** name the production subject and an oracle independent of it; give the failing assertion a stable `[QK:<claim>]` label and add/update the exact-once mutant in `scripts/mutants/*.json`; if the contract is combinatorial, update the literal matrix axes/cells/exclusions together with their declared counts; then verify focused gate → `check-gate-qualification` → `pnpm check`, in that order. `MUTANT-STALE`/`SURVIVED`/`WRONG-REASON`/`CONTROL-RED`/`HANG`/`IMPURE` are red — never substitute an assertion count for a kill.
|
|
123
|
+
- Run LIVE gates with `PWD` in scratch so session artifacts do not land in the repo.
|
|
124
|
+
- Release acceptance and evidence levels are defined in [VERIFY.md](./VERIFY.md); recorded host evidence is in [BASELINE.md](./BASELINE.md).
|
|
125
|
+
- A failed gate or evidence downgrade blocks commit/release. Pipes can be connected and the water can still taste wrong.
|
|
257
126
|
|
|
258
|
-
##
|
|
127
|
+
## Repository Map
|
|
259
128
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
129
|
+
| Path | Purpose |
|
|
130
|
+
|---|---|
|
|
131
|
+
| `pi-extensions/entwurf-control.ts` | pi adapter: record attach, record-keyed socket, RPC, native tools |
|
|
132
|
+
| `pi-extensions/lib/pi-citizen-birth.ts` | pi native session → shared V3 record → socket address |
|
|
133
|
+
| `pi-extensions/lib/meta-session.ts` | shared V3 record/store authority plus native marker/mailbox primitives |
|
|
134
|
+
| `pi-extensions/lib/entwurf-v2-*.ts` | v2 contract, decider, transports, runner, production wiring |
|
|
135
|
+
| `pi-extensions/lib/entwurf-fact*.ts` | record citizens + transport-specific liveness facts |
|
|
136
|
+
| `pi-extensions/lib/native-push/` | native-push adapter/probe/register leaf |
|
|
137
|
+
| `pi-extensions/acp-provider.ts` | `entwurf` provider registration |
|
|
138
|
+
| `pi-extensions/lib/acp/` | ACP adapter rail, config/overlay, augment, turn loop, event mapping |
|
|
139
|
+
| `mcp/entwurf-bridge/` | MCP surface for v2/self/peers/inbox/native-register |
|
|
140
|
+
| `scripts/` | deterministic gates, LIVE smokes, install/doctor surfaces |
|
|
141
|
+
| `run.sh` | installed command and gate dispatcher |
|
|
142
|
+
|
|
143
|
+
## Type and Runtime Boundaries
|
|
144
|
+
|
|
145
|
+
- 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
|
+
- Root pi extensions import TypeBox through `@earendil-works/pi-ai`; do not mix direct `@sinclair/typebox` types.
|
|
147
|
+
- 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.82.1 <0.83` with devDep exact `0.82.1`; re-evaluate loader aliases and `/compat` at the minor ceiling.
|
|
149
|
+
- 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.
|
|
263
150
|
|
|
264
151
|
## Working Style
|
|
265
152
|
|
|
266
|
-
- Surgical changes
|
|
267
|
-
-
|
|
268
|
-
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
- Keep docs calibrated
|
|
274
|
-
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
- [
|
|
283
|
-
- [VERIFY.md](./VERIFY.md)
|
|
284
|
-
- [
|
|
285
|
-
- [agent-config](https://github.com/junghan0611/agent-config) — real consumer repo.
|
|
153
|
+
- Surgical changes, one contract at a time. Ask whether a change belongs in core, a harness adapter, a backend adapter, or the resident's own repo.
|
|
154
|
+
- Removal/repair changes source and their gates together. Do not leave a green gate that only proves retired behavior.
|
|
155
|
+
- Before commit, perform a **repo-wide** stale-prose sweep on two axes:
|
|
156
|
+
1. retired symbols/authority vocabulary (`dual-read`, old schema names, removed commands, privileged identity wording);
|
|
157
|
+
2. landed-plan future tense (`yet`, `will land`, `not here`, stale step headers).
|
|
158
|
+
- Judge each grep hit: historical CHANGELOG tombstones may remain; live claims, comments, usage text, gates, README, docs, NEXT, and source-module prose must agree with current behavior.
|
|
159
|
+
- Prefer capability/domain names (`control-socket domain`, `self-fetch`, `native-push`, `out-of-domain`) over identity-rank names (`pi-only citizen`, `non-pi citizen`).
|
|
160
|
+
- Keep docs calibrated and compact. Implementation archaeology belongs in git/CHANGELOG/issues; AGENTS keeps only invariants needed before acting.
|
|
161
|
+
- Use tabs unless the existing file/linter requires otherwise.
|
|
162
|
+
- GLG decides commit, push, and release gates. Never infer push from a commit request.
|
|
163
|
+
|
|
164
|
+
## Next and References
|
|
165
|
+
|
|
166
|
+
- [NEXT.md](./NEXT.md) — current priority and exact next move; branch work uses disposable `NEXT--<branch>.md`.
|
|
167
|
+
- [ROADMAP.md](./ROADMAP.md) — forward direction and deferred lanes.
|
|
168
|
+
- [docs/acp-backend-rail.md](./docs/acp-backend-rail.md) — ACP adapter contract and current entry conditions.
|
|
169
|
+
- [DELIVERY.md](./DELIVERY.md) — delivery capability/evidence coordinates.
|
|
170
|
+
- [VERIFY.md](./VERIFY.md) / [BASELINE.md](./BASELINE.md) — verification protocol and recorded evidence.
|
|
171
|
+
- [README.md](./README.md) — operator-facing package contract.
|
package/BASELINE.md
CHANGED
|
@@ -230,7 +230,7 @@ the same conversation must have a garden id.
|
|
|
230
230
|
| Q-AGY-SELF | Sender identity | `entwurf_self` reports the same garden id, `origin=meta-session`, `agentId=meta-session/antigravity`, and `replyable:true` while the native probe is alive. | Anonymous `external-mcp`, unbacked marker accepted, model name substituted into `agentId`, or mailbox evidence used to infer replyability. |
|
|
231
231
|
| Q-AGY-SEND | Outbound attribution | `entwurf_v2` from agy reaches a sibling carrying that same sender garden id and `replyable:true`. | Receiver sees unknown host/wrong garden id, or sender ambiguity is silently guessed. |
|
|
232
232
|
| Q-AGY-REPLY | Same-conversation reply | Sibling replies with `entwurf_v2(target=<agy-gid>, intent=fire-and-forget)` and the message direct-injects into the same live agy conversation. | New conversation/spawn, mailbox file/doorbell, or a cosmetic delivered result with no live native route. |
|
|
233
|
-
| Q-AGY-OWNERSHIP | Install scope | MCP owns one server plus `mcp(entwurf-bridge
|
|
233
|
+
| Q-AGY-OWNERSHIP | Install scope | MCP owns one server plus one narrow `mcp(entwurf-bridge/<tool>)` rule per normal-path tool (`entwurf_v2`, `entwurf_peers`, `entwurf_self`) and nothing else; statusline owns its subtree; hooks own one named hook. | Installer broadens YOLO policy (`command(*)`, `unsandboxed(*)`), grants tools it does not need (`entwurf_inbox_read`, `entwurf_register_native`), or overwrites unrelated settings/hooks. |
|
|
234
234
|
| Q-AGY-CONCURRENCY | Evidence boundary | Separate agy processes have separate pid/start-key markers; same-pid concurrent model invocation is explicitly reported unsupported. | Claims that one pid can safely identify two simultaneously invoking conversations. |
|
|
235
235
|
|
|
236
236
|
The replyability formula is **record-backed identity AND live native-push probe**.
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@ All notable changes to this project will be documented here. Format follows [Kee
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.12.10 — 2026-07-27
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- **The Claude ACP dependency rail moves to `@agentclientprotocol/claude-agent-acp` 0.62.0.** The paired SDK surface fence now covers Claude Agent SDK 0.3.219; this is a dependency refresh, not a claim that MCP readiness timing changed.
|
|
12
|
+
- **The ACP rail document now names its unresolved readiness question precisely.** The ordered probe records wire availability, `newSession`, model enforcement, and prompt boundaries before any adapter remedy or Cortex work is considered.
|
|
13
|
+
- **Gate qualification is part of the deterministic floor.** Committed defect mutants run in an isolated snapshot and must fail their named `[QK:<claim>]` oracle; the agy permission contract is likewise covered by an independent literal matrix.
|
|
14
|
+
|
|
15
|
+
### Fixed
|
|
16
|
+
|
|
17
|
+
- **All citizen rails now share the same record authority without inventing pi privilege.** Control-socket, self-fetch, and native-push capability differences remain explicit while stale pi-special address and transport prose is removed.
|
|
18
|
+
- **The shipped pi and MCP tool descriptions tell the complete v2 dispatch truth.** Native-push direct injection, its three-valued probe rejects, mailbox deliverability, control-socket lock scope, and spawn-bg's separate relaunch transport are described and regression-fenced on both surfaces.
|
|
19
|
+
- **Native-push self-awareness and agy permissions follow their actual rail.** Native-push never advertises an inbox; normal-path agy approval covers `entwurf_v2`, `entwurf_peers`, and `entwurf_self` with per-rule ownership, strict state migration, and separate runtime/ownership doctor verdicts.
|
|
20
|
+
|
|
21
|
+
### Verification
|
|
22
|
+
|
|
23
|
+
- Pre-version landing HEAD `9a501b30f0e7d82307d885f1a1eb9d91c79c5f16` passed exact-SHA GitHub Actions run [30252596435](https://github.com/junghan0611/entwurf/actions/runs/30252596435): `check`, `install-surface`, and `artifact-consumer` all success.
|
|
24
|
+
- The prepared tree passed `pnpm check`; `LIVE=1 ./run.sh release-gate /tmp/entwurf-release-gate-0.12.10.d4gC9v` 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.12.10.d4gC9v/release-gate.log`; per-step artifacts are preserved in that log. Prepared-HEAD exact-SHA CI and preserved-candidate acceptance remain deliberately deferred to `make`.
|
|
25
|
+
|
|
7
26
|
## 0.12.9 — 2026-07-26
|
|
8
27
|
|
|
9
28
|
### Changed
|
package/DELIVERY.md
CHANGED
|
@@ -213,11 +213,12 @@ three markers) but **not** simultaneous model invocation by two conversations
|
|
|
213
213
|
under one agy pid: one marker file would be last-writer-wins, so that concurrency
|
|
214
214
|
is explicitly unsupported.
|
|
215
215
|
|
|
216
|
-
Current deterministic floor: `smoke-agy-install-state`
|
|
216
|
+
Current deterministic floor: `smoke-agy-install-state` 167 checks,
|
|
217
217
|
`smoke-agy-statusline-state` 69, `smoke-agy-hooks-state` 44,
|
|
218
218
|
`check-agy-sender-identity` 28, plus the shared self-address/native-push gates.
|
|
219
|
-
The bridge installer owns
|
|
220
|
-
`
|
|
219
|
+
The bridge installer owns one narrow rule per normal-path tool
|
|
220
|
+
(`entwurf_v2`, `entwurf_peers`, `entwurf_self`) in `permissions.allow`;
|
|
221
|
+
broad YOLO policy stays operator-owned. Live 2026-07-13
|
|
221
222
|
(agy 1.0.x): automatic birth → gid/statusline → record-backed sender → sibling
|
|
222
223
|
delivery → same-gid native-push reply passed. Live 2026-07-14 (**agy 1.1.0**):
|
|
223
224
|
re-verified on the new minor — `entwurf_self` answered without a permission
|