@junghanacs/entwurf 0.34.0 → 0.34.2
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/CHANGELOG.md +207 -0
- package/CONTRIBUTING.md +1 -1
- package/README.md +4 -7
- package/VERIFY.md +1 -1
- package/docs/setup-clean-host.md +18 -0
- package/package.json +2 -2
- package/run.sh +5 -3
- package/scripts/check-gate-qualification.ts +2 -2
- package/scripts/check-herdr-activation.ts +210 -10
- package/scripts/check-herdr-plugin-build.ts +235 -6
- package/scripts/check-meta-doctor-oracle.sh +86 -1
- package/scripts/herdr-activation.mjs +66 -1
- package/scripts/herdr-doctor-mode.mjs +26 -0
- package/scripts/herdr-plugin-activate.mjs +112 -76
- package/scripts/herdr-plugin-deactivate.mjs +41 -2
- package/scripts/meta-bridge-doctor.sh +79 -20
- package/scripts/mutants/herdr-activation.json +106 -0
- package/scripts/mutants/herdr-plugin-build.json +66 -0
- package/scripts/mutants/herdr-runtime-bootstrap.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,213 @@ All notable changes to this project will be documented here. Format follows [Kee
|
|
|
4
4
|
|
|
5
5
|
## Unreleased
|
|
6
6
|
|
|
7
|
+
## 0.34.2 - 2026-10-11
|
|
8
|
+
|
|
9
|
+
### Release coordination
|
|
10
|
+
|
|
11
|
+
- **A patch cut for #136.** Coordinated by the Claude Code Fable citizen `20261011T132613-9a46b6`,
|
|
12
|
+
implemented by Claude Code Opus `20261008T094901-5d295e` as sole writer on the thinkpad that
|
|
13
|
+
holds the failing installation, and independently reviewed by a pi `gpt-6.1-sol` sibling. GLG
|
|
14
|
+
authorized the commits, main and this release. This section is written at prepare time: the
|
|
15
|
+
`check:full` and exact-SHA CI results will be recorded at make time in the GitHub release and
|
|
16
|
+
#136, not claimed here.
|
|
17
|
+
- **GLG waived the LIVE `release-gate --cut` for this cut** (doctor-only change, no LIVE surface
|
|
18
|
+
touched). The deterministic floor `check:full` and the exact-SHA CI body are this release's
|
|
19
|
+
evidence, and acceptance 4 (host rebind + new Claude session) is owed after publication. This is
|
|
20
|
+
not a PASS and not a standing waiver.
|
|
21
|
+
- **The plugin runtime lock rides `herdr-checkout` for this window.** `certifyLockCoherence`
|
|
22
|
+
(`scripts/herdr-runtime.mjs:353-361`) refuses an npm lock whose version differs from the
|
|
23
|
+
checkout's package, so `plugins/herdr/runtime-lock.json` leaves npm 0.34.1 for the closed
|
|
24
|
+
`herdr-checkout` source from this prep until the post-publish npm 0.34.2 re-pin; the plugin
|
|
25
|
+
manifest moves with that re-pin. A host already on npm 0.34.1 is unaffected until then and
|
|
26
|
+
upgrades same-source; a host that installs the plugin from `main` inside the window gets a
|
|
27
|
+
checkout-source runtime and needs `herdr-plugin-deactivate` before the npm reinstall.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- **`doctor-meta-bridge` certifies a Herdr plugin installation (#136).** The plugin activation
|
|
32
|
+
writes Claude's MCP and statusLine as absolute commands under the stable runtime, but the doctor
|
|
33
|
+
computed its three expectations (`meta-bridge-state.py check`, `desired-statusline`,
|
|
34
|
+
`desired-mcp`) without that mode. It expected bare bins and reported correct wiring as drift, so
|
|
35
|
+
no plugin host could reach a green doctor. The doctor now learns its mode from the certified
|
|
36
|
+
activation ledger through one narrow call (`resolveDoctorPluginRuntime`,
|
|
37
|
+
`scripts/herdr-doctor-mode.mjs`). Derived plugin mode needs all four clauses:
|
|
38
|
+
- the ledger phase is `active`;
|
|
39
|
+
- `claude-code` was activated;
|
|
40
|
+
- the ledger's runtimeRoot is this host's stable root;
|
|
41
|
+
- the doctor runs from that runtime's package.
|
|
42
|
+
A flagless checkout doctor never opens the ledger. The explicit `--plugin-runtime <root>`
|
|
43
|
+
override bypasses only the repo clause and still reads and certifies the ledger, which it must
|
|
44
|
+
agree with. A refusal reports each expectation as UNKNOWN, never a bare-bin fallback, and
|
|
45
|
+
the runtime sections still run. The doctor prints the mode it used on one line.
|
|
46
|
+
- **`run.sh doctor-meta-bridge` forwards its arguments.** The verb was never shifted, so it rode
|
|
47
|
+
into the doctor's argv; the override was unreachable through the operator entrypoint.
|
|
48
|
+
|
|
49
|
+
### Docs
|
|
50
|
+
|
|
51
|
+
- **CONTRIBUTING matches the scheduling rule.** A gate, mutant or matrix change runs only its
|
|
52
|
+
affected exact-argv groups as PARTIAL receipts; the whole qualification body runs once per cut,
|
|
53
|
+
in the prepared SHA's CI. CONTRIBUTING still told a gate-changing PR to run the body itself.
|
|
54
|
+
|
|
55
|
+
### Verification
|
|
56
|
+
|
|
57
|
+
- New cells: `check-herdr-activation` D1-D6 and `check-meta-doctor-oracle` P1-P3. The existing
|
|
58
|
+
clone control is unchanged (P4). Six mutants joined the `herdr-activation` lane (now 34).
|
|
59
|
+
PARTIAL receipts: herdr-activation group 33/33 and doctor-oracle group 2/2 killed, control ok.
|
|
60
|
+
No whole body ran in development.
|
|
61
|
+
- **Host acceptance before publication (thinkpad, live plugin 0.34.1 wiring).** The patched
|
|
62
|
+
checkout doctor with `--plugin-runtime <stable root>` named `mode: plugin-runtime … (activation
|
|
63
|
+
ledger)`. Its only FAIL was writer-version parity, the declared non-goal of a checkout doctor on
|
|
64
|
+
a plugin host. The seven drift lines the shipped doctor printed are gone.
|
|
65
|
+
- **Owed after publication.** After the plugin is re-pinned to 0.34.2 and rebound on that host, a
|
|
66
|
+
flagless runtime-absolute `doctor-meta-bridge` must exit 0 and a new Claude session must call
|
|
67
|
+
`entwurf_self`. That is what closes #136.
|
|
68
|
+
|
|
69
|
+
## v2026.10.9-herdr.0.34.1 — Herdr Entwurf plugin 0.34.1
|
|
70
|
+
|
|
71
|
+
A Herdr plugin snapshot, not a core release: no package version, npm artifact or core tag moves.
|
|
72
|
+
|
|
73
|
+
### Herdr plugin
|
|
74
|
+
|
|
75
|
+
- **Runtime re-pinned to the published 0.34.1 (#135).** `plugins/herdr/runtime-lock.json` returns
|
|
76
|
+
from the `herdr-checkout` verification carrier the 0.34.1 preparation rode to the npm production
|
|
77
|
+
source: `@junghanacs/entwurf@0.34.1` with the registry's measured sha512
|
|
78
|
+
(`sha512-AiB88Ext…GDxA==`). The manifest version moves 0.34.0 → 0.34.1; `min_herdr_version`
|
|
79
|
+
stays 0.9.0. A plugin host now receives the #135 fixes listed under 0.34.1: owner preflight
|
|
80
|
+
before acquisition, the no-ledger deactivate, and the regular-file-or-nothing ledger address.
|
|
81
|
+
- **Upgrading.** A host on the npm 0.34.0 snapshot stays on the npm source, so its next
|
|
82
|
+
`herdr plugin install` is a same-source rebind under the plugin README's conditions. A host that
|
|
83
|
+
installed while the lock named `herdr-checkout` — the 0.30.1 plugin, or `main` during the 0.34.1
|
|
84
|
+
preparation window — holds a checkout-source runtime and ledger, and npm is a different
|
|
85
|
+
acquisition source, refused rather than inherited (`activation-artifact-source-drifted`). Run
|
|
86
|
+
`herdr-plugin-deactivate` by its absolute runtime path, then `herdr plugin install` again.
|
|
87
|
+
- **The READMEs no longer state a current release.** The root README's hardcoded release block and
|
|
88
|
+
the plugin README's snapshot and carrier prose went stale with every version bump; they now point
|
|
89
|
+
at `runtime-lock.json`, `herdr-plugin.toml`, Releases and this file. The source-switch rules and
|
|
90
|
+
the 0.34.0 runtime's no-ledger limit stay, the latter as a historical fact.
|
|
91
|
+
|
|
92
|
+
### Verification
|
|
93
|
+
|
|
94
|
+
- **Registry, measured before the pin.** One scheduled observation, after a 300 s delay:
|
|
95
|
+
version 0.34.1 published at 2026-10-09T14:29:48.184Z with `latest` → 0.34.1, and the downloaded
|
|
96
|
+
tarball re-hashed to the artifact accepted as 0.34.1 (sha256 `73407ba8…`, 13587297 bytes), with
|
|
97
|
+
`dist.integrity` re-derived equal. Dist-tags before publication were not captured, so no
|
|
98
|
+
before/after claim is made about them.
|
|
99
|
+
- **VERIFY's 0.34.0 public-ref row is closed with its measured receipts:** `--ref main` PASS at
|
|
100
|
+
`b5d15d8` and `8ed4d1a`, both acquiring npm 0.34.0. That is a main-ref receipt, not a tag-ref
|
|
101
|
+
or native claim.
|
|
102
|
+
- No gate, mutant or matrix changed, so no qualification PARTIAL is owed. The npm-source re-proof
|
|
103
|
+
for this pin — the focused Herdr gates, a real-npm 0.34.0 → 0.34.1 swap and torn-swap recovery,
|
|
104
|
+
an installed registry consumer, the registry-file container consumer, the public `main`
|
|
105
|
+
first-user path and the exact-SHA CI run — is recorded in the GitHub release, not claimed here.
|
|
106
|
+
A `--ref <tag>` install, a citizen drawn as a ROW in a real Herdr pane, and native hosts stay
|
|
107
|
+
unmeasured.
|
|
108
|
+
|
|
109
|
+
## 0.34.1 - 2026-10-09
|
|
110
|
+
|
|
111
|
+
### Release coordination
|
|
112
|
+
|
|
113
|
+
- **A patch cut for #135.** Coordinated by the pi-durable citizen `20261008T113104-801621` and
|
|
114
|
+
implemented by Claude Code Opus as sole writer, under the maintainer's grant through prepare and
|
|
115
|
+
make; npm publication is not part of that grant. This section is written at prepare time, before
|
|
116
|
+
the release gates run: the `check:full`, package-consumer and `release-gate --cut` results are
|
|
117
|
+
recorded in the operator handoff and the GitHub release, not claimed here. Their raw logs stay
|
|
118
|
+
under the ignored `.tmp-verify/135-install-ownership/writer/release-0341/{p4,p6,p5}/`.
|
|
119
|
+
- **The published 0.34.0 does not carry these fixes.** Its registry bytes stay as accepted.
|
|
120
|
+
|
|
121
|
+
### Herdr plugin
|
|
122
|
+
|
|
123
|
+
- **Component owners are asked before anything is fetched (#135).** The plugin build now runs the
|
|
124
|
+
selected components' read-only owner preflights — Pi package, Pi provider, and the Claude
|
|
125
|
+
meta-bridge plan — before runtime acquisition, on the same Pi state paths the activation reads. A
|
|
126
|
+
foreign Pi owner refuses with no runtime, journal, cache or ledger written, and the refusal says
|
|
127
|
+
to release the registration from the root that owns it (its own `remove-user-scope`): a takeover
|
|
128
|
+
from the plugin's root is not a route. The check is planned against the physical prospective
|
|
129
|
+
runtime root; a landed package whose name or root differs from that plan refuses as
|
|
130
|
+
`herdr-build-artifact-drifted`. The installed activation keeps its own preflight recheck.
|
|
131
|
+
- **`herdr-plugin-deactivate` without a ledger no longer reports success over leftovers.** With no
|
|
132
|
+
certified activation ledger it exits 0 only when nothing stands at the plugin's journal, runtime
|
|
133
|
+
and cache addresses; otherwise it names what it found and exits non-zero
|
|
134
|
+
(`deactivate-unattributed-leftovers`), removing nothing.
|
|
135
|
+
- **Only a regular file or nothing may stand at the activation ledger address.** A symlink,
|
|
136
|
+
dangling or not, or a directory at `activation.json` refuses as `activation-ledger-uncertified`.
|
|
137
|
+
- **Limits that stay.** The Claude install state records the last installer and is not root-bound.
|
|
138
|
+
Roots changed between runs, or a host changing between the early owner check and the installed
|
|
139
|
+
recheck, can still refuse after the download. The no-ledger deactivate reports leftovers and
|
|
140
|
+
neither reclaims nor reuses them. No wider Claude-root or ownership guarantee is added.
|
|
141
|
+
`docs/setup-clean-host.md` §1.1 names the four installation paths and these limits.
|
|
142
|
+
- **The runtime lock rides the `herdr-checkout` verification carrier for this window.**
|
|
143
|
+
`plugins/herdr/runtime-lock.json` returns from npm 0.34.0 to the closed `herdr-checkout` source,
|
|
144
|
+
so the lock stays coherent with the 0.34.1 package version without inventing a registry
|
|
145
|
+
integrity. The plugin manifest stays 0.34.0, and this is not a plugin pair: the npm re-pin to
|
|
146
|
+
0.34.1 follows publication with its measured sha512 and its own source proof. Moving a host
|
|
147
|
+
between the published npm 0.34.0 plugin and this carrier, in either direction, needs
|
|
148
|
+
`herdr-plugin-deactivate` first.
|
|
149
|
+
|
|
150
|
+
### Repository hooks
|
|
151
|
+
|
|
152
|
+
- **`prepare` no longer runs husky.** It only builds the bridge. The local
|
|
153
|
+
`core.hooksPath=.husky/_` override that shadowed the configured global guard was removed on this
|
|
154
|
+
checkout, and `.husky/pre-commit` (whitespace, lint, typecheck) is reached through a global guard
|
|
155
|
+
that chains to repository-local hooks. Another existing clone may keep its local value until it
|
|
156
|
+
is unset there (unmeasured). On this checkout a real `npm pack` inside `check-pack-install` left
|
|
157
|
+
`.git/config` and `.husky/_` unchanged. The `husky` devDependency is unchanged.
|
|
158
|
+
|
|
159
|
+
## v2026.10.9-herdr.0.34.0 — Herdr Entwurf plugin 0.34.0
|
|
160
|
+
|
|
161
|
+
A Herdr plugin snapshot, not a core release: no package version, npm artifact or core tag moves.
|
|
162
|
+
|
|
163
|
+
### Herdr plugin
|
|
164
|
+
|
|
165
|
+
- **Runtime re-pinned to the published 0.34.0 (#132 B).** `plugins/herdr/runtime-lock.json`
|
|
166
|
+
returns from the `herdr-checkout` verification carrier the 0.30.1 preparation rode to the npm
|
|
167
|
+
production source: `@junghanacs/entwurf@0.34.0` with the registry's measured sha512
|
|
168
|
+
(`sha512-rUpQ…/uJ/fw==`), which is the artifact accepted and published as 0.34.0. 0.31–0.33
|
|
169
|
+
were never pinned here. The manifest version moves 0.30.1 → 0.34.0; `min_herdr_version` stays
|
|
170
|
+
0.9.0 and the measured Herdr supply stays 0.9.3.
|
|
171
|
+
- **Upgrading from a 0.30.1 plugin install needs an explicit deactivate.** That install recorded a
|
|
172
|
+
`herdr-checkout` runtime and ledger, and npm is a different acquisition source, which is refused
|
|
173
|
+
rather than inherited (`activation-artifact-source-drifted`). Run `entwurf
|
|
174
|
+
herdr-plugin-deactivate`, then `herdr plugin install` again. A host with no plugin installation
|
|
175
|
+
starts fresh.
|
|
176
|
+
- **The release skill's core baseline ignores Herdr snapshot tags.** `prepare` P1 took the newest
|
|
177
|
+
tag by version sort, and a `vYYYY.M.D-herdr.*` tag sorts above every `v0.x`, so it would have
|
|
178
|
+
become the next core audit baseline. P1 now excludes exactly that shape; a core `v20.1.0` is
|
|
179
|
+
still picked.
|
|
180
|
+
- **Plugin docs corrected before the tag (GLG's final review).**
|
|
181
|
+
- The direct route opens six fresh-call backends, `pi-durable` among them as the managed launcher.
|
|
182
|
+
The plugin's Herdr pair stays `{pi, claude-code}`, and the manifest now says it does not widen
|
|
183
|
+
with the core list.
|
|
184
|
+
- `smoke-herdr-plugin-build-live` is described as the checkout-carrier journey it is, not as
|
|
185
|
+
registry evidence.
|
|
186
|
+
- `herdr-plugin-deactivate` is given by its absolute runtime path, because the plugin puts nothing
|
|
187
|
+
on `PATH`.
|
|
188
|
+
- The plugin tag namespace is explained.
|
|
189
|
+
- A v1 record is now described as refused by the current inverse as well. The launch-rail doc
|
|
190
|
+
separates the `0.9.0` admission floor from the single Herdr version the gates certify (the
|
|
191
|
+
supply pin, 0.9.3).
|
|
192
|
+
|
|
193
|
+
### Verification
|
|
194
|
+
|
|
195
|
+
- **Real-npm swap and torn-swap recovery, measured before commit.** This is the row the 0.30.0
|
|
196
|
+
pin left open. A one-shot driver ran the registry-shipped `scripts/herdr-runtime.mjs`, whose
|
|
197
|
+
sha256 equals this checkout's, against the real registry:
|
|
198
|
+
- A 0.33.0 → 0.34.0 swap.
|
|
199
|
+
- The same upgrade torn between its two renames (`torn-swap-with-candidate`), then resumed.
|
|
200
|
+
The last-good 0.33.0 tree was restored before 0.34.0 was acquired again.
|
|
201
|
+
- Both ended `runtime-ready` with observed digest
|
|
202
|
+
`sha256-e9d995ff3858ffca40fa12b4fce2a6db3802da3ee27c7b233142fc4c71f23450`, the accepted
|
|
203
|
+
artifact. Neither left a staging or backup directory behind.
|
|
204
|
+
- Each 0.34.0 runtime passed the installed-runtime check: three executable bins, the compiled
|
|
205
|
+
entry, and `check-bridge` with its exact eight verbs. The owned inverse removed cache,
|
|
206
|
+
runtime and journal.
|
|
207
|
+
- Two earlier runs stopped on defects in the driver's own verb parser, not on product behaviour.
|
|
208
|
+
- The focused Herdr gates (`check-herdr-plugin`, `-plugin-profile`, `-plugin-build`,
|
|
209
|
+
`-runtime-bootstrap`, `-activation`) and `check-gate-manifests` are green on this tree. No gate,
|
|
210
|
+
mutant or matrix changed, so no qualification PARTIAL is owed.
|
|
211
|
+
- The public-ref first-user path (`smoke-herdr-raw-install-live`) and the exact-SHA CI run on the
|
|
212
|
+
pushed commit. Their receipts are recorded in the GitHub release and #132, not claimed here.
|
|
213
|
+
|
|
7
214
|
## 0.34.0 - 2026-10-09
|
|
8
215
|
|
|
9
216
|
### Release coordination
|
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 a branch push whose diff touched the qualification surface (and unconditionally on dispatch or the weekly schedule)
|
|
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 a branch push whose diff touched the qualification surface (and unconditionally on dispatch or the weekly schedule). 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 the whole body runs once per cut, in the prepared SHA's CI. 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
|
@@ -27,11 +27,8 @@ Claude and Cortex Code are ACP backends. Codex and Antigravity stay native so th
|
|
|
27
27
|
retain their own tools and work context. Capabilities differ by rail: a shipped
|
|
28
28
|
citizen is not a promise of every lifecycle operation.
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
> Includes the pinned Pi 1.1.0 native durable app/TUI and one explicit native-module ingress;
|
|
33
|
-
> `npm` `latest` is `0.33.0`. What that cut ran and did not run is in its CHANGELOG section.
|
|
34
|
-
> Release history and detailed evidence belong in [CHANGELOG](./CHANGELOG.md).
|
|
30
|
+
[Releases](https://github.com/junghan0611/entwurf/releases) contain each cut's notes and acceptance
|
|
31
|
+
receipts; [CHANGELOG](./CHANGELOG.md) records source history.
|
|
35
32
|
|
|
36
33
|
## Install
|
|
37
34
|
|
|
@@ -88,8 +85,8 @@ models/auth, queues, SQLite, transcripts and recovery remain upstream-owned:
|
|
|
88
85
|
[Hard Rule 17](./AGENTS.md#hard-rules), **supply the missing surface; do not become the harness**.
|
|
89
86
|
|
|
90
87
|
Optional `--native-module <absolute file>` initializes trusted ESM before runtime/TUI
|
|
91
|
-
imports, then installs its default native Extension after the contact.
|
|
92
|
-
`--native-module-dir <absolute directory>` loads the top-level `*.extension.mjs` files of that
|
|
88
|
+
imports, then installs its default native Extension after the contact.
|
|
89
|
+
`--native-module-dir <absolute directory>` (#134) loads the top-level `*.extension.mjs` files of that
|
|
93
90
|
one named directory in byte-wise order instead, and the durable TUI keeps a live
|
|
94
91
|
background-task badge on screen at any terminal size. No automatic module discovery or
|
|
95
92
|
classic Pi API shim; guards are not a sandbox or rollback.
|
package/VERIFY.md
CHANGED
|
@@ -96,7 +96,7 @@ that moved out of `scripts/` and into a file beside its subject would otherwise
|
|
|
96
96
|
|
|
97
97
|
> **The herdr rail is an on-demand axis until it has run.** `smoke-herdr-fresh-call-live` opens a real caller inside a real herdr pane, has it invoke the PUBLIC `entwurf_fresh_call`, and reads the child's nonce callback — the one axis no deterministic gate reaches, since the rail is selected from the caller's own process environment. **The release aggregate does not yet require the herdr rail**: herdr is optional (a cut on a host without it must not block), and first evidence precedes promotion — a rail whose first acceptance run is days old has not earned a place in the gate that blocks every cut. Run it directly with `LIVE=1 ./run.sh smoke-herdr-fresh-call-live` whenever a cut changes herdr rail code, and promote it to a MUST only after the axis has a run history to point at. Without `LIVE=1`, or without herdr/pi/claude on PATH, it reports protocol SKIP — never a pass.
|
|
98
98
|
|
|
99
|
-
> **The plugin's FIRST USER PATH is its own on-demand axis, and an npm acquisition receipt holds only for the ref it ran on (#118 홉 1).** Every other herdr gate proves the plugin against a source this repository controls: `check-herdr-plugin-build` drives a stub, and `smoke-herdr-plugin-build-live` redirects the product remote to a local bare clone with git `insteadOf` and asserts `identity.kind === "herdr-checkout"`. npm has been the production authority class since `dd84ac0`; the 0.30.0 follow-up re-pinned `@junghanacs/entwurf@0.30.0` with its published sha512 after the candidate windows rode `herdr-checkout` (`8b92e09`)
|
|
99
|
+
> **The plugin's FIRST USER PATH is its own on-demand axis, and an npm acquisition receipt holds only for the ref it ran on (#118 홉 1).** Every other herdr gate proves the plugin against a source this repository controls: `check-herdr-plugin-build` drives a stub, and `smoke-herdr-plugin-build-live` redirects the product remote to a local bare clone with git `insteadOf` and asserts `identity.kind === "herdr-checkout"`. npm has been the production authority class since `dd84ac0`; the 0.30.0 follow-up re-pinned `@junghanacs/entwurf@0.30.0` with its published sha512 after the candidate windows rode `herdr-checkout` (`8b92e09`), and the 0.30.1 preparation rode that closed verification carrier again without inventing a registry integrity. The plugin snapshot `v2026.10.9-herdr.0.34.0` pinned the published `@junghanacs/entwurf@0.34.0` with its measured sha512 (#132); 0.31–0.33 were never pinned. The 0.34.1 preparation rode the closed `herdr-checkout` verification carrier again without inventing a registry integrity, and the snapshot `v2026.10.9-herdr.0.34.1` re-pins the published `@junghanacs/entwurf@0.34.1` with its measured sha512 (#135). The source re-proof has separate dated npm rows: 2026-09-23 public `main=113ca53`, plugin 0.5.0, runtime 0.25.0 (CHANGELOG 0.25.1), and the 0.30.0 re-pin accepted at public `506c46f` in the [#126 thread](https://github.com/junghan0611/entwurf/issues/126). Neither certifies the 0.34.0 registry acquisition. That pin's real-npm swap / torn-swap recovery was measured locally on 2026-10-09 by driving the registry-shipped `scripts/herdr-runtime.mjs` (byte-equal to this checkout's) with its own npm acquisition: a 0.33.0 → 0.34.0 swap, and the same upgrade torn between its two renames then resumed, where the last-good 0.33.0 tree was restored before 0.34.0 was acquired again. Both ended `runtime-ready` at observed digest `sha256-e9d995ff…`, the accepted 0.34.0 artifact. That local receipt is recorded in the [#132 thread](https://github.com/junghan0611/entwurf/issues/132); it covers runtime recovery, not this smoke's cells. This smoke's public-ref acceptance of the 0.34.0 pin was measured locally at `--ref main`: PASS at resolved `b5d15d8` and again at the docs follow-up `8ed4d1a`, each acquiring `kind=npm @junghanacs/entwurf@0.34.0` — a main-ref receipt, not a tag-ref, native or full-Herdr claim. The 0.34.1 re-pin's npm-source rows — swap / torn-swap recovery, this smoke at a public ref, and the package consumer — are its own, recorded with that pin and never inherited from 0.34.0; checkout candidate evidence does not transfer. `LIVE=1 ./run.sh smoke-herdr-raw-install-live [--ref <REF>]` fills that row in a clean `node:24` container with no socket, config, cache or repo mounted, no `insteadOf`, the public remote spelled as a user would type it, and pi / herdr / Claude Code installed in the IMAGE BUILD as scaffolding (Hard Rule 17 — the product face begins at `herdr integration install pi`). herdr itself comes from `scripts/install-herdr-ci.sh` against `scripts/fixtures/herdr-supply.json`, so no version or digest lives here. `--ref` defaults to `main` rather than a pinned SHA because receipt (a) is defined as what a user gets today; the resolved commit is printed, so the receipt stays exact. It takes a REMOTE REF and not an arbitrary commit — measured on herdr 0.9.1, `--ref <sha>` fails as `couldn't find remote ref`, because the checkout fetches by name — so a candidate is addressed by its branch and pinned by the resolved commit the gate prints. **Its first question is a measurement, not an assumption:** herdr registers a plugin through a running server and falls back to `persist_plugin_offline` only on a connection error (`src/cli/plugin.rs:914-981,1016-1021` @ `c77af189`, 0.9.0 source), and a container has no server. The 2026-09-23 PASS installed with no server on the 0.9.1 binary `113ca53`'s `herdr-supply.json` pins, so that install path worked on 0.9.1 — inferred from the PASS, not a direct observation of the fallback branch; a later "no" on another herdr is #118 investigation output rather than a completion. `--yes` is always passed so a non-interactive exit 2 (`:189`) can never be misread as a missing server. **At a ref whose lock names `herdr-checkout` the acquisition axis reports a NAMED SKIP rather than a red, and the rest of the journey still runs.** That lock is the candidate carrier a cut legitimately sits on — 0.23.0 was tagged that way and `dd84ac0` pinned npm afterwards — so a red there would report a broken install when what is true is that the ref does not lock npm. What is asserted at BOTH lock kinds is that the runtime came from the source the ref locks, and the package name is read from the checkout manifest rather than the lock, because a `herdr-checkout` lock carries no `name` (`herdr-runtime.mjs:317-328`) and joining `undefined` throws instead of failing an assertion. **Cells [6]–[9] carry it past the install into the USE path (#118 H1-4/H1-5).** An install is not a use, so the same container then runs what those bytes became: the compiled bridge entry, the three `REQUIRED_BINS` as executables, and a real `entwurf check-bridge` printing its exact eight-verb set — the installed-runtime row below, measured rather than inferred from the bootstrap's refusal to install without them. Then the pi that this plugin WIRED is started with no `-e` and no `--no-extensions`, because the subject is the wiring and not this checkout: one `get_state` in `--mode rpc` costs zero tokens and needs no provider argument (a bogus `--provider` exits 1 before session_start; omitting the pair lets pi resolve the default the extension itself registers), and while that session is alive the cell reads its V3 record, its gardenId-keyed control socket, and the installed `entwurf peer-facts` reporting it `alive`. The plugin's own status fan is then driven with NEITHER side stubbed, in both states a user can be in: with no herdr server it must name `herdr-agent-list-failed` and go red rather than draw an empty table, and under a headless `herdr server` — scaffolding for that second read only, stopped again before the teardown — it exits 0 and COUNTS the citizen as `unobserved` instead of dropping it. Last, the shipped `entwurf herdr-plugin-deactivate` runs from the installed bin, deletes the runtime it is executing from, and the plugin reinstalls onto the host it fully left — the deactivation row, on the npm source. **What these cells still do not close:** swap / torn-swap recovery on the npm source, the package-consumer proof, and the fan drawing a citizen as a ROW — that needs `placement.kind === "herdr-pane"`, so the pi session must live in a herdr pane a session reference joins, and a headless container has no panes. **This smoke carries no test beside behavior and no mutant**, and that is a property of its class rather than an omission: it is a real-live container journey whose oracle is the container's own end state, so there is no pure seam to assert against and nothing a source mutation could kill deterministically. Like the other two herdr LIVE lanes it is **on-demand and not an aggregate MUST** — herdr is optional, a cut on a host without it must not block, and first evidence precedes promotion. Without `LIVE=1`, or without a usable Docker daemon, it reports a named SKIP; `ENTWURF_REQUIRE_DOCKER=1` turns the Docker absence red. Neither skip is a pass.
|
|
100
100
|
|
|
101
101
|
> **The Herdr plugin's install-time build has two axes, and one of them needs the network (#116 M3-b3).** `check-herdr-plugin-build` is deterministic and rides `check:hermetic`: the listing reaches the runner through its own spawn seam (there is no fake `herdr` binary in this repo), and the one cell that drives the REAL binary reports a named SKIP on a host without it — `ENTWURF_REQUIRE_HERDR=1` makes that absence red. What it cannot have is the real acquisition: `npm pack git+https://github.com/junghan0611/entwurf.git#<full sha>` builds the bridge through `prepare`, which installs devDependencies from the registry. So `LIVE=1 ./run.sh smoke-herdr-plugin-build-live` owns that axis, and its cells are **two kinds of evidence, labelled as such**: three are the real Herdr journey — a real `herdr plugin install` driving the real `[[build]]`, with the UNCHANGED product remote redirected to a local bare clone by git `insteadOf` (the one substitution, which is what makes an unpushed candidate testable) — covering remote-commit available, the `{pi}` → `{pi, claude-code}` reinstall with OpenCode as a zero-write negative control and exactly ONE counted vendor MCP owner entry, and the post-build Herdr-commit gap (where the ledger has already rebound to the gap commit, so the honest assertion is that transition and not unchanged bytes). The fourth cell — remote-commit **unavailable** — calls the shipped runtime leaf directly with the fixed product argv and is therefore **acquisition-leaf evidence, not a journey**; routing it through Herdr would add a second explanation for one red. Its oracle is the honest one too: active runtime, ledger and harness bytes preserved, while the journal is left as the certified `installing` retry authority the transaction deliberately writes before acquiring, and a normal install afterwards is green. Its Claude cell is where the vendor question the deterministic gates refuse to claim gets answered — whether Claude Code accepts an ABSOLUTE executable as an MCP command — and it reports a named skip on a host without `claude`, never a pass. Like the herdr fresh-call rail, this smoke is **on-demand and not an aggregate MUST**. The release aggregate does not require the plugin build smoke: herdr is optional, a cut on a host without it must not block, and first evidence precedes promotion.
|
|
102
102
|
|
package/docs/setup-clean-host.md
CHANGED
|
@@ -179,6 +179,24 @@ packageRoot↔installerRoot coupling mismatch and a package/provider managed-pat
|
|
|
179
179
|
| source checkout | the checkout dir | `dev-bin` symlinks (`setup`) | `<project>/.pi/settings.json` | shared entry + owner state | `takeover-user-scope` from the new checkout | `remove` (project) / `remove-user-scope` (global, same-owner-only) | `doctor-pi-package` → `missing-owner`; normal install still refuses |
|
|
180
180
|
| global npm (`npm i -g`) | the global `node_modules/@junghanacs/entwurf` | npm bin linking | same | same shared entry | same explicit action | same; a LIVE foreign owner always refuses | same |
|
|
181
181
|
| project-local npm | that project's `node_modules/@junghanacs/entwurf` | `node_modules/.bin` | same | same shared entry | same explicit action | same | same; a deleted root becomes the aligned `remove-user-scope` orphan cleanup (entry + package state + provider installerRoot must all name that missing root) |
|
|
182
|
+
| Herdr plugin | `$XDG_DATA_HOME/entwurf/herdr-plugin/runtime/active/node_modules/@junghanacs/entwurf` | none on PATH — Pi provider and Claude MCP/statusLine record ABSOLUTE commands under that runtime | none | same shared entry, plus the plugin's activation ledger (`$XDG_STATE_HOME/entwurf/herdr-plugin/activation.json`) | none — the plugin never takes a registration over; release it from its owner first | the runtime's own absolute `…/node_modules/.bin/entwurf herdr-plugin-deactivate` | — |
|
|
183
|
+
|
|
184
|
+
The four installation paths keep separate records: Herdr's plugin registry (changed only by `herdr
|
|
185
|
+
plugin install` / `unlink` / `uninstall`), the plugin's runtime journal and activation ledger, the shared Pi
|
|
186
|
+
package/provider ownership above, and the Claude meta-bridge install state
|
|
187
|
+
(`${CLAUDE_CONFIG_DIR:-~/.claude}/entwurf.install-state.json`). Moving between them is explicit: release the
|
|
188
|
+
shared registration from its owner (`remove-user-scope`, plus `uninstall-meta-bridge` for Claude) before
|
|
189
|
+
`herdr plugin install` — a foreign Pi owner refuses the plugin build before anything is fetched (#135) — and
|
|
190
|
+
run the plugin's `herdr-plugin-deactivate` before going back to `setup`. Do not `takeover-user-scope` a
|
|
191
|
+
registration the plugin owns, even though a refused `setup` suggests it: it splits ownership (the plugin's
|
|
192
|
+
provider key becomes an unowned override while its ledger still records pi) and the plugin's deactivate
|
|
193
|
+
then refuses. Limits that stay as they are: the Claude install state records the LAST installer and is not
|
|
194
|
+
root-bound — an install from another root rewrites it rather than refusing; nothing covers roots (XDG,
|
|
195
|
+
`PI_CODING_AGENT_DIR`, Claude config) changed between runs or a host that changes between the plugin's
|
|
196
|
+
early owner check and its installed recheck, which can still refuse after the download; and the plugin's
|
|
197
|
+
deactivate, finding no activation ledger, reports what is left at its addresses and neither reclaims nor
|
|
198
|
+
reuses it. The 0.34.0 runtime predates that no-ledger diagnostic; a plugin host runs the runtime its
|
|
199
|
+
`runtime-lock.json` pins.
|
|
182
200
|
|
|
183
201
|
## 2. Optional pi adapter / ACP plugin
|
|
184
202
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@junghanacs/entwurf",
|
|
3
|
-
"version": "0.34.
|
|
3
|
+
"version": "0.34.2",
|
|
4
4
|
"description": "Garden-citizen dispatch substrate and meta-bridge for pi, Claude Code, Copilot CLI, OMP, Antigravity, and Codex CLI; Claude and Snowflake Cortex Code ACP backends.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"vitest": "4.1.9"
|
|
120
120
|
},
|
|
121
121
|
"scripts": {
|
|
122
|
-
"prepare": "
|
|
122
|
+
"prepare": "npm run --silent build-bridge 1>&2",
|
|
123
123
|
"postinstall": "node scripts/postinstall-chmod.cjs",
|
|
124
124
|
"build-bridge": "bash scripts/with-dist-lock.sh bash scripts/build-bridge.sh",
|
|
125
125
|
"prepack": "pnpm run build-bridge 1>&2",
|
package/run.sh
CHANGED
|
@@ -294,7 +294,7 @@ Usage:
|
|
|
294
294
|
./run.sh remove [project-dir] # remove entwurf entries from project .pi/settings.json (project scope only; global user-scope citizen left intact)
|
|
295
295
|
./run.sh install-user-scope [--plugin-runtime <root>] # #116 M3-b2 PLUGIN-ONLY forward seam: compose ONLY the global pi citizen (user-scope packages[] + provider), never a project `.pi/settings.json` — a Herdr plugin activation has no project and must not invent one. With --plugin-runtime the provider's managed command becomes the absolute bridge under that certified stable runtime (a clean host has nothing entwurf on PATH); without it every byte is the historical bare-bin install. Inverse: remove-user-scope
|
|
296
296
|
./run.sh herdr-plugin-activate <backend...> # #116 M3-b2 public forward activation. Takes a subset of {pi, claude-code} and NOTHING else — the stable runtime root is DERIVED from XDG here and handed down, and both harness writers accept a named root only when it IS that derived one. Certifies the runtime-ready journal AND the installed tree, certifies the existing ledger and its recorded harness roots, plans ADD-ONLY (a backend absent from this request is retained, never removed), preflights every selected component before the first byte, then writes each component `pending` BEFORE mutating and checkpoints `active` the moment its writer returns — so a run that dies halfway leaves a record of how far it got. Which backends is M3-b3's question: this verb is handed the answer, it does not read Herdr's integration status
|
|
297
|
-
./run.sh herdr-plugin-deactivate # #116 M3-b2 public teardown of a Herdr-plugin activation. Herdr's `plugin uninstall` deletes its checkout and calls NO cleanup hook, so the harness wiring and the stable runtime are retained, not cleaned — this is the shipped verb that takes them back. Certifies the activation ledger, the resolved Pi/Claude roots and BOTH component inverses read-only first; mutates only when every preflight is green; then Claude -> Pi user scope -> runtime -> ledger LAST. A component failure stops with the runtime and ledger intact as retry authority. Static imports only: the process deletes the runtime it is running from, and a lazy import after that fails
|
|
297
|
+
./run.sh herdr-plugin-deactivate # #116 M3-b2 public teardown of a Herdr-plugin activation. Herdr's `plugin uninstall` deletes its checkout and calls NO cleanup hook, so the harness wiring and the stable runtime are retained, not cleaned — this is the shipped verb that takes them back. Certifies the activation ledger, the resolved Pi/Claude roots and BOTH component inverses read-only first; mutates only when every preflight is green; then Claude -> Pi user scope -> runtime -> ledger LAST. A component failure stops with the runtime and ledger intact as retry authority. With NO ledger it removes nothing: a clean host exits 0, and anything found at the plugin's journal/runtime/cache addresses is named with a non-zero exit (#135). Static imports only: the process deletes the runtime it is running from, and a lazy import after that fails
|
|
298
298
|
./run.sh remove-user-scope # explicit GLOBAL inverse of install's user-scope citizen: drop entwurf from ~/.pi/agent/settings.json packages[] (affects ALL cwds — shared entry, not per-project). #86 C2: same-owner-only — a LIVE foreign owner refuses; a MISSING owner is removed only when package entry + package state + provider installerRoot all align (reported orphan cleanup)
|
|
299
299
|
./run.sh takeover-user-scope # #86 C2: operator-EXPLICIT ownership move of the shared user-scope registration to THIS root (old→new reported, packages[] entry + provider installerRoot together). The only writer over another owner — normal install/setup/remove refuse instead. No --force exists
|
|
300
300
|
./run.sh doctor-pi-package # #86 C2: package-side user-scope ownership verdict — unregistered / owned / owned-by-other(live) / legacy-no-state / mismatch / missing-owner (nonzero on defect verdicts). Provider runtime verdicts stay with doctor-pi-provider
|
|
@@ -4393,8 +4393,8 @@ _check_pack_install_impl() {
|
|
|
4393
4393
|
|
|
4394
4394
|
# Fresh-temp install smoke. Uses pnpm because that is what this
|
|
4395
4395
|
# repo packages with; --ignore-workspace stops it from re-attaching
|
|
4396
|
-
# to our pnpm-workspace.yaml; --ignore-scripts blocks
|
|
4397
|
-
# prepare
|
|
4396
|
+
# to our pnpm-workspace.yaml; --ignore-scripts blocks
|
|
4397
|
+
# prepare (and any future install scripts) from running inside
|
|
4398
4398
|
# the consumer project. The pi SDK is pinned to the CURRENT pi release
|
|
4399
4399
|
# baseline (the package.json exact production dependency — the pins below
|
|
4400
4400
|
# are what check-dep-versions binds to it) so the smoke matches the same
|
|
@@ -7634,6 +7634,8 @@ case "$cmd" in
|
|
|
7634
7634
|
# global plugin install, USER MCP reach, meta-record store integrity, hook log
|
|
7635
7635
|
# no-ERROR, and actual SessionStart creation evidence. A plugin present with
|
|
7636
7636
|
# zero claude-code meta-records is a SILENT MISS -> non-zero exit.
|
|
7637
|
+
# #136: the only argument is `--plugin-runtime <root>`; shift the verb so the doctor sees it.
|
|
7638
|
+
shift || true
|
|
7637
7639
|
(cd "$REPO_DIR" && bash scripts/meta-bridge-doctor.sh "$@")
|
|
7638
7640
|
;;
|
|
7639
7641
|
install-copilot-bridge)
|
|
@@ -3471,8 +3471,8 @@ let manifestCount: number;
|
|
|
3471
3471
|
"herdr-placement": 13,
|
|
3472
3472
|
"herdr-plugin": 25,
|
|
3473
3473
|
"herdr-plugin-profile": 14,
|
|
3474
|
-
"herdr-activation":
|
|
3475
|
-
"herdr-plugin-build":
|
|
3474
|
+
"herdr-activation": 34,
|
|
3475
|
+
"herdr-plugin-build": 20,
|
|
3476
3476
|
"herdr-runtime-bootstrap": 31,
|
|
3477
3477
|
"herdr-fresh-call": 38,
|
|
3478
3478
|
"herdr-supply": 11,
|