fix(entrypoint,tests): register pi-fork — guard matched its own config block
Lint / actionlint (push) Successful in 32s
Lint / hadolint (push) Successful in 1m25s

The `pi install /opt/<pkg>` loop in entrypoint-user.sh guarded on a
whole-file substring grep of ~/.pi/agent/settings.json. settings.example.json
ships a top-level "pi-fork" CONFIG block (fork effort profiles, pi-toolkit
adb6907, 2026-06-17), so `grep -q pi-fork settings.json` matched the config
key itself and `pi install /opt/pi-fork` never ran — on fresh or preserved
volumes. The `fork` tool has therefore been absent since v1.0.0.

The non-destructive template merge runs earlier in the same startup than the
install loop, so the mechanism that delivers new template keys to an old
volume is what plants the string that defeats the guard. pi-observational-
memory and pi-studio escaped only by luck: the template key is
"observational-memory" (no pi- prefix) and there is no studio block.

Guard now inspects the `packages` array via jq, with a grep fallback on the
stored `.../opt/<name>"` path form, which a config key can never produce.
Existing volumes self-heal on the next container start.

Both test suites asserted the bug as green — smoke-test.sh:244 and
recreate-sanity-check.sh:204 used the same whole-file grep, so "pi-fork
registered (fork tool)" passed on every build and recreate while the tool was
missing. Both now assert against packages[] with the entrypoint's predicate,
labels say packages[], and the smoke readiness wait loop uses the array check
plus `docker exec -u developer` + $HOME instead of a hard-coded
/home/developer path.

Evidence: zero `fork` tool calls across all 19 sessions on this volume; the
v1.6.3 session that tuned pi-fork.deep to opus-5 was configuring a tool that
never loaded.
This commit is contained in:
2026-07-29 19:21:49 +02:00
parent e274510fd1
commit 8248688d58
4 changed files with 116 additions and 21 deletions
+39
View File
@@ -13,6 +13,45 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
## Unreleased
### Fixed
- **`pi-fork` was never registered — the `fork` tool has been missing since
v1.0.0.** `entrypoint-user.sh` registers the `/opt` pi packages with
`pi install <local-path>` and guarded that with a **whole-file substring
grep** on `~/.pi/agent/settings.json`. But `settings.example.json` carries a
top-level `"pi-fork"` **config block** (the fork effort profiles, added in
`pi-toolkit` `adb6907`, 2026-06-17), so `grep -q pi-fork settings.json`
matches on any settings file bootstrapped from — or template-merged with —
that template. The guard therefore concluded "already installed" and
`pi install /opt/pi-fork` never ran, on fresh *and* preserved volumes.
Compounding it, the non-destructive template merge runs **earlier in the same
startup** than the install loop, so the very mechanism that delivers new
template keys to an old volume is what plants the string that defeats the
guard. `pi-observational-memory` and `pi-studio` escaped only by luck: the
template key is `observational-memory` (no `pi-` prefix) and there is no
studio block.
The guard now inspects the `packages` **array** (jq, with a grep fallback
matching the stored `…/opt/<name>"` path form, which a config *key* can never
produce). Existing volumes self-heal on the next container start — the guard
returns false, `pi install /opt/pi-fork` runs, and `fork` registers on the
following pi start or `/reload`. No image rebuild is required to benefit if
you run `pi install /opt/pi-fork` by hand.
- **Both test suites asserted the bug as green.** `scripts/smoke-test.sh` and
`scripts/recreate-sanity-check.sh` checked registration with the *same*
whole-file grep, so "pi-fork registered (fork tool)" passed on every build
and every recreate while the tool was absent. Both now assert against
`packages[]` with the same predicate as the entrypoint guard, and the labels
say `packages[]` so the distinction is visible in CI output. The smoke-test
readiness wait loop was switched to the array check too (and to
`docker exec -u developer` + `$HOME` instead of a hard-coded
`/home/developer` path).
Detected by an agent session noticing `fork` was absent from its own tool
list on v1.6.3; zero `fork` calls exist across the 19 sessions on this
volume, confirming it never once loaded.
### Changed
- **Settings template now defaults to Claude Opus 5** (`pi-toolkit` @ `926f738`).