@junghanacs/entwurf 0.36.1 → 0.37.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 +2 -2
- package/CHANGELOG.md +301 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +5 -0
- package/VERIFY.md +26 -17
- package/docs/setup-clean-host.md +1 -0
- package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +16 -1
- package/package.json +4 -3
- package/pi/pi-durable/bootstrap.mjs +113 -11
- package/pi/pi-durable/carrier/harness-setup.js +4 -1
- package/pi/pi-durable/carrier/prompt.js +31 -2
- package/pi/pi-durable/carrier/runtime.js +11 -2
- package/pi/pi-durable/carrier/sessions.js +75 -5
- package/pi/pi-durable/carrier/tui.js +23 -0
- package/pi/pi-durable/overlay/upstream-pin.json +10 -10
- package/pi-extensions/meta-bridge-pi-durable.ts +20 -0
- package/run.sh +44 -17
- package/scripts/check-gate-qualification.ts +3 -3
- package/scripts/check-release-gate-outcomes.ts +200 -387
- package/scripts/fixtures/herdr-supply.json +11 -10
- package/scripts/lib/codex-fresh-live-protocol.ts +6 -1
- package/scripts/lib/qualification-ledger.ts +2 -2
- package/scripts/mutants/herdr-supply.json +5 -5
- package/scripts/mutants/pi-durable.json +117 -45
- package/scripts/mutants/release-gate.json +18 -52
- package/scripts/smoke-mux-lifecycle-live.ts +1 -1
- package/scripts/ci-qualify-decide.sh +0 -256
- package/scripts/fixtures/qualify-replay.json +0 -149
package/AGENTS.md
CHANGED
|
@@ -91,10 +91,10 @@ implement → affected focused gates → independent review → one amendment bu
|
|
|
91
91
|
→ affected qualification PARTIAL once if gate/mutant/matrix changed → full floor once on frozen candidate → commit
|
|
92
92
|
```
|
|
93
93
|
|
|
94
|
-
- GLG-requested branch checkpoint commits keep completed subject/proof bundles small: scoped review, affected focused checks and normal hooks/shared scanner before each checkpoint, with known RED/unmeasured boundaries recorded. A checkpoint is not frozen-candidate acceptance. The sequence above owns final candidate acceptance: the affected qualification PARTIAL, frozen FULL and native/LIVE/release floors remain mandatory before landing, and the prepared SHA's CI qualification body before shipment, never inherited from an interim commit.
|
|
94
|
+
- GLG-requested branch checkpoint commits keep completed subject/proof bundles small: scoped review, affected focused checks and normal hooks/shared scanner before each checkpoint, with known RED/unmeasured boundaries recorded. A checkpoint is not frozen-candidate acceptance. The sequence above owns final candidate acceptance: the affected qualification PARTIAL, frozen FULL and native/LIVE/release floors remain mandatory before landing, and the prepared SHA's exact-SHA CI push run (its four required jobs; the qualification body is no longer a release axis, #144) before shipment, never inherited from an interim commit.
|
|
95
95
|
- Inner loop runs only affected gates; review and its corrections finish before the full floor.
|
|
96
96
|
- A changed contract names a production subject and independent oracle; its focused assertion has a stable QK and exact-once mutant. Matrices change by their declared axes/cells, not appended anecdotes.
|
|
97
|
-
- Development never runs the whole qualification body. A changed gate/mutant/matrix runs its affected exact-argv groups once, after review and amendment, as PARTIAL receipts (`./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`); the manifest head stays in the deterministic floor.
|
|
97
|
+
- Development never runs the whole qualification body. A changed gate/mutant/matrix runs its affected exact-argv groups once, after review and amendment, as PARTIAL receipts (`./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`); the manifest head stays in the deterministic floor. Since #144 (GLG, 2026-10-16) the whole body is not a release axis: it runs only on the weekly schedule or a manual `qualify=true` dispatch, as a drift diagnostic no cut waits for, and no cut owes a local whole body either. A release states that kill-power was not re-measured at its SHA and lists any earlier-candidate PARTIAL with its own candidate; a PARTIAL never stands for the release, and the release still requires the exact-SHA evidence VERIFY names, never a nearby green run.
|
|
98
98
|
- Freeze the candidate while the full floor runs; any worktree/index movement voids that receipt. Pre-commit is not the full floor.
|
|
99
99
|
- LIVE/release floors are not lowered by a shorter inner loop. Failed gate or evidence downgrade blocks the relevant commit/release decision.
|
|
100
100
|
|
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,307 @@ All notable changes to this project will be documented here. Format follows [Kee
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.37.1 - 2026-10-16
|
|
8
|
+
|
|
9
|
+
### Verification
|
|
10
|
+
|
|
11
|
+
- **The native-module ingress claims get their own mutant coordinate (#144).** The 13
|
|
12
|
+
`PI-DURABLE-MODULE-*` claims carry their QKs only in `pi-durable-native-module.test.ts`, and a
|
|
13
|
+
kill is attributed from the mutant's own QK, yet each of them re-ran all six pi-durable beside
|
|
14
|
+
tests. `./run.sh check-pi-durable-native-module` runs that one file and is now their gate argv;
|
|
15
|
+
`check-pi-durable-beside` no longer runs it. No claim, find/replace, signature or build changes.
|
|
16
|
+
- **The carrier claims get their own mutant coordinate too (#144).** The 30 claims whose QKs live
|
|
17
|
+
only in `pi-durable-carrier.test.ts` move to `./run.sh check-pi-durable-carrier`, which runs that
|
|
18
|
+
file alone; `check-pi-durable-beside` keeps the adapter, verifier, preflight and owner-join files
|
|
19
|
+
and their 39 claims. All three coordinates stay in `check:contracts`, and every claim keeps its
|
|
20
|
+
subject, find/replace, signature and bridge build (the carrier test reaches the bridge through the
|
|
21
|
+
bootstrap). Measured once on one host, on an isolated copy of `5e1e629` (M1, a composition
|
|
22
|
+
measurement, not a kill run): the six files together took 24.5s, the carrier file alone 17.6s and
|
|
23
|
+
the native-module file alone 1.7s, so before the split every mutant of the former six-file
|
|
24
|
+
`check-pi-durable-beside` group (82; the two `check-node-floor-coherence` claims were never in it)
|
|
25
|
+
paid the carrier's time. Those seconds are local, not CI timing. A moved mutant no longer runs beside the other
|
|
26
|
+
files; that was incidental exposure, never the ground of a kill, which is attributed only from the
|
|
27
|
+
mutant's own QK.
|
|
28
|
+
- **The whole qualification body is no longer a release axis (#144).** By GLG's decision of
|
|
29
|
+
2026-10-16 (split local gates from CI; a named loss of verification is accepted to stop paying for
|
|
30
|
+
the same proof twice), no push runs the body any more and no cut waits for it. Measured from the
|
|
31
|
+
GitHub API over one cut window (v0.36.1 push `cab1b9f` through the Herdr 0.37.0 snapshot `5e1e629`,
|
|
32
|
+
six `ci.yml` runs): the body ran five times on five SHAs for 506.3 minutes of `check`-step time,
|
|
33
|
+
once as a dispatch that re-bought it for a SHA whose push had skipped it, while a push run without
|
|
34
|
+
it took 10.9 minutes wall. That is the cost before this change, not a measured saving. The body now
|
|
35
|
+
runs only on the weekly schedule or a manual `qualify=true` dispatch, as a drift diagnostic. The
|
|
36
|
+
push-range filter that decided when it ran (`scripts/ci-qualify-decide.sh`, its replay fixture, and
|
|
37
|
+
the five `QUALIFY-FILTER-*` claims) is retired with it, and the release skill no longer dispatches
|
|
38
|
+
the body.
|
|
39
|
+
- **The release oracle takes the push run as its only witness, and no longer reads the body
|
|
40
|
+
(#144).** `verify-exact-ci.sh` asks for push runs of the exact SHA (`--event push`, and a jq that
|
|
41
|
+
keeps only push runs) and judges the four required jobs. Its fourth axis, the body step, is
|
|
42
|
+
removed with `RELEASE-SHA-QUALIFIED-IN-CI`, and its PASS prints that the body is not a release
|
|
43
|
+
axis instead of a body success line. `check-release-gate-outcomes` drives the shipped script
|
|
44
|
+
through a fake `gh`: `RELEASE-WITNESS-IS-PUSH-RUN` pins the one `run list` call it sends (the
|
|
45
|
+
fake evaluates no jq, and GitHub's own filtering is not observed), `RELEASE-ORACLE-REFUSES-NON-SUCCESS-JOB`
|
|
46
|
+
refuses each required job that is absent, failed, skipped, cancelled or unconcluded, and
|
|
47
|
+
`RELEASE-ORACLE-CLAIMS-NO-BODY` passes the four jobs whether the body step is skipped, absent or
|
|
48
|
+
green without ever naming it. The `release-gate` lane is 21 claims.
|
|
49
|
+
- **Named loss.** A release no longer re-measures the kill-power of the committed claims at its SHA.
|
|
50
|
+
Its section says so (`Kill-power re-measured at this shipped SHA: none`), and lists a PARTIAL
|
|
51
|
+
receipt only with its own candidate, never summed into a count for the release. The weekly run is
|
|
52
|
+
a drift window, not a guarantee for any commit.
|
|
53
|
+
- **The mux lifecycle LIVE runs on a different native model, and before the ACP tier.** In 0.37.0's
|
|
54
|
+
first LIVE run and in this cut's first one, `smoke-mux-lifecycle-live` went red the same way: its
|
|
55
|
+
pi-native sibling (`openai-codex/gpt-6-luna`) was alive, ran shell no-ops, answered "ACK" and never
|
|
56
|
+
called the callback tool within 300 s. The cause is not determined; one instrumented diagnostic run
|
|
57
|
+
saw the callback declared in the first request and called back in about 4 s, so the failure did
|
|
58
|
+
not reproduce. The test's native model is now `openai-codex/gpt-6.1-sol:low` (`VERIFY.md` names it), and
|
|
59
|
+
`release-gate` runs this step right after the v2 matrix, before the ACP tier, so a red answer comes
|
|
60
|
+
before the ACP turns are spent. This is a test-model and order change, not a fix: the `gpt-6-luna`
|
|
61
|
+
cause stays undetermined. In this cut's second and third LIVE runs the step passed on the new
|
|
62
|
+
model and order; those are two observations, and neither proves the earlier cause.
|
|
63
|
+
- **The Codex first-admission LIVE now says the id prefixes are part of the ids.** In this cut's
|
|
64
|
+
second LIVE run the moved mux step passed, and `smoke-codex-fresh-live` failed on its last check:
|
|
65
|
+
the Codex sibling's final `entwurf_v2` arguments carried `PI_SESSION_ID=485` and
|
|
66
|
+
`PI_WINDOW_ID=1130` where the launch receipt printed `$485` and `@1130`, with every other field
|
|
67
|
+
exact. Its instruction named the `$` and `@` only inside the placeholder text; it now tells the
|
|
68
|
+
sibling to copy both ids byte for byte from the receipt's `window:` line, keeping each leading
|
|
69
|
+
prefix. The exact-argument comparison is unchanged and nothing is stripped. That the wording
|
|
70
|
+
invited the drop is a hypothesis: the same code and model passed in 0.37.0. In this cut's third
|
|
71
|
+
LIVE run the step passed with both prefixes exact (`$488`, `@1136`); that is one run, and it does
|
|
72
|
+
not prove that the wording caused the earlier drop or rule out model variation.
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
### Release boundary and verification
|
|
76
|
+
|
|
77
|
+
- **Scope.** A core patch over `v0.37.0` for #144: `1df7926` (the pi-durable native-module and
|
|
78
|
+
carrier mutant coordinates, and the release oracle's job refusal driven through a fake `gh`) and
|
|
79
|
+
`c208d37` (the whole qualification body retired as a release axis). The Herdr plugin snapshot
|
|
80
|
+
`v2026.10.15-herdr.0.37.0` at `5e1e629` is unchanged; pi 1.3.0 (#145) is not in this cut.
|
|
81
|
+
- **Kill-power re-measured at this shipped SHA: none (all 979 committed claims not re-proved,
|
|
82
|
+
#144).**
|
|
83
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
|
|
84
|
+
e907429b9c00 -- `check-pi-durable-native-module` 13/13 receipt e0f96c3374de
|
|
85
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
|
|
86
|
+
e907429b9c00 -- `check-pi-durable-beside` 69/69 receipt 36e46bdd4cf0
|
|
87
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
|
|
88
|
+
ea26d369b1af -- `check-pi-durable-carrier` 30/30 receipt 01f9096a8eb5
|
|
89
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
|
|
90
|
+
ea26d369b1af -- `check-pi-durable-beside` 39/39 receipt 93d9f5cdf699
|
|
91
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
|
|
92
|
+
980384f2532f -- `check-release-gate-outcomes` 25/25 receipt eedfb075bf07
|
|
93
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
|
|
94
|
+
980384f2532f -- `check-gate-manifests` 52/52 receipt 8a976415c566
|
|
95
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 5e1e629a5826 surface
|
|
96
|
+
980384f2532f -- `check-gate-qualification.ts --attribution-self-test` 1/1 receipt 3edfa0af9d3a
|
|
97
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 1df7926257a9 surface
|
|
98
|
+
106c59c5cb99 -- `check-release-gate-outcomes` 21/21 receipt c869965b8dbc
|
|
99
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 1df7926257a9 surface
|
|
100
|
+
106c59c5cb99 -- `check-gate-manifests` 52/52 receipt 08eae97d65b0
|
|
101
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head 1df7926257a9 surface
|
|
102
|
+
106c59c5cb99 -- `check-gate-qualification.ts --attribution-self-test` 1/1 receipt 276118d0ba9b
|
|
103
|
+
- Earlier-candidate PARTIAL (operator-attested, not this SHA): head c208d37f1442 surface
|
|
104
|
+
d941509e2e9e -- `check-release-gate-outcomes` 21/21 receipt cd0a59e12569 (taken after the
|
|
105
|
+
mux model/order change and before the Codex id-prefix sentence; kept locally under
|
|
106
|
+
`.tmp-verify/release-0.37.1/fix-mux-first/partial-evidence/`)
|
|
107
|
+
- **Not re-measured for the Codex id-prefix sentence.** The five mutants whose subject is
|
|
108
|
+
`scripts/lib/codex-fresh-live-protocol.ts` were reviewed as lying outside the changed bytes, and
|
|
109
|
+
their `check-mux-fresh-call` group (150 mutants over 18 subjects) was not run, so those five
|
|
110
|
+
kills are not re-measured on the new bytes. The new sentence has no deterministic assertion of
|
|
111
|
+
its own: deleting it would leave the deterministic suite green, and only a LIVE run would see it.
|
|
112
|
+
- **Where those receipts are published.** Each receipt above except the newest (`cd0a59e12569`) is
|
|
113
|
+
listed with its candidate in a #144 checkpoint comment, so another host can trace it without this
|
|
114
|
+
operator's paths; the newest is local and operator-attested only, in no #144 comment. A′
|
|
115
|
+
([#144 comment 6195663856](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6195663856)),
|
|
116
|
+
B ([6196318282](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6196318282)),
|
|
117
|
+
RO-1 ([6200017214](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6200017214)) and
|
|
118
|
+
P1 ([6202638853](https://github.com/junghan0611/entwurf/issues/144#issuecomment-6202638853)).
|
|
119
|
+
The links add location only; they prove nothing new.
|
|
120
|
+
- **Branch CI, not this SHA.** The pushed branch head `c208d37` ran the new policy's first push CI
|
|
121
|
+
(run 38811304369): the four required jobs green, the body step skipped, created to last required
|
|
122
|
+
job 645 s. That run is evidence for `c208d37`; the prepared SHA owes its own.
|
|
123
|
+
- **Unpublished candidate carrier.** As in 0.37.0, `plugins/herdr/runtime-lock.json` names the
|
|
124
|
+
closed `herdr-checkout` source, because 0.37.1 has no published integrity yet and the runtime
|
|
125
|
+
refuses an npm lock whose version is not the checkout's (`scripts/herdr-runtime.mjs:355-358`).
|
|
126
|
+
The npm 0.37.0 bytes and every existing tag are unchanged; re-pinning registry bytes is a later,
|
|
127
|
+
separate Herdr snapshot.
|
|
128
|
+
- **No local static floor; it is the exact CI's.** `check:hermetic` carries
|
|
129
|
+
`check-herdr-plugin-build` and `check-herdr-sandbox`, which must not run on the operator host,
|
|
130
|
+
and `release-gate`'s first MUST step is `pnpm run check:full`. By GLG's decision of 2026-10-16
|
|
131
|
+
for this cut (a new approval, not inherited from 0.37.0), `check:full` is not run locally at P4,
|
|
132
|
+
at P5's first step or at M0, and is owed whole to the prepared SHA's CI.
|
|
133
|
+
- **LIVE, taken step by step, not as `release-gate --cut`.** The gate's 23 non-static MUST steps
|
|
134
|
+
and its BEHAVIOR step ran in the gate's own order, command, environment and working directory,
|
|
135
|
+
stopping at the first red, with each run's candidate fingerprint the same at freeze, before and
|
|
136
|
+
after. The first run (`c208d37` with this preparation's first edits) passed 18 MUST steps and
|
|
137
|
+
failed `smoke-mux-lifecycle-live` at its old position; the second (with the model and order
|
|
138
|
+
change) passed 21 and failed `smoke-codex-fresh-live` on the dropped id prefixes. Both red
|
|
139
|
+
receipts are kept. The third ran on the tested bytes, `c208d37` with this cut's source and package
|
|
140
|
+
edits; after it only `CHANGELOG.md` and `NEXT.md` changed, to record these results. It ran every
|
|
141
|
+
step itself, none reused: **MUST 23/23 PASS, FAIL 0, SKIP 0;
|
|
142
|
+
BEHAVIOR 1/1 PASS.** `smoke-mux-lifecycle-live` passed 81 checks as step 5,
|
|
143
|
+
`smoke-codex-fresh-live` 66 assertions against one owned app-server in its own tmux session
|
|
144
|
+
(named pane pid with its recorded start time, `gpt-5.6-luna` and `openai-codex/gpt-5.6-luna`,
|
|
145
|
+
stopped by one TERM after the run with its subtree, listener and control alias gone), and
|
|
146
|
+
`smoke-pi-durable-fresh-live` 36 assertions. Receipts on the operator host, under
|
|
147
|
+
`.tmp-verify/release-0.37.1/`: the third run's freeze fingerprint `3a90e3f1f2a2`, gate log
|
|
148
|
+
`94d14b3d42af` and step-log manifest `ded0d693c3ff` (24 logs); the red runs' gate logs
|
|
149
|
+
`3e16e8964f9e` and `da9622fb5312`. This is local LIVE evidence, not a release-gate verdict, and
|
|
150
|
+
no static CI result is claimed by it.
|
|
151
|
+
- **Publication boundary.** The LIVE and PARTIAL lines above are local preparation evidence.
|
|
152
|
+
Shipping this version separately requires the prepared SHA's exact CI (the four required jobs), a
|
|
153
|
+
preserved accepted candidate made from that SHA, and the tag and GitHub Release cut from it; npm
|
|
154
|
+
publication is the operator's.
|
|
155
|
+
|
|
156
|
+
## v2026.10.15-herdr.0.37.0 — Herdr Entwurf plugin 0.37.0
|
|
157
|
+
|
|
158
|
+
A separate Herdr plugin snapshot, not another core release: core package 0.37.0 and
|
|
159
|
+
its `v0.37.0` tag remain unchanged. The operator has published the core to npm.
|
|
160
|
+
|
|
161
|
+
### Herdr plugin
|
|
162
|
+
|
|
163
|
+
- **Re-pin the published core 0.37.0 and close the checkout window.**
|
|
164
|
+
`plugins/herdr/runtime-lock.json` returns from the `herdr-checkout` carrier that 0.36.1 and
|
|
165
|
+
0.37.0 rode to production npm source `@junghanacs/entwurf@0.37.0` with the registry's
|
|
166
|
+
measured sha512 (`sha512-ETVgzMWf…7964A==`). The plugin manifest moves 0.36.0 → 0.37.0;
|
|
167
|
+
admission remains Herdr >= 0.9.0 and the one-build/one-pane/Linux shape is unchanged.
|
|
168
|
+
- **The same core capability through Herdr.** The runtime this snapshot acquires carries core
|
|
169
|
+
0.36.1 and 0.37.0: the Claude ACP driver on 0.90.0, Codex app-server socket ownership read
|
|
170
|
+
from the kernel, the durable app's transport and compaction tuning (#143) and its project
|
|
171
|
+
skill list (`4968ffd`). The measured Herdr is the 0.9.5 pin that landed in core 0.37.0
|
|
172
|
+
(`d8cd8f3`). This snapshot changes no rail, gate or mutant, and Pi's accepted range is the
|
|
173
|
+
same as 0.36.0's.
|
|
174
|
+
- **Upgrade by acquisition source, not just version.** A settled npm-source 0.36.0 installation
|
|
175
|
+
can rebind under the plugin README's ownership conditions. A host that installed an
|
|
176
|
+
intervening `herdr-checkout` candidate must explicitly deactivate by its own absolute runtime
|
|
177
|
+
path before reinstalling the npm-source snapshot. No operator installation or active session
|
|
178
|
+
is rewired by this release work.
|
|
179
|
+
|
|
180
|
+
### Source-specific verification
|
|
181
|
+
|
|
182
|
+
- Registry metadata reports version/latest 0.37.0, repair 0.12.8-repair.1. The downloaded
|
|
183
|
+
tarball is 11144951 bytes, SHA256
|
|
184
|
+
`d127a927e6a9f9c6561f86975dc30697aebaa5eeb2de463e8f0d765ff12035ee`, byte-identical to the
|
|
185
|
+
preserved accepted core candidate; independently computed sha512 equals `dist.integrity`, and
|
|
186
|
+
the registry-shipped runtime helper is byte-equal to this checkout's.
|
|
187
|
+
- The exact registry tarball passed the required Docker consumer without repacking
|
|
188
|
+
(`node:24-bookworm`, repoDigest `node@sha256:6dac556d…`).
|
|
189
|
+
- **The npm runtime swap against the real registry**, by the registry-shipped helper in sandboxed
|
|
190
|
+
user roots, 20/20 checks. The 0.36.0 runtime was seeded from its own committed lock; the swap
|
|
191
|
+
to 0.37.0 took one acquisition, the cached tarball's sha512 equals the lock and its sha256
|
|
192
|
+
equals the ready journal's observed digest and the accepted candidate. The `installing`
|
|
193
|
+
journal carried the 0.36.0 identity as `previousRuntime` and the `runtime-ready` journal
|
|
194
|
+
carries `null`; when acquisition began the 0.36.0 tree was still at the active address. A
|
|
195
|
+
manually seeded torn swap (the active tree moved to the backup address with a half candidate
|
|
196
|
+
in staging; not a killed process) was restored before acquisition and reported
|
|
197
|
+
`recovered: torn-swap-with-candidate`. An exact re-request acquired nothing and left journal
|
|
198
|
+
and tree byte-identical, and the owned removal reclaimed cache, runtime and journal. Not
|
|
199
|
+
certified by these cells: Herdr's install/update relocation, harness wiring, the installed
|
|
200
|
+
CLI's deactivate path, a model turn, or recovery from a real kill.
|
|
201
|
+
- **Focused gates on the branch**, with HEAD, index and work surface unchanged across them:
|
|
202
|
+
`check-herdr-supply` (11 assertions), `check-herdr-plugin` (49),
|
|
203
|
+
`check-herdr-plugin-profile` (14), `check-herdr-runtime-bootstrap` (31),
|
|
204
|
+
`check-herdr-activation` (33), `check-herdr-placement` (25), `check-herdr-fresh-call` (45)
|
|
205
|
+
and `check-gate-manifests` (982 committed mutants across 72 lanes validated, none executed).
|
|
206
|
+
`check-herdr-plugin-build` and `check-herdr-sandbox` were not run locally because they run
|
|
207
|
+
the operator's own herdr; they ride the pushed SHA's FULL floor in CI.
|
|
208
|
+
- Pending, and not claimed here: the pushed SHA's four-job CI with the qualification body, and
|
|
209
|
+
the public-ref install/use/deactivate journey on Herdr 0.9.5. Earlier npm or checkout-carrier
|
|
210
|
+
receipts cannot certify these source-specific axes.
|
|
211
|
+
|
|
212
|
+
## 0.37.0 - 2026-10-15
|
|
213
|
+
|
|
214
|
+
### pi-durable
|
|
215
|
+
|
|
216
|
+
- **The durable app forwards pi's transport and stops compacting beside a running turn (#143).**
|
|
217
|
+
The owned Harness settings now carry `SettingsManager.getTransport()` (pi's default `auto`)
|
|
218
|
+
into every request; the reference app had left the field out, so the SDK chose per connection.
|
|
219
|
+
`auto` permits a cached WebSocket continuation only when the provider's own body and prefix
|
|
220
|
+
conditions hold; it does not make every request a delta. Background compaction is off
|
|
221
|
+
(`backgroundTokens: 0`): a turn past the blocking threshold waits for the SDK's summary instead
|
|
222
|
+
of one being written beside it. Threshold, manual and overflow compaction stay the SDK's, on
|
|
223
|
+
pi's own compaction settings. The SDK engine, models, auth and storage are unchanged, and this
|
|
224
|
+
claims neither lower vendor overload nor better memory.
|
|
225
|
+
- **`entwurf pi-durable --resume` reopens a chosen session (#143).** It lists the current
|
|
226
|
+
directory's durable sessions from their files and the record store only (creation time, garden
|
|
227
|
+
id, last write, open elsewhere), most recently written first, and opens the chosen one as it
|
|
228
|
+
was saved, under its own garden id. Cancelling opens nothing. No session, a non-terminal, a
|
|
229
|
+
session open elsewhere, or a new session's argument beside it refuse by name, with no fallback.
|
|
230
|
+
`--continue` still opens the newest-created session.
|
|
231
|
+
- **The durable app lists a project's skills again.** The owned prompt handed pi's `skills`
|
|
232
|
+
setting to the skill loader as written, so a relative entry was read against the session
|
|
233
|
+
directory: a project's `.pi/settings.json` entry `../.claude/skills` named a `.claude/skills`
|
|
234
|
+
beside the project, in its parent, and the project's own skills were silently not listed.
|
|
235
|
+
Relative path entries are now read as pi reads them, the project's against its `.pi` and the
|
|
236
|
+
global ones against the agent directory. Both scopes are kept, the project's first, so a project
|
|
237
|
+
skill wins over a global one of the same name. Absolute and `~` entries are unchanged.
|
|
238
|
+
Patterns, package skills, `.agents/skills` and skill diagnostics are not supported by this
|
|
239
|
+
change. No project trust check is added: the durable app reads a project's settings without a
|
|
240
|
+
trust decision, as it did before.
|
|
241
|
+
|
|
242
|
+
### Herdr plugin
|
|
243
|
+
|
|
244
|
+
- **The measured Herdr moves to 0.9.5, the hotfix of 0.9.4.** `scripts/fixtures/herdr-supply.json`
|
|
245
|
+
pins v0.9.5 (`2ecf19a9`), protocol 22, with both Linux asset digests taken from the immutable
|
|
246
|
+
release and named by its attestation. On aarch64 the pin rests on a private CLI baseline:
|
|
247
|
+
version, protocol 22, 18 `integration status` rows unchanged from 0.9.4, and a residue-free
|
|
248
|
+
`server stop`. The full `check-herdr-sandbox` then passed at this pin on x86_64 in the CI run of
|
|
249
|
+
the SHA that introduced it (run 38667564413 at `d8cd8f3`, 12 assertions on private Herdr 0.9.5),
|
|
250
|
+
and the x86_64 asset is recorded as executed with that receipt; it has not run on aarch64. The
|
|
251
|
+
supply receipt mutant now removes the x86_64 receipt instead of flipping an unexecuted flag,
|
|
252
|
+
because no asset at this pin is unexecuted. Plugin admission (Herdr >= 0.9.0), the plugin
|
|
253
|
+
version and the runtime lock are unchanged.
|
|
254
|
+
- **A host that uses the Claude integration needs `herdr integration install claude` again
|
|
255
|
+
after upgrading to Herdr 0.9.5.** 0.9.5 raises its claude integration from v10 to v11 and leaves pi at v9. Over integrations seeded by
|
|
256
|
+
0.9.4 it reads claude as `outdated (v10 < v11)`, which the plugin's activation profile files as
|
|
257
|
+
`herdr-integration-outdated`, so the build and pane block [1] refuse by name until the
|
|
258
|
+
reinstall. In the measured 0.9.4-seeded private sandbox, the reinstall changed only the hook's
|
|
259
|
+
version line; the pi extension and the Claude settings stayed byte-identical. The plugin README
|
|
260
|
+
and the launch-rail document say so.
|
|
261
|
+
|
|
262
|
+
### Release boundary and verification
|
|
263
|
+
|
|
264
|
+
- **Scope.** A core minor over `v0.36.1`: #143 at `3a65c8d`, the Herdr 0.9.5 pin at `d8cd8f3`
|
|
265
|
+
and its CI record at `dbb8a32`, and the skill fix at `4968ffd`. Not in it: #142 (the ACP
|
|
266
|
+
thinking option), and the default thinking level of a new durable session named by a model
|
|
267
|
+
without `:<level>`, which starts at `off` where pi starts at its configured default; that is
|
|
268
|
+
recorded on #142 and not changed here. The Herdr manifest stays 0.36.0; plugin 0.37.0 is a
|
|
269
|
+
separate cut after the core is published.
|
|
270
|
+
- **Local evidence before this preparation is focused, not a whole pass.** Each affected
|
|
271
|
+
qualification group (PARTIAL) measured its own change with a green control, and none is
|
|
272
|
+
carried to another. #143 killed 81/81 in the `check-pi-durable-beside` group. The supply
|
|
273
|
+
receipt mutant re-aimed at `dbb8a32` killed with its whole `check-herdr-supply` group, 11/11;
|
|
274
|
+
that commit skipped CI, so the re-aimed mutant has no CI run yet. The skill fix killed 82/82 in
|
|
275
|
+
the `check-pi-durable-beside` group (receipt `d934e43c4dad5dc28b49a3a85c5a133d126df9558f2bc260087c1b34cf7422f9`),
|
|
276
|
+
with 900 of the 982 committed claims not run. The qualification body has not run on any of them.
|
|
277
|
+
- **Unpublished candidate carrier.** As in 0.36.1, `plugins/herdr/runtime-lock.json` names the
|
|
278
|
+
closed `herdr-checkout` source, because 0.37.0 has no published integrity yet. The npm 0.36.1
|
|
279
|
+
bytes and every existing tag are unchanged. Re-pinning registry bytes is the separate Herdr
|
|
280
|
+
0.37.0 cut, after the operator publishes core 0.37.0.
|
|
281
|
+
- **No local static floor; it is the exact CI's.** `check:hermetic` carries
|
|
282
|
+
`check-herdr-plugin-build` and `check-herdr-sandbox`, which must not run on the operator host,
|
|
283
|
+
and `release-gate`'s first MUST step is `pnpm run check:full`. By the operator's decision for
|
|
284
|
+
this cut only, `check:full` was not run locally and is owed whole to the prepared SHA's CI.
|
|
285
|
+
The decision is not inherited by a later cut.
|
|
286
|
+
- **LIVE, taken step by step, not as `release-gate --cut`.** The gate's 23 non-static MUST steps
|
|
287
|
+
and its BEHAVIOR step ran in the gate's own order, command, environment and working directory,
|
|
288
|
+
stopping at the first red, on the frozen candidate (`4968ffd` with this preparation's edits),
|
|
289
|
+
with the candidate fingerprint the same before and after each run. The first run passed steps
|
|
290
|
+
1-18 and failed `smoke-mux-lifecycle-live`: its pi-native sibling (`openai-codex/gpt-6-luna`)
|
|
291
|
+
was alive and answered with a shell call and "ACK" but never called the callback tool within
|
|
292
|
+
300 s. No input of that step changed in this cut, and the cause was not measured. By the
|
|
293
|
+
operator's choice it was run again once, unchanged, with steps 1-18 reused: steps 19-23 and the
|
|
294
|
+
BEHAVIOR step then passed. **MUST 23/23 PASS (18 + 5 on the second run), SKIP 0; BEHAVIOR 1/1
|
|
295
|
+
PASS.** `smoke-mux-lifecycle-live` passed 81 checks, `smoke-codex-fresh-live` 66 assertions
|
|
296
|
+
against an app-server started for each run in its own tmux session (named pane pid, a child
|
|
297
|
+
holding the kernel LISTEN inode, `gpt-5.6-luna` and `openai-codex/gpt-5.6-luna`, stopped by one
|
|
298
|
+
TERM after the run), and `smoke-pi-durable-fresh-live` 36 assertions. The gate sessions held no
|
|
299
|
+
ambient identity carrier. This is local LIVE evidence, not a release-gate verdict and not the
|
|
300
|
+
exact CI.
|
|
301
|
+
- **Exact CI owes the whole floor.** The prepared SHA's exact CI (the four required jobs, the
|
|
302
|
+
whole qualification body over the 982 committed claims, the re-aimed supply mutant included,
|
|
303
|
+
and `check-herdr-sandbox` on pinned Herdr 0.9.5) is the next checkpoint and is not presumed
|
|
304
|
+
PASS.
|
|
305
|
+
- **Publication boundary.** No make artifact, core tag, GitHub Release or npm publication is
|
|
306
|
+
claimed; they wait for the exact CI, the make decision and the operator.
|
|
307
|
+
|
|
7
308
|
## 0.36.1 - 2026-10-14
|
|
8
309
|
|
|
9
310
|
### ACP
|
package/CONTRIBUTING.md
CHANGED
|
@@ -30,7 +30,7 @@ pnpm check # everyday core (prints wall time; <=60s on the referenc
|
|
|
30
30
|
pnpm run check:full # full deterministic floor — the required PR gate
|
|
31
31
|
```
|
|
32
32
|
|
|
33
|
-
The deterministic floor is tiered (#70). `pnpm check` is the everyday core (biome, tsc, the vitest lanes, and the fast contract gates); `pnpm run check:full` adds the hermetic-integration and package/install tiers — including `check-gate-manifests`, the qualification HEAD (runner self-test, manifest-set validation, declared lane inventory; zero COMMITTED mutants executed — the self-test runs only its synthetic fixture mutants in tmp fixture repos — ~20s), but not the separately scheduled mutant-EXECUTING body `check-gate-qualification`, which CI runs on
|
|
33
|
+
The deterministic floor is tiered (#70). `pnpm check` is the everyday core (biome, tsc, the vitest lanes, and the fast contract gates); `pnpm run check:full` adds the hermetic-integration and package/install tiers — including `check-gate-manifests`, the qualification HEAD (runner self-test, manifest-set validation, declared lane inventory; zero COMMITTED mutants executed — the self-test runs only its synthetic fixture mutants in tmp fixture repos — ~20s), but not the separately scheduled mutant-EXECUTING body `check-gate-qualification`, which CI runs only on the weekly schedule or a manual `qualify=true` dispatch, as a drift diagnostic outside release acceptance (#144). Development never runs that whole body: a gate, mutant or matrix change runs only its affected exact-argv groups once, as PARTIAL receipts (`./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`), and no cut waits for the whole body. Exact membership is the named `check:*` scripts in `package.json`. Run `check:full` once on your frozen commit candidate — the pre-commit hook (`.husky/pre-commit`) carries only fast static checks (whitespace, lint, typecheck), not the full floor, so a green `pnpm run check:full` before commit is the evidence that your change holds (scheduling contract: AGENTS.md "Verification scheduling"). No install or build lifecycle script installs git hooks: a global `core.hooksPath` guard that chains to repository-local hooks runs its own checks, then delegates — to `.husky/pre-commit` here, unless an executable `.git/hooks/pre-commit` takes precedence.
|
|
34
34
|
|
|
35
35
|
For changes that touch backend launch, session lifecycle, or `_meta` shape, also run
|
|
36
36
|
the live ACP smokes that cover the touched rail — at minimum:
|
package/README.md
CHANGED
|
@@ -91,8 +91,13 @@ incomplete, drifted or mixed supply refuses by name.
|
|
|
91
91
|
```bash
|
|
92
92
|
entwurf pi-durable --provider <provider> --model <model-id> --width task-wide
|
|
93
93
|
entwurf pi-durable --continue
|
|
94
|
+
entwurf pi-durable --resume
|
|
94
95
|
```
|
|
95
96
|
|
|
97
|
+
`--continue` opens this directory's newest durable session. `--resume` lists its
|
|
98
|
+
sessions, most recently written first, by creation time, garden id and last write, and
|
|
99
|
+
reopens the one you choose as it was saved; a cancelled choice opens nothing.
|
|
100
|
+
|
|
96
101
|
The contact adds garden identity and two-way mailbox communication. Entwurf owns the
|
|
97
102
|
thin app/TUI composition (shipped as an emitted JS carrier); execution, models/auth, queues,
|
|
98
103
|
SQLite, transcripts and recovery remain the upstream SDK's:
|
package/VERIFY.md
CHANGED
|
@@ -95,8 +95,7 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
|
|
|
95
95
|
### The canonical floor — two entry points
|
|
96
96
|
|
|
97
97
|
- **Deterministic floor — two tiers (#70):** `pnpm check` is the everyday CORE — toolchain (lint + typecheck), the vitest lanes, and the pure-unit / behavioral-contract / source-topology gates plus the cheap static coherence checks. It prints its own total wall time; acceptance is ≤60s on the reference host `oracle` (an operator measurement, never a hard wall-clock gate on arbitrary hosts). `pnpm run check:full` is the FULL deterministic floor — the core plus the hermetic-integration and package/install tiers — and is what the frozen-candidate protocol, push CI, release-gate, and `prepublishOnly` run. Exact membership is the named `check:*` group scripts in `package.json` (the executable SSOT — this document records meaning and principles, not the command list); a gate changes tier by semantic-class decision, never by getting faster or slower. One core member assumes a build output: the beside test `pi-extensions/entwurf-control.test.ts` (reached through `check-tests-beside-behavior`) registers the COMPILED bridge and refuses by name when it is absent. `prepare` normally builds it at install; after an `--ignore-scripts` install or a bridge source change, run `pnpm run build-bridge` (in the sandbox candidate when verifying one) before the core. The FULL tier carries the qualification HEAD (`check-gate-manifests`, through `check:hermetic`); the everyday core does not, and neither tier carries the separately scheduled mutant-executing body (`check-gate-qualification`).
|
|
98
|
-
- **Discriminating power of that floor:** `./run.sh check-gate-qualification` (scheduled, not ambient: the whole body runs only as the bare call — in the CI `check` job on
|
|
99
|
-
- **Push matching is conservative and hunk-aware (#137).** Git ranges read mutant manifests from the named HEAD commit, not a later working tree. Signature sources and the existing deciding machinery always match at file level, including paths that are also subjects. Only TOML subjects (`.toml`) may skip, and only when every mutant's joined `find` span occurs exactly once on both blobs, stays on the same lines, and intersects no zero-context diff hunk. Markdown, JSON, code and unknown subject types remain file-level. An outside-find early return/import/caller change can weaken a code mutant without editing its literal find. A presence/`includes` oracle whose required literal is shorter than the find can be re-satisfied by an out-of-span restatement; a scratch-repo probe measured exactly that false SKIP for `ADMISSION-LEGACY-DOCUMENTED` in `DELIVERY.md`. A later duplicate JSON key wins under `JSON.parse`, which every current JSON data oracle uses. TOML refuses a redefined key, and the current TOML oracles are exact-count/absence checks; a future TOML subject with a presence oracle reopens this boundary. `QUALIFY-FILTER-TOML-ONLY-REFINEMENT` pins Markdown/JSON at file level. Moved, absent, ambiguous, binary or unreadable spans/diffs/manifests run the body with a named reason; renames are compared as delete/add. `--files-from` has no hunk evidence and retains path identity. There is no Herdr filename or release-shape exemption. Span matching is not proof of unchanged kill-power. The rule narrows per-push qualification to those declared TOML spans; forced/scheduled and exact-SHA release qualification remain the backstop. This narrows redundant data-only pushes, never the FULL floor or exact-SHA release body's obligation; a body-less plugin SHA cannot supply the core SHA's evidence.
|
|
98
|
+
- **Discriminating power of that floor:** `./run.sh check-gate-qualification` (scheduled, not ambient: the whole body runs only as the bare call — in the CI `check` job on the weekly `schedule` or a `workflow_dispatch -f qualify=true`, never on a push. It is a drift diagnostic, not a release axis (#144): no cut waits for it and the exact-SHA release oracle reads only the push run's four required jobs. Development runs no whole body (#133): a lane that changes a gate/mutant/matrix runs its affected exact-argv groups once, after review, as PARTIAL receipts — `./run.sh check-gate-qualification --group '<argv JSON>' --receipt <absolute path outside the repo>`, whose arguments reach the runner's parser unchanged and are refused there by name, before any body or snapshot, when malformed, missing or repeated. A receipt is a measurement of one group on its own candidate, never a qualification pass and never coverage of a release. Neither form is inside the default check chains; a semver TAG push triggers no CI at all) re-plants committed defect mutants (`scripts/mutants/*.json`, one per closed defect class) in an isolated snapshot repo and requires each to turn its gate red **bounded and at its claimed `[QK:<claim>]` signature** — a wrong-reason red fails, a baseline-red control voids the whole group, and the runner is negative-controlled on every run (zero-match/multi-match/survived/wrong-reason/hang/control-red/impurity). This measures whether the deterministic gates still *block* what they claim to block; it is **not a new evidence level** (L0–L5 are untouched) and never substitutes for LIVE evidence. Per-cut records cite claim IDs + killed mutant IDs — "N checks passed" alone is not evidence. `check-agy-permission-matrix` complements it with the enumerated permission contract space (literal cells + stated exclusion rules, oracle independent of the SUT). The gate's HEAD is separable and IS in the floor: `check-gate-manifests` runs the runner self-test, validates the committed manifest set against the origin index, and asserts the declared lane inventory, while executing zero COMMITTED mutants (the self-test runs only its synthetic fixture mutants, in tmp fixture repos) and never snapshotting the repo — three of the five reds qualification has ever produced in CI died in that head, in under five seconds.
|
|
100
99
|
- **The snapshot is source-only (#125).** It replicates the git work surface and never copies an ignored artifact from the checkout. A gate that consumes an ignored build output — the compiled `entwurf-bridge` a pi citizen registers — declares it on each of its mutants (`"build": {"argv": [...], "output": "<dir>"}`, one declaration per gate group). For that group only, the runner builds the output from the snapshot's own bytes before the control, rebuilds it after every mutation and from the restored bytes before the post-control (which must reproduce the baseline digest), never counts a build red as a kill, voids a run whose gate writes into the output, and removes the output when the group ends. The runner self-test owns this as `[QK:QUALIFY-BUILD-*]`.
|
|
101
100
|
- **Live floor:** `LIVE=1 ./run.sh release-gate <scratch-project-dir> --cut` — `pnpm run check:full` + the v2-native live gates + the ACP plugin acceptance floor. It reports a **two-tier summary**:
|
|
102
101
|
- **MUST tier** (release-blocking — owns the exit code; "green" applies only here): `pnpm run check:full`, `smoke-entwurf-v2-matrix-live`, `check-bridge`, `doctor-pi-provider` (#81 — `check-bridge` proves the launcher this checkout SHIPS; this proves the invocation the operator's pi provider actually EXECS, by booting it and requiring the entwurf verb set back, because `command -v` answers yes for a command that exits 127; wired as a step on 2026-08-19 after a relocated pnpm cmd-shim cost a cut sixteen LIVE steps before the same fact surfaced at `smoke-acp-bundled-mcp-live`), the resident-garden-guard zero-token half (record birth / record-keyed socket / attach-on-reopen), the `smoke-acp-*-live` ACP plugin smokes (socket-citizen / raw-turn / overlay / provider / session-reuse / carrier-augment / memory-containment / rgg / mcp / skill / bundled-mcp / v2-send), the axis wired in on 2026-07-31 that the aggregate had simply never listed (`smoke-claude-native-resume-live`), `smoke-entwurf-chain-live` — the cross-harness delivery chain (native Claude Code → pi GPT → pi ACP Sonnet → mailbox terminus) proving sender identity and replyability at every hop plus a real read receipt at the end — the integrated `smoke-mux-lifecycle-live` (its own note below), and the two OMP steps 0.16.0 wired: `smoke-omp-receive-live` (the addressed roundtrip into a live omp citizen; it reads the capability registry and decides its own outcome rather than passing by default) and `smoke-omp-fresh-live` (the clause 7 receipt the release stop now requires). (`smoke-session-id-name` is gone — #50 C3: its `--session-id`/`--name` substrate has no entwurf consumer anymore.)
|
|
@@ -116,7 +115,7 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
|
|
|
116
115
|
>
|
|
117
116
|
> A cut that touches the prompt-lifecycle contract (no wall clock on a running turn) owes one long-turn acceptance the aggregate floor is too short to carry: `LIVE=1 ./run.sh smoke-acp-long-turn-live` drives a real turn whose tool work outlasts the retired 600s cutoff and requires exactly one cold ACP bootstrap in the transcript. It takes >12 minutes by construction and is on-demand, not part of `release-gate`.
|
|
118
117
|
>
|
|
119
|
-
> **The integrated mux lifecycle IS a release-gate MUST.** `LIVE=1 ./run.sh smoke-mux-lifecycle-live` enters through a real MCP `tools/call` on the shipped bridge launcher and follows one citizen the whole way: fresh-call launch receipt, the sibling's own nonce callback whose SENDER ENVELOPE is the address, an `entwurf_v2` control-socket send that lands in the sibling's own transcript, `entwurf_resume_call` REFUSED while that citizen is live, a stable-handle close proving pane and socket gone with the record preserved, delivery to the dormant citizen refused honestly, then the public `entwurf_resume_call` — whose LAUNCH and OBSERVATION receipts stay apart — and finally an `entwurf_v2` send the resumed session answers with a fact it was told BEFORE the window closed. That last step is the point: a socket answering under the same garden id proves a process stood up at that address, and only the recall proves the same conversation came back. Both pi provider shapes are driven to it (native `openai-codex/gpt-6-
|
|
118
|
+
> **The integrated mux lifecycle IS a release-gate MUST.** `LIVE=1 ./run.sh smoke-mux-lifecycle-live` enters through a real MCP `tools/call` on the shipped bridge launcher and follows one citizen the whole way: fresh-call launch receipt, the sibling's own nonce callback whose SENDER ENVELOPE is the address, an `entwurf_v2` control-socket send that lands in the sibling's own transcript, `entwurf_resume_call` REFUSED while that citizen is live, a stable-handle close proving pane and socket gone with the record preserved, delivery to the dormant citizen refused honestly, then the public `entwurf_resume_call` — whose LAUNCH and OBSERVATION receipts stay apart — and finally an `entwurf_v2` send the resumed session answers with a fact it was told BEFORE the window closed. That last step is the point: a socket answering under the same garden id proves a process stood up at that address, and only the recall proves the same conversation came back. Both pi provider shapes are driven to it (native `openai-codex/gpt-6.1-sol:low` and recorded-ACP `entwurf/claude-sonnet-5-5`, the only shape that re-injects a bridge extension), and the Claude Code cell ends where its capability ends: its resume is refused as `target-not-pi` with no window opened and no lock residue (the per-gid coordination lock is released).
|
|
120
119
|
>
|
|
121
120
|
> One cell cannot be fully fenced, and that is recorded rather than glossed: the recorded-ACP pi cell runs under the operator's REAL home, because its provider spawns `claude` as a child that authenticates from there — measured, a fenced HOME kills that turn with `Authentication required` before the model is ever reached, and `CLAUDE_CONFIG_DIR` alone does not fix it. That is the same trade `smoke-acp-bundled-mcp-live` already makes. While that cell runs, its citizen's control socket and per-gid lock exist under the operator's own `~/.pi/entwurf-control` and `~/.pi/entwurf-v2-locks`; its meta store stays fixture, so no garden record is minted outside the fixture, and the run ends by proving all six real roots hold the entry sets they started with, with no fixture garden id and no leftover lock.
|
|
122
121
|
>
|
|
@@ -210,16 +209,19 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
|
|
|
210
209
|
|
|
211
210
|
Do not collapse source, package, fixture, and native-host evidence into one “green.”
|
|
212
211
|
|
|
213
|
-
**Native durable contact (#129, #130 carrier).**
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
212
|
+
**Native durable contact (#129, #130 carrier).** Three deterministic beside-test/mutant
|
|
213
|
+
coordinates in `check:contracts` split the durable contact by the file that carries each claim's QK
|
|
214
|
+
(#144): a carrier or native-module mutant runs its one file, the rest run four. `check-pi-durable-beside` holds the adapter, the installed
|
|
215
|
+
carrier/SDK-set verifier, the preflight and the owner join. `check-pi-durable-carrier` holds the
|
|
216
|
+
carrier's relocation grammar, resolver and maintainer emitter (its `--check` reads only the owned
|
|
217
|
+
in-repo source, #141; the overlay patch is retired, and `--origin <clone>` checks provenance only)
|
|
218
|
+
and the task footer and sandboxed children described below. `check-pi-durable-native-module` is the coordinate of
|
|
219
|
+
the bootstrap's explicit `--native-module` ingress
|
|
220
|
+
(#130 P2) with its paired `--native-module-dir` (#134). That ingress is driven through the packaged `main`'s own
|
|
219
221
|
seams: initialization before the TUI and the open, named refusals, the identity and directory
|
|
220
222
|
guards, the top-level `*.extension.mjs` filter and byte-wise order, cross-module name refusals, the
|
|
221
|
-
contact-first order by reference, and the bridge spawn *spec* (not the child's inheritance).
|
|
222
|
-
carrier's task footer (#134) is observed in ONE sandboxed child that loads the committed carrier
|
|
223
|
+
contact-first order by reference, and the bridge spawn *spec* (not the child's inheritance). In
|
|
224
|
+
`check-pi-durable-carrier`, the carrier's task footer (#134) is observed in ONE sandboxed child that loads the committed carrier
|
|
223
225
|
through its own resolver: the real carrier runtime opened and closed with no model (graph observed
|
|
224
226
|
for the session, `/tasks` toggling only the panel), then continued after one native background task
|
|
225
227
|
was committed into that session through the SDK's public `Conversation.commit` (the carrier's graph
|
|
@@ -227,8 +229,15 @@ holds that node and the badge counts it, `pending` while recovered), and the car
|
|
|
227
229
|
`durableLayout` drawn by the published pi-tui renderer on a fake terminal across rows 1–8 × cols
|
|
228
230
|
1–12, count changes and resizes, against the pinned upstream screen for the zero-task case. Its
|
|
229
231
|
editor is a fixed stand-in: the real `CustomEditor`, overlays, emoji width and a consumer's own task
|
|
230
|
-
are the visible-terminal and consumer subjects.
|
|
231
|
-
|
|
232
|
+
are the visible-terminal and consumer subjects. The 1.2 bootstrap child also observes `--resume`
|
|
233
|
+
reopening the chosen session and cancelling to nothing (#143). Two more sandboxed children reach the
|
|
234
|
+
reference app's settings and prompt mapping: one drives the real bootstrap against a loopback
|
|
235
|
+
WebSocket Responses endpoint, whose received frames decide the forwarded transport and its
|
|
236
|
+
continuation and the reference compaction policy (no background summary; blocking and overflow
|
|
237
|
+
kept, #143); the other renders the carrier prompt's skills section with no model, against a fixture
|
|
238
|
+
of both settings scopes, an absolute entry, a same-name pair and a wrong-base decoy.
|
|
239
|
+
`check-pi-runtime-version` asks the
|
|
240
|
+
same installed verifier (`check-pi-durable-beside`) whether this checkout resolves exactly the pinned SDK set (the native set; the PATH
|
|
232
241
|
host is setup's subject), and `check-pi-import-surface` asserts the carrier fence. The separate
|
|
233
242
|
`check-pi-durable-contact`, `check-pi-durable-send` and `check-pi-durable-receive` are
|
|
234
243
|
CHECKOUT-ONLY SDK/contact gates: they run the checkout's own carrier — verified first, refused by
|
|
@@ -253,7 +262,7 @@ initializing only its top-level `*.extension.mjs` (#134) and a directory without
|
|
|
253
262
|
before anything opens — and the HOST kept a separate subject — a real pi 1.1.0
|
|
254
263
|
binary (the previous generation) beside the pinned native set is a named pi FAIL with zero Pi wiring while pi-durable still
|
|
255
264
|
PASSes — not native admission. The carrier's rebuild
|
|
256
|
-
equality is the owned source's emission (#141): the
|
|
265
|
+
equality is the owned source's emission (#141): the carrier claim `PI-DURABLE-CARRIER-EMIT-SOURCE-EQUAL`
|
|
257
266
|
on every floor, `emit-pi-durable-carrier --check` as its CLI. The emitter's exact Node is red in the CI
|
|
258
267
|
`check` job (`ENTWURF_REQUIRE_EMITTER_NODE=1`) and a named SKIP on a host running another Node, not
|
|
259
268
|
acceptance there. First-release visible fresh/callback and native
|
|
@@ -262,10 +271,10 @@ caller/target/cross-harness LIVE are owed by `smoke-pi-durable-fresh-live`, a re
|
|
|
262
271
|
|
|
263
272
|
| Axis | Required proof | Limit |
|
|
264
273
|
|---|---|---|
|
|
265
|
-
| Source | `pnpm run check:full`
|
|
274
|
+
| Source | `pnpm run check:full` in the prepared SHA's CI `check` job | Does not prove an installed consumer. Kill-power of the committed claims is not re-measured per release (#144); the release record says so and lists any earlier-candidate PARTIAL separately. |
|
|
266
275
|
| Packed install | `check-pack-install` | Real tarball, but checkout-visible. |
|
|
267
276
|
| Linux artifact consumer | required `check-install-container` CI job against one preserved candidate | Fixtures prove package/oracle shape, not a real Claude lifecycle. |
|
|
268
|
-
| Exact release commit | all required CI jobs green
|
|
277
|
+
| Exact release commit | the exact SHA's push run: all four required CI jobs green (the qualification body is not read, #144) | A different green SHA is not transferable evidence. |
|
|
269
278
|
| macOS Entwurf-only install | required `macos-install-surface` CI job at the exact release SHA | Shape-only, CERTIFIED (CI): certifies the Entwurf-only install path on macOS only — never Claude/Copilot/OMP/agy wiring, the pi rail, ACP or mux. Promoted from non-voting (`continue-on-error`) to required in 0.20.0 after its first CERTIFIED (CI) green on a GitHub Actions `macos-latest` runner (not a physical host): run 34303884286 @ `70eda03` (2026-09-09), 65s, all 10 steps success — the packed candidate installed clean, `entwurf --help` and `entwurf check-bridge` ran (the latter listing the seven current `entwurf-bridge` MCP tools), an all-harness-absent `entwurf setup` reached `result: green` across the five documented SKIP probes (`pi`/`claude`/`agy`/`copilot`/`omp`), and five checked paths (`.pi`, `settings.json`, `.gemini`, `.copilot`, `auth.json.bak`) plus a byte-identical `auth.json` proved zero harness/credential writes. A macOS runner failure now blocks every release cut, the same as any other required job. |
|
|
270
279
|
| LIVE runtime | `LIVE=1 ./run.sh release-gate <scratch> --cut` plus any shipped on-demand backend axis | `--cut` enforces `SKIP=0`; a red wired gate blocks the cut. |
|
|
271
280
|
| Native Claude host | installed strict doctor against a new real session | Missing live join is `NOT CERTIFIED`, not a fixture PASS. |
|
|
@@ -508,7 +517,7 @@ Pass: user/assistant turns accumulate normally; the transcript is not broken/emp
|
|
|
508
517
|
|
|
509
518
|
The minimum passing bar:
|
|
510
519
|
|
|
511
|
-
1. **Deterministic floor green:** `pnpm run check:full` passes (the core tier plus the hermetic-integration and package/install tiers, incl. `check-pack`),
|
|
520
|
+
1. **Deterministic floor green:** `pnpm run check:full` passes (the core tier plus the hermetic-integration and package/install tiers, incl. `check-pack`), in the exact-SHA CI push run of the same prepared candidate (criterion 2's run). The qualification body is not a criterion (#144).
|
|
512
521
|
2. **All four required CI jobs green on the exact release commit:** `check`, `install-surface`, the required Linux `artifact-consumer`, and `macos-install-surface` — promoted from non-voting to required in 0.20.0 (see the release acceptance axes table above for what its green run does and does not certify); preserve the Linux artifact-consumer's tarball digest and image identity. A macOS runner failure now blocks the cut like any other required job.
|
|
513
522
|
3. **Live floor MUST green:** `LIVE=1 ./run.sh release-gate <dir> --cut` exits 0 reporting `MUST PASS=N FAIL=0 SKIP=0`; with `--cut` a single SKIP is red, so the exit code itself now carries this condition. A BEHAVIOR FAIL is advisory, not blocking.
|
|
514
523
|
4. **Native-host doctor green where the Claude meta-bridge is claimed:** a new post-install Claude session exists, live evidence is present, and the installed `doctor-meta-bridge` exits 0. `NOT CERTIFIED` is a release failure for that host, not a skip.
|
package/docs/setup-clean-host.md
CHANGED
|
@@ -358,6 +358,7 @@ tree (for example an override that binds pi-durable's `pi-ai` to an older publis
|
|
|
358
358
|
```bash
|
|
359
359
|
entwurf pi-durable --provider <provider> --model <exact catalog id> --width task-wide
|
|
360
360
|
entwurf pi-durable --continue # this directory's newest durable session
|
|
361
|
+
entwurf pi-durable --resume # choose one of this directory's durable sessions
|
|
361
362
|
```
|
|
362
363
|
|
|
363
364
|
The bootstrap imports only the compiled closure shipped beside it
|
|
@@ -107,9 +107,24 @@ import * as fs from "node:fs";
|
|
|
107
107
|
import * as path from "node:path";
|
|
108
108
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
109
109
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
110
|
-
import { defaultMetaMailboxDir, defaultMetaReceiversDir, defaultMetaSendersDir, defaultMetaSessionsDir, readAddressableMetaIdentity, readMetaReceiverMarker, readMetaSenderMarker, requireGardenId, upsertMetaSession, writeMetaReceiverMarker, writeMetaSenderMarker, } from "./lib/meta-session.js";
|
|
110
|
+
import { defaultMetaMailboxDir, defaultMetaReceiversDir, defaultMetaSendersDir, defaultMetaSessionsDir, listAllMetaIdentitiesDir, readAddressableMetaIdentity, readMetaReceiverMarker, readMetaSenderMarker, requireGardenId, upsertMetaSession, writeMetaReceiverMarker, writeMetaSenderMarker, } from "./lib/meta-session.js";
|
|
111
111
|
/** The backend id this contact mints under. */
|
|
112
112
|
export const PI_DURABLE_BACKEND = "pi-durable";
|
|
113
|
+
/**
|
|
114
|
+
* The garden ids the record store holds for these durable sessions (#143 `--resume`), read only: a session no record
|
|
115
|
+
* names is absent, and an unreadable record is counted, never guessed.
|
|
116
|
+
*/
|
|
117
|
+
export function piDurableGardenIds(nativeSessionIds, sessionsDir = defaultMetaSessionsDir()) {
|
|
118
|
+
const wanted = new Set(nativeSessionIds);
|
|
119
|
+
const { identities, errors } = listAllMetaIdentitiesDir(sessionsDir);
|
|
120
|
+
const gardens = new Map();
|
|
121
|
+
for (const identity of identities) {
|
|
122
|
+
if (identity.backend === PI_DURABLE_BACKEND && wanted.has(identity.nativeSessionId)) {
|
|
123
|
+
gardens.set(identity.nativeSessionId, identity.gardenId);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return { gardens, unreadable: errors.length };
|
|
127
|
+
}
|
|
113
128
|
/** The durable Extension's name, owned exactly. */
|
|
114
129
|
export const PI_DURABLE_EXTENSION_NAME = "entwurf";
|
|
115
130
|
/** Every bridge tool this contact exposes. A tool outside this list is not callable here. */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junghanacs/entwurf",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.1",
|
|
4
4
|
"description": "Visible sibling sessions across independent agent harnesses: launch in Herdr or tmux, reopen pi in tmux, and deliver messages by garden id; native bridges and Claude/Cortex ACP adapters.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -123,7 +123,8 @@
|
|
|
123
123
|
"husky": "^9.1.7",
|
|
124
124
|
"rregex": "1.13.1",
|
|
125
125
|
"typescript": "^6.0.2",
|
|
126
|
-
"vitest": "4.1.9"
|
|
126
|
+
"vitest": "4.1.9",
|
|
127
|
+
"ws": "8.21.3"
|
|
127
128
|
},
|
|
128
129
|
"scripts": {
|
|
129
130
|
"prepare": "npm run --silent build-bridge 1>&2",
|
|
@@ -193,7 +194,7 @@
|
|
|
193
194
|
"check:core": "pnpm run check:toolchain && pnpm run check:vitest && pnpm run check:contracts",
|
|
194
195
|
"check:toolchain": "pnpm lint && pnpm typecheck",
|
|
195
196
|
"check:vitest": "./run.sh check-mux-fresh-call && ./run.sh check-acp-sdk-surface && ./run.sh check-pi-queue-oracle && ./run.sh check-tests-beside-behavior",
|
|
196
|
-
"check:contracts": "./run.sh check-demo-reproducibility && ./run.sh check-shell-quote && ./run.sh check-entwurf-session-identity && ./run.sh check-meta-session && ./run.sh check-meta-v3-record && ./run.sh check-mailbox-receipt-state && ./run.sh check-entwurf-capabilities && ./run.sh check-harness-admission-parity && ./run.sh check-capability-bundle-reach && ./run.sh check-meta-mailbox-state-write && ./run.sh check-meta-receiver-marker && ./run.sh check-meta-capability-source && ./run.sh check-model-lock && ./run.sh check-dep-versions && ./run.sh check-node-floor-coherence && ./run.sh check-claude-floor-coherence && ./run.sh check-copilot-statusline && ./run.sh check-pi-import-surface && ./run.sh check-env-namespace && ./run.sh check-pi-runtime-version && ./run.sh check-pi-preflight && ./run.sh check-project-trust-handler && ./run.sh check-entwurf-v2-contract && ./run.sh check-entwurf-v2-send && ./run.sh check-entwurf-v2-runner && ./run.sh check-control-send-receipt && ./run.sh check-compaction-send-guard && ./run.sh check-entwurf-resume-args && ./run.sh check-entwurf-v2-native-push && ./run.sh check-entwurf-v2-production && ./run.sh check-entwurf-v2-surface && ./run.sh check-entwurf-bridge-pi-free && ./run.sh check-resume-launch-identity && ./run.sh check-mux-placement && ./run.sh check-mux-launch && ./run.sh check-mux-resume-call && ./run.sh check-mux-parent-artifact && ./run.sh check-mux-launcher-fence && ./run.sh check-entwurf-v2-visible-resume && ./run.sh check-control-socket-path && ./run.sh check-meta-listing && ./run.sh check-entwurf-fact-provider && ./run.sh check-herdr-placement && ./run.sh check-herdr-fresh-call && ./run.sh check-herdr-supply && ./run.sh check-fresh-call-dispatch && ./run.sh check-entwurf-peers-surface && ./run.sh check-entwurf-self-address && ./run.sh check-entwurf-deliverability && ./run.sh check-native-push-adapter && ./run.sh check-native-push-register && ./run.sh check-auth-boundary && ./run.sh check-acp-overlay && ./run.sh check-acp-tool-surface && ./run.sh check-acp-event-mapper && ./run.sh check-acp-prompt-builder && ./run.sh check-acp-config && ./run.sh check-acp-session-store && ./run.sh check-acp-carrier-augment && ./run.sh check-acp-foreground-only && ./run.sh check-acp-set-model-readback && ./run.sh check-acp-vendor-rejection && ./run.sh check-codex-sender-identity && ./run.sh check-codex-native-push && ./run.sh check-pi-durable-beside",
|
|
197
|
+
"check:contracts": "./run.sh check-demo-reproducibility && ./run.sh check-shell-quote && ./run.sh check-entwurf-session-identity && ./run.sh check-meta-session && ./run.sh check-meta-v3-record && ./run.sh check-mailbox-receipt-state && ./run.sh check-entwurf-capabilities && ./run.sh check-harness-admission-parity && ./run.sh check-capability-bundle-reach && ./run.sh check-meta-mailbox-state-write && ./run.sh check-meta-receiver-marker && ./run.sh check-meta-capability-source && ./run.sh check-model-lock && ./run.sh check-dep-versions && ./run.sh check-node-floor-coherence && ./run.sh check-claude-floor-coherence && ./run.sh check-copilot-statusline && ./run.sh check-pi-import-surface && ./run.sh check-env-namespace && ./run.sh check-pi-runtime-version && ./run.sh check-pi-preflight && ./run.sh check-project-trust-handler && ./run.sh check-entwurf-v2-contract && ./run.sh check-entwurf-v2-send && ./run.sh check-entwurf-v2-runner && ./run.sh check-control-send-receipt && ./run.sh check-compaction-send-guard && ./run.sh check-entwurf-resume-args && ./run.sh check-entwurf-v2-native-push && ./run.sh check-entwurf-v2-production && ./run.sh check-entwurf-v2-surface && ./run.sh check-entwurf-bridge-pi-free && ./run.sh check-resume-launch-identity && ./run.sh check-mux-placement && ./run.sh check-mux-launch && ./run.sh check-mux-resume-call && ./run.sh check-mux-parent-artifact && ./run.sh check-mux-launcher-fence && ./run.sh check-entwurf-v2-visible-resume && ./run.sh check-control-socket-path && ./run.sh check-meta-listing && ./run.sh check-entwurf-fact-provider && ./run.sh check-herdr-placement && ./run.sh check-herdr-fresh-call && ./run.sh check-herdr-supply && ./run.sh check-fresh-call-dispatch && ./run.sh check-entwurf-peers-surface && ./run.sh check-entwurf-self-address && ./run.sh check-entwurf-deliverability && ./run.sh check-native-push-adapter && ./run.sh check-native-push-register && ./run.sh check-auth-boundary && ./run.sh check-acp-overlay && ./run.sh check-acp-tool-surface && ./run.sh check-acp-event-mapper && ./run.sh check-acp-prompt-builder && ./run.sh check-acp-config && ./run.sh check-acp-session-store && ./run.sh check-acp-carrier-augment && ./run.sh check-acp-foreground-only && ./run.sh check-acp-set-model-readback && ./run.sh check-acp-vendor-rejection && ./run.sh check-codex-sender-identity && ./run.sh check-codex-native-push && ./run.sh check-pi-durable-beside && ./run.sh check-pi-durable-carrier && ./run.sh check-pi-durable-native-module",
|
|
197
198
|
"check:hermetic": "./run.sh check-bridge-delivery && ./run.sh smoke-pi-attach && ./run.sh check-fresh-cut-gate && ./run.sh check-hook-launch-topology && ./run.sh check-meta-hook-session-switch && ./run.sh check-copilot-birth-hook && ./run.sh check-copilot-receive-arm && ./run.sh check-copilot-launch && ./run.sh check-pi-launch && ./run.sh check-codex-app-server-launch && ./run.sh check-meta-identity-consumers && ./run.sh check-socket-probe && ./run.sh smoke-meta-honesty && ./run.sh check-meta-doctor-oracle && ./run.sh check-agy-permission-matrix && ./run.sh smoke-agy-statusline-state && ./run.sh smoke-copilot-statusline-state && ./run.sh smoke-copilot-mcp-state && ./run.sh smoke-omp-bridge-state && ./run.sh smoke-omp-mcp-state && ./run.sh smoke-omp-receive-state && ./run.sh check-omp-birth-hook && ./run.sh check-omp-receive-arm && ./run.sh check-omp-fresh-preflight && ./run.sh smoke-agy-hooks-state && ./run.sh smoke-pi-provider-state && ./run.sh smoke-user-scope-citizen && ./run.sh smoke-meta-prune && ./run.sh smoke-meta-keyset-guard && ./run.sh check-meta-manifest-schema && ./run.sh check-entwurf-control-rpc && ./run.sh check-entwurf-bridge-boot && ./run.sh check-probe-bridge-command && ./run.sh check-meta-facts && ./run.sh check-peer-facts && ./run.sh check-herdr-plugin && ./run.sh check-herdr-plugin-profile && ./run.sh check-herdr-plugin-build && ./run.sh check-herdr-runtime-bootstrap && ./run.sh check-herdr-activation && ./run.sh check-agy-sender-identity && ./run.sh check-acp-provider-surface && ./run.sh check-acp-stop-reason && ./run.sh check-acp-prompt-lifecycle && ./run.sh check-acp-usage-accounting && ./run.sh check-acp-launch-namespace && ./run.sh check-acp-stream-hooks && ./run.sh check-acp-backend-preflight && ./run.sh check-acp-session-reuse && ./run.sh check-typing-call-fence && ./run.sh check-gate-manifests && ./run.sh check-release-gate-outcomes && ./run.sh check-probe-ordering && ./run.sh check-probe-cli-shim && ./run.sh check-acp-cortex && ./run.sh check-codex-bridge-identity && ./run.sh check-pi-bridge-sender && ./run.sh check-pi-mcp-register && ./run.sh check-pi-mcp-bridge && ./run.sh check-codex-birth-hook && ./run.sh smoke-codex-config-state && ./run.sh smoke-codex-birth && ./run.sh check-herdr-sandbox",
|
|
198
199
|
"check:package": "./run.sh check-install-surface && ./run.sh smoke-meta-install-state && ./run.sh smoke-agy-install-state && ./run.sh smoke-setup-verdict && ./run.sh check-pack-pin-matcher && ./run.sh check-pack-consumer-roots && ./run.sh check-package-source-routing && ./run.sh check-install-preflight && ./run.sh check-pack"
|
|
199
200
|
},
|