release(v1.9.5): pi 0.87.1 with pi-obsmem pinned to the merged finishTurn fix
Lint / skill-floor (push) Successful in 7s
Lint / hadolint (push) Successful in 14s
Lint / actionlint (push) Successful in 19s
Lint / doc-drift (push) Successful in 12s

v1.9.4 held pi at 0.85.1 because 0.87.0 REMOVED `shouldStopAfterTurn`, which
pi-observational-memory 3.1.4 still used in all three workers. Its peerDeps are
`*`, so nothing refuses at install time and the breakage is silent at runtime --
turn caps ignored, workers losing their specialised prompts. PR #83 fixes that
and merged 2026-09-23.

Re-measured 2026-10-01 across src/agents/{observer,reflector,dropper}/agent.ts,
deliberately reusing the v1.9.4 audit's counting method so the numbers compare:

  e7d77dc (3.1.4, baked in v1.9.4): shouldStopAfterTurn 3, finishTurn 0, systemPrompt 3
  731c3d4 (pinned here)           : shouldStopAfterTurn 0, finishTurn 3, systemPrompt 0

All three workers migrated, and the 0.86.0 AgentContext.systemPrompt reads are
gone too. The coupling is asymmetric and that is why these move in ONE commit:
3.1.4 + 0.87.1 silently ignores turn caps, and 731c3d4 + 0.85.1 breaks the
workers outright, because finishTurn does not exist before 0.87.0.

Pinned to a SHA rather than waiting for a tag, departing from the v1.9.4
instruction to wait for a release: #83 is merged but the newest obsmem tag is
still 3.1.4, cut 2026-09-20, BEFORE the merge. Upstream tags slowly and moves
master often (e7d77dc -> 1529e14 -> 731c3d4 in nine days), so waiting means
holding pi indefinitely. A pinned SHA keeps the property `master` lacks:
rebuilding this tag later produces the same image.

The 40-char form is load-bearing, not pedantry. check-doc-drift.sh recognises a
literal SHA only through a 40-char match, so a 7-char pin would fall through to
its branch-or-tag lookup, fail to resolve, and downgrade pi-obsmem's drift check
to a silent SKIP -- a pin that reads correctly and is no longer verified. Full
gate run after this change: 23 OK, 0 DRIFT, 0 SKIP, 0 FAIL.

0.99.0/0.99.1/0.99.2 and 1.0.0 all exist upstream and are deliberately skipped:
obsmem's only compatibility work names Pi 0.87 (2b1dc1c) and a repo-wide
issue/PR search for 0.99 or 1.0 returns zero matches. 1.0.0 is its own round.

pi-atelier stays at v0.10.3 and is the residual risk. Its peerDeps declare pi
>=0.84.0 -- a floor, satisfied -- on both v0.10.3 and the current v0.12.1, so it
spans this bump. But atelier hooks pi TUI internals that a declared floor does
not protect, and an under-declared floor is exactly what failed to warn anyone
at pi 0.84. Acceptance must confirm the sidebar PAINTS, using the two-sided
check from 0.84.4/0.85.1 that distinguishes "loaded" from "silently absent".

Also here:
- check-doc-drift.sh gains a pi-obsmem pin check. The ref-move check covers the
  same component, but for a pinned SHA it can only answer "upstream did not
  move", never "the table still says what we bake".
- scripts/lint-shell.sh mode 100644 -> 100755. Pre-existing since f25efa0 and
  the only non-executable script in scripts/; it was latent because both CI
  steps call it as `bash scripts/lint-shell.sh`, but it failed rc=126 "bad
  interpreter" when invoked directly. Same dropped-exec-bit signature recorded
  on 2026-09-22, found the same way: by RUNNING it, not by reading a diff.
- Unreleased section renamed to `## v1.9.5 — 2026-10-02`, satisfying the
  release-gate rule that a tag's CHANGELOG must name its own version.
This commit is contained in:
Joakim Persson
2026-10-02 00:23:28 +02:00
parent cb8969ef2c
commit 9d0b3dec0b
5 changed files with 115 additions and 10 deletions
+43 -2
View File
@@ -134,7 +134,41 @@ ARG USER_NAME=developer
# contract) and its registerTool calls spread the built-in tools so they
# carry parameter schemas (#9300). 0.86.1 as an intermediate is untested and
# not worth the pty matrix for a stop that #83 will make moot.
ARG PI_VERSION=0.85.1
#
# v1.9.5: 0.85.1 -> 0.87.1, and pi-obsmem moves off `master` to a pinned SHA in
# the SAME commit, because neither is safe alone. 0.87.0 REMOVED
# `shouldStopAfterTurn`, which 3.1.4 still used; the pinned tip uses
# `finishTurn`, which does not exist before 0.87.0. So 3.1.4 + 0.87.1 silently
# ignores turn caps, and the new tip + 0.85.1 breaks the workers outright — the
# pair only works together, exactly as the v1.9.4 note predicted.
# MEASURED 2026-10-01 across src/agents/{observer,reflector,dropper}/agent.ts,
# deliberately the same counting method as the v1.9.4 audit above so the two
# numbers are comparable:
# 3.1.4 (e7d77dc): shouldStopAfterTurn 3, finishTurn 0, systemPrompt 3
# 731c3d4 (pinned) : shouldStopAfterTurn 0, finishTurn 3, systemPrompt 0
# i.e. all three workers migrated, and the 0.86.0 `AgentContext.systemPrompt`
# reads are gone too. #82/#83 merged 2026-09-23.
# WHY A SHA AND NOT A TAG, departing from the v1.9.4 instruction to wait for a
# release: #83 is merged, but the newest obsmem tag is STILL 3.1.4, cut
# 2026-09-20 — before the merge. Upstream tags slowly while moving master often
# (e7d77dc -> 1529e14 -> 731c3d4 in the nine days to 2026-10-01), so waiting for
# a tag means holding pi indefinitely. A full SHA keeps the one property
# `master` does not have: rebuilding this tag later produces the SAME image.
# SKIPPING 0.99.0/0.99.1/0.99.2 and 1.0.0, which all exist upstream: obsmem's
# only compatibility work names Pi 0.87 ("fix: support Pi 0.87 agent APIs",
# 2b1dc1c), and a repo-wide issue/PR search for "0.99" or "1.0" returns ZERO
# matches. Its peerDependencies are `*`, so nothing would refuse at install
# time and a 1.0.0 bump would fail silently at RUNTIME. 0.87.1 is the highest
# version the evidence actually covers; 1.0.0 is a separate round.
# pi-atelier v0.10.3 is deliberately NOT bumped here: its peerDependencies
# declare pi >=0.84.0 — a FLOOR, satisfied by 0.87.1 — on both v0.10.3 and the
# current upstream v0.12.1, so it spans this bump either way. It is the residual
# risk, because atelier hooks pi TUI internals (the `TuiMainScreen` prototype,
# `renderLayoutFrame`) that a declared floor does not protect, and a floor is
# exactly what failed to warn us at pi 0.84. Acceptance must confirm the sidebar
# still PAINTS — the same two-sided check used at 0.84.4 and 0.85.1, which can
# tell "loaded" from "silently absent".
ARG PI_VERSION=0.87.1
ARG PI_TOOLKIT_REF=main
ARG PI_EXTENSIONS_REF=main
# Repo URLs default to the canonical gitea origin but are overridable so a
@@ -149,7 +183,14 @@ ARG PI_EXTENSIONS_REPO=https://gitea.jordbo.se/joakimp/pi-extensions.git
ARG PI_FORK_REPO=https://github.com/elpapi42/pi-fork.git
ARG PI_FORK_REF=master
ARG PI_OBSMEM_REPO=https://github.com/elpapi42/pi-observational-memory.git
ARG PI_OBSMEM_REF=master
# PINNED to a full 40-char SHA as of v1.9.5, not `master` — see the PI_VERSION
# note above for the measurement and the reasoning. Moves together with
# PI_VERSION by necessity, not by convention. The width matters: 731c3d4 is the
# same commit, but check-doc-drift.sh recognises a literal SHA only via a
# 40-char match (SHA40), so a short pin would fall through to its
# branch-or-tag lookup, fail, and downgrade that component's drift check to a
# silent SKIP — a pin that reads fine and is no longer verified.
ARG PI_OBSMEM_REF=731c3d49288580f4d79cabdbfbc0d16b34db0f41
# pi-atelier (TUI sidebar: ordered panels, split-pane, themes) is PINNED TO A
# TAG, which CI resolves to that tag's commit SHA — same treatment as
# pi-studio, for reproducibility plus cache-busting.