docs: the withdrawal fix shipped in v1.9.1 unnamed — say so, and re-pin the canary
v1.9.1 bakes mempalace-toolkit e68ee20, which contains e2b060a. Requester-side
ask withdrawal has therefore been LIVE on every v1.9.1 device since 2026-09-10,
while the v1.9.0 section of CHANGELOG.md still read "not yet pinned ... this
image still pins e45f6b4", and the mempalace skill still told every agent at
session start that a withdrawal is impossible.
Measured, two independent routes, expectation recorded before looking:
- published image label, :v1.9.1-studio and :latest-studio (same digest):
se.jordbo.pi-devbox.mempalace-toolkit-ref = e68ee2071ca3ad39...
- ancestry: e2b060a is an ancestor of e68ee20
- baked mempalace.ts sha 7c16fe14 != v1.8.14's dfca71e9 (different bytes)
- grep -c isWithdrawn on this container's baked copy = 0 (v1.8.14, so
tor-ms22 cannot exercise the behaviour it is documenting)
The first label read came back EMPTY, and that empty was a claim about the
request rather than the image: Hub redirects blob fetches to a CDN and curl
without -L returns 0 bytes at exit 0. Recorded in the notes, because a registry
audit reporting "no labels" is missing -L until proven otherwise.
Changes:
- CHANGELOG Unreleased: the floating-ref mechanism, which is the reusable
part. ARG MEMPALACE_TOOLKIT_REF=main + CI resolving it to a SHA at build
time means a release absorbs whatever toolkit main holds, and "what
behaviour did this image gain" is a question nobody is forced to answer.
The fleet rule (name the pickup before tagging) was honoured for the
feed-tick commits v1.9.1 names, and missed for one in the same range.
- CHANGELOG v1.9.0: the stale caveat is ANNOTATED, not rewritten. The
sentence is the evidence for how the drift happened; deleting it would
destroy the only trace. Same discipline as fleet-ops d42412c.
- CHANGELOG Unreleased: corrected the size entry's "needs no base rebuild"
claim. True of that entry alone, false of the release now that the
vendored skill snapshot -- a base_tag input -- moves with it (~67 min).
- rootfs mempalace skill snapshot 44472 -> 46045 B, refreshed via
scripts/vendor-mempalace-skill.sh so the bytes and SKILLSET_SNAPSHOT_REF
(4d7c0ea -> e9e45f7) move together; --check confirms exact match.
- scripts/smoke-test.sh canary RE-PINNED. The retired pair was still green
against the new snapshot, i.e. blind to this refresh for the same reason
the pre-v1.8.13 pair was blind to that one. The replacement is stronger
than any predecessor here because BOTH witnesses come from the same
upstream commit: e9e45f7 added "Withdrawing an ask you sent" and deleted
"nothing anyone can do about it from the other end", the sentence the new
bullet contradicts. Directions measured against both files, then the
canary body EXECUTED against each: new -> rc=0 "ok", old -> rc=1 empty.
A canary whose negative witness was removed by the commit it pins fails
loudly on stale bytes instead of merely failing to notice them.
Gates: check-doc-drift OK, check-skill-floor OK, vendor --check OK,
hooks/pre-push OK (16 shell files clean at severity error).
Not fixable here: isWithdrawn is deployed and UNPROVEN. 17 assertions and 4
mutation kills, never once exercised on a released image against the live
logstream. Ask routed to a v1.9.1 device.
This commit is contained in:
@@ -100,6 +100,77 @@ Touches `Dockerfile.variant` and `scripts/smoke-test.sh` only: `Dockerfile.base`
|
||||
is unchanged, so this needs no base rebuild and should **ride the next release**
|
||||
rather than burn a cycle of its own.
|
||||
|
||||
> **Superseded by the entry below:** that entry refreshes the vendored mempalace
|
||||
> skill snapshot, which **is** hashed into `base_tag`. The release as a whole now
|
||||
> costs a base rebuild (~67 min). The *size* work above still needs none of its
|
||||
> own; the two simply travel together now.
|
||||
|
||||
**A behaviour change reached the fleet without any release naming it, and a
|
||||
paragraph in these notes kept saying it had not.** v1.9.1 bakes
|
||||
`mempalace-toolkit` **`e68ee20`**, which contains **`e2b060a`** — requester-side
|
||||
ask withdrawal (`isWithdrawn`, RFC 003 §3.3 clause 4). So the behaviour has been
|
||||
live on every v1.9.1 device since 2026-09-10, while the v1.9.0 section of this
|
||||
file still read "not yet pinned … this image still pins `e45f6b4`" and the
|
||||
mempalace skill still told every agent, at session start, that a withdrawal is
|
||||
impossible: *"there is nothing anyone can do about it from the other end."*
|
||||
|
||||
The mechanism is the point, because it will do this again. `Dockerfile.variant`
|
||||
carries `ARG MEMPALACE_TOOLKIT_REF=main` and `docker-publish.yml` resolves it to
|
||||
a commit SHA at build time (`gitea_sha mempalace-toolkit`). A release therefore
|
||||
absorbs *whatever toolkit `main` holds at that moment*, and "what behaviour did
|
||||
this image gain?" is a question **nobody is structurally forced to answer**. This
|
||||
fleet already has the rule — a floating ref that pulls a behaviour change into
|
||||
the image must be named in the CHANGELOG *before* tagging. It was honoured for
|
||||
the feed-tick fix, which v1.9.1 names explicitly (`309980b`, `e68ee20`), and
|
||||
missed for the commit sitting in the same range.
|
||||
|
||||
Measured before being written, two independent routes, expectation recorded
|
||||
first ("label should read ≥ `e68ee20`, since the build at 22:00Z postdates that
|
||||
commit's 18:58Z"):
|
||||
|
||||
| route | result |
|
||||
|---|---|
|
||||
| Docker Hub config-blob label, `:v1.9.1-studio` and `:latest-studio` (same digest) | `se.jordbo.pi-devbox.mempalace-toolkit-ref = e68ee2071ca3ad39…` |
|
||||
| `git merge-base --is-ancestor e2b060a e68ee20` | ancestor — the fix is inside the baked ref |
|
||||
| baked `extensions/pi/mempalace.ts` sha256 vs v1.8.14's | `7c16fe14…` vs `dfca71e9…` — different bytes, so not the pre-fix file |
|
||||
| `grep -c isWithdrawn` on this v1.8.14 container's baked copy | `0` — confirms the split, and that tor-ms22 cannot exercise it |
|
||||
|
||||
The first attempt at that label read **empty**, and the empty result was a claim
|
||||
about the request, not the image: Docker Hub redirects blob fetches to a CDN and
|
||||
`curl` without `-L` returns 0 bytes with exit 0. A registry audit that reports
|
||||
"no labels" should be assumed to be missing `-L` until proven otherwise.
|
||||
|
||||
So the skill is updated rather than deferred (skillset **`e9e45f7`**, vendored
|
||||
here with `scripts/vendor-mempalace-skill.sh`, `44472 → 46045 B`). Two things
|
||||
were deliberate:
|
||||
|
||||
- **The "silence is not an answer" rule keeps its teeth.** An ask still stays
|
||||
owed until the *recipient's* terminal event; what is new is a release by the
|
||||
**asker**, explicitly marked. Stated that way round on purpose — the wrong
|
||||
reading of this change is "withdrawals happen, so I need not reply".
|
||||
- **The precondition ships with the rule**, because this skill is read on images
|
||||
that lack the behaviour (tor-ms22, right now):
|
||||
`grep -c isWithdrawn /opt/mempalace-toolkit/extensions/pi/mempalace.ts`, where
|
||||
`0` means the withdrawal will not reach the recipient's mailbox. Same shape as
|
||||
the provenance bullet's live-bridge check.
|
||||
|
||||
**The snapshot canary is re-pinned, and this time it fails on the old bytes
|
||||
instead of merely failing to notice them.** The retired pair (`"Diaries
|
||||
self-heal…"` present / `"Agent diaries live in"` absent) was still green against
|
||||
the new snapshot, so it was blind to this refresh exactly as the pre-v1.8.13 pair
|
||||
was blind to that one. The replacement is stronger than any predecessor here
|
||||
because **both witnesses come from the same upstream commit**: `e9e45f7` added
|
||||
`"Withdrawing an ask you sent"` and deleted `"nothing anyone can do about it from
|
||||
the other end"`, the sentence the new bullet contradicts. Directions were
|
||||
measured against both files rather than read off the diff (`new=1/old=0` and
|
||||
`new=0/old=1`), then the canary body was **executed** against each: new → `rc=0
|
||||
ok`, old → `rc=1` empty.
|
||||
|
||||
Still outstanding, and not fixable from this device: `isWithdrawn` has 17
|
||||
assertions and 4 independent mutation kills, but has **never been exercised on a
|
||||
released image against the live logstream**. It is deployed and unproven — a
|
||||
different state from untested, and a worse one to leave unlabelled.
|
||||
|
||||
---
|
||||
|
||||
## v1.9.1 — 2026-09-10
|
||||
@@ -343,6 +414,20 @@ derivation's `mine` query at the newest end (`order: "desc"`); with the previous
|
||||
default `asc` + `limit: 100`, a device passing 100 authored events would have its
|
||||
recent replies fall out of the join window and see answered asks resurface.
|
||||
|
||||
> **Corrected 2026-09-14 (`pi@tor-ms22`, the device in the measured cost above).**
|
||||
> "This image still pins `e45f6b4`" and "until an image bakes `e2b060a` or later"
|
||||
> were true when written on 2026-09-09 and are **false for the running fleet**.
|
||||
> **v1.9.1 bakes `e68ee20`**, a descendant of `e2b060a`, so requester-side
|
||||
> withdrawal is LIVE wherever v1.9.1 runs. Measured from the published image's own
|
||||
> label (`se.jordbo.pi-devbox.mempalace-toolkit-ref`) rather than from these
|
||||
> notes, and cross-checked by ancestry and by the baked `mempalace.ts` sha
|
||||
> differing from v1.8.14's. Nothing here was mis-stated on purpose:
|
||||
> `ARG MEMPALACE_TOOLKIT_REF=main` is resolved to a commit SHA by CI at build
|
||||
> time, so the release absorbed the commit without anybody having to name it,
|
||||
> while this paragraph went on asserting it had not. Left standing rather than
|
||||
> rewritten — the sentence is the evidence for how the drift happened. See
|
||||
> Unreleased.
|
||||
|
||||
**Four small packages, each chosen from a gap that was measured rather than
|
||||
imagined.** All four were picked by looking back at a real session — the
|
||||
`gitea.egl.lan`/FreeIPA debugging of 2026-09-09..10 — and asking which absences
|
||||
|
||||
Reference in New Issue
Block a user