From 9c31c641d6a310e7f19c3dc2e92075d940581718 Mon Sep 17 00:00:00 2001 From: pi Date: Thu, 4 Jun 2026 21:59:39 +0200 Subject: [PATCH] smoke: gate fork/recall registration checks behind STRICT_REGISTRATION (#12) validate.yml builds variants FROM the published base-latest, which lags the entrypoint in the current commit until a release tag rebuilds the base. The fork/recall registration smoke checks depend on the base entrypoint running 'pi install /opt/', so a stale base-latest reded push-to-main runs with a false negative even when the variant layer was correct. smoke-test.sh now gates the two registration assertions behind STRICT_REGISTRATION (warn-only when unset). validate.yml leaves it unset; docker-publish-split.yml, which builds the base fresh in the same run, sets STRICT_REGISTRATION=1 on the pi-bearing smoke jobs. Build-time /opt + node_modules checks stay hard in both paths. --- .gitea/workflows/docker-publish-split.yml | 3 +++ .gitea/workflows/validate.yml | 8 ++++++ CHANGELOG.md | 14 +++++++++++ scripts/smoke-test.sh | 30 +++++++++++++++++++++-- 4 files changed, 53 insertions(+), 2 deletions(-) diff --git a/.gitea/workflows/docker-publish-split.yml b/.gitea/workflows/docker-publish-split.yml index ae97cb1..a63768c 100644 --- a/.gitea/workflows/docker-publish-split.yml +++ b/.gitea/workflows/docker-publish-split.yml @@ -386,6 +386,7 @@ jobs: PI_OBSMEM_REF=${{ needs.resolve-versions.outputs.obsmem_ref }} - env: EXPECTED_PI_VERSION: ${{ needs.resolve-versions.outputs.pi_version }} + STRICT_REGISTRATION: "1" run: bash scripts/smoke-test.sh opencode-devbox:smoke-with-pi --variant with-pi smoke-omos-with-pi: @@ -435,6 +436,7 @@ jobs: - env: EXPECTED_PI_VERSION: ${{ needs.resolve-versions.outputs.pi_version }} EXPECTED_OMOS_VERSION: ${{ needs.resolve-versions.outputs.omos_version }} + STRICT_REGISTRATION: "1" run: bash scripts/smoke-test.sh opencode-devbox:smoke-omos-with-pi --variant omos-with-pi smoke-pi-only: @@ -482,6 +484,7 @@ jobs: PI_OBSMEM_REF=${{ needs.resolve-versions.outputs.obsmem_ref }} - env: EXPECTED_PI_VERSION: ${{ needs.resolve-versions.outputs.pi_version }} + STRICT_REGISTRATION: "1" run: bash scripts/smoke-test.sh opencode-devbox:smoke-pi-only --variant pi-only # ── Phase 4: multi-arch publish per variant ──────────────────────── diff --git a/.gitea/workflows/validate.yml b/.gitea/workflows/validate.yml index bddfb4a..28a71b6 100644 --- a/.gitea/workflows/validate.yml +++ b/.gitea/workflows/validate.yml @@ -20,6 +20,14 @@ name: Validate # release tags are the gate that fully validates base-image changes. # The base-change-warning job below surfaces a runtime warning when this # blind-spot applies. +# +# Because of this, the fork/recall *registration* smoke checks (which depend on +# the base entrypoint running `pi install /opt/`) are warn-only here: +# smoke-test.sh leaves STRICT_REGISTRATION unset on this path, so a base-latest +# that lags the entrypoint in the current commit can't red the run with a false +# negative. The release smoke jobs build the base fresh and set +# STRICT_REGISTRATION=1 to enforce those checks. The build-time /opt + +# node_modules checks stay hard in both paths. on: push: diff --git a/CHANGELOG.md b/CHANGELOG.md index 426ee51..603d211 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,20 @@ Tags follow `v{opencode_version}[letter]` — bare tag for the first build on a ## Unreleased +### Fixed: validate.yml false-negative on fork/recall registration checks + +The push-to-main `validate.yml` builds variants FROM the published `base-latest` +image, which lags the entrypoint in the current commit until a release tag +rebuilds the base. The fork/recall *registration* smoke checks depend on the +base entrypoint running `pi install /opt/`, so a stale `base-latest` reded +those runs with a false negative even when the variant layer was correct. +`smoke-test.sh` now gates the two registration assertions behind +`STRICT_REGISTRATION` (warn-only when unset). `validate.yml` leaves it unset; +the release pipeline (`docker-publish-split.yml`), which builds the base fresh +in the same run, sets `STRICT_REGISTRATION=1` on the pi-bearing smoke jobs to +enforce them. The build-time `/opt` + `node_modules` checks stay hard in both +paths. + ### Added: persist the LAN-jump key + one-line authorize hint (authorize once per machine) The jump keypair (`~/.ssh-local/devbox_jump_ed25519`) was stored on the diff --git a/scripts/smoke-test.sh b/scripts/smoke-test.sh index a1cc4ef..1f803b2 100755 --- a/scripts/smoke-test.sh +++ b/scripts/smoke-test.sh @@ -30,6 +30,19 @@ fi FAILED=0 pass() { echo " ✓ $1"; } fail() { echo " ✗ $1" >&2; FAILED=$((FAILED + 1)); } +warn() { echo " ⚠ $1" >&2; } + +# Registration assertions (fork/recall installed by the BASE image's +# entrypoint-user.sh via `pi install /opt/`) depend on the base, not the +# variant layer built here. validate.yml builds variants FROM the published +# base-latest, which can lag the entrypoint in the current commit (the base +# only rebuilds on a release tag), so a stale base-latest would red the +# push-to-main run with a false negative. These checks are therefore warn-only +# by default; the release pipeline (docker-publish-split.yml) builds the base +# fresh in the same run and sets STRICT_REGISTRATION=1 to enforce them hard. +# The build-time /opt + node_modules checks below stay hard in every path — +# those are produced by the variant layer and must always be correct. +STRICT_REGISTRATION="${STRICT_REGISTRATION:-0}" run() { # Run a command inside the image and capture its output. @@ -206,6 +219,19 @@ if docker run --rm --entrypoint="" "$IMAGE" sh -c "command -v pi" >/dev/null 2>& fi } + # Like exec_test but warn-only unless STRICT_REGISTRATION=1 (see note at top). + exec_test_reg() { + local label="$1"; shift + local out + if out=$(docker exec -u developer "$CID" sh -c "$*" 2>&1); then + pass "$label ($(echo "$out" | head -1))" + elif [ "$STRICT_REGISTRATION" = "1" ]; then + fail "$label: $out" + else + warn "$label (warn-only — stale base-latest? set STRICT_REGISTRATION=1 to enforce): $out" + fi + } + exec_test "~/.pi/agent/keybindings.json (pi-toolkit)" \ 'test -L $HOME/.pi/agent/keybindings.json && echo ok' exec_test "~/.pi/agent/extensions/*.ts ≥ 4 (pi-extensions)" \ @@ -225,9 +251,9 @@ if docker run --rm --entrypoint="" "$IMAGE" sh -c "command -v pi" >/dev/null 2>& fi sleep 1 done - exec_test "pi-fork registered in settings.json (fork tool)" \ + exec_test_reg "pi-fork registered in settings.json (fork tool)" \ 'grep -q pi-fork $HOME/.pi/agent/settings.json && echo ok' - exec_test "pi-observational-memory registered in settings.json (recall tool)" \ + exec_test_reg "pi-observational-memory registered in settings.json (recall tool)" \ 'grep -q pi-observational-memory $HOME/.pi/agent/settings.json && echo ok' docker rm -f "$CID" >/dev/null 2>&1 || true