---
name: v0121-published
description: "v0.12.1 published 2026-06-18 (counter 26, PATCH); real-harness lifecycle fixes + CLI polish"
metadata: 
  node_type: memory
  type: project
  originSessionId: 291b3f47-b265-4a38-867f-ac3d798281c0
  modified: 2026-08-19T20:24:57.107Z
---

v0.12.1 PUBLIC 2026-06-18 (counter 26); PATCH 0.12.0→0.12.1; real-harness lifecycle fixes (v0.12.0 lifecycle fixes were green-on-mocks but broken in the real claude-spt harness — see [[v0121-realharness-reopen]]): attach output, tab-close survival (viewer-close-detach), broker attach wedge/deadlock; + CLI polish (endpoint list always-merges-local / `--local` removed, picker Attach-for-online + fresh-shows-under-project, `spt --help` renders markdown). main @86f20ac.

DIVISION OF LABOR (differs from prior releases): **doyle drove changelog→bump (0.12.0→0.12.1)→merge-to-main→green CI both runners→tag**; deployah leg = SIGN + PUBLISH ONLY (RELEASE-RUNBOOK step 4). todlando cross-checked changelog scope; 2 trailing commits (185eaee/86f20ac) = test/CI-hygiene, no bullet (correct per [[changelog-scope-vs-commit-range]]). sign+publish: update-set v26. Hashes: linux `fa6a3cdfdd7555d0…` / win `2c5ca121ed14c20b…`. Publisher leg 20× clean (counter 7-26).

COUNTER: v0.12.0=25 → v0.12.1=26 (confirmed vs my publish logs; release-publish monotonic rollback-floor accepted 26). hfenduleam disk held (~322G free, recovered from the mid-session 100%-full event). EIGHT releases this revive session: v0.8.3→v0.8.4→v0.9.0→v0.9.1→v0.10.0→v0.11.0→v0.12.0→v0.12.1. See [[v0120-published]].

## ✅ v0.46.0 PUBLISHED 2026-07-30T02:07:18Z — counter 81 — REL_SHA `8f3e10bc05400d133b4eb0a1a48c388490f38cb7`

**Full note: [[v0460-published]]** (deployah's, from the driver's seat — tree-sha check, both time-varying reads,
signed-metadata hashes, the corrected quiet predicate). Not duplicated here. Two facts of mine that it does not carry:

- ⚠ **The sha is `8f3e10b`, NOT `af65ac0`.** My own index carried af65ac0 as the pending v0.46.0 tip and it was
  stale by **11 commits** — the repair batch. Anyone resuming off a stale index would publish the wrong tree.
- **Releases live on `BigscreenVR/spt-bs-releases`; `repos/BigscreenVR/spt-bs-core/releases/latest` returns 404.**
  My independent verification: `tag_name v0.46.0 · draft=false · prerelease=false · target_commitish=main ·
  11 assets`, plus `git ls-remote` on the server for both `refs/tags/v0.46.0` and `refs/heads/main` — both
  `8f3e10b`, so tested == tagged == main == published, checked without relying on deployah's report.
  ⚠ I nearly reported that without naming which repo answered, because a `||` fallback swallowed the first call's
  failure — **a fallback chain hides which branch produced the answer; split it when the source is the claim.**

## ⚠ 2026-08-03 CORRECTION — latest is v0.52.0, not v0.46.0. Cause = a FORKED MEMORY ROOT.

This ledger sat on **v0.46.0 c81** while **six** more releases shipped. Re-measured 2026-08-03:
`gh release list --repo BigscreenVR/spt-bs-releases` for the published set, `git ls-remote origin
refs/tags/<v>` (origin = `BigscreenVR/spt-bs-core`) for the tag shas, counters from store A's
per-version notes (see the mechanism section below).

| version | published (UTC) | tag sha | counter | theme |
|---|---|---|---|---|
| v0.47.0 | 2026-07-31T04:20:28Z | `00f3f92` | 82 | fast-follow to A: engine-room ceremony verb, roster access views, admin ceremonies on subnet create/revoke |
| v0.48.0 | see ⚠ below | `0f90431` | 83 | reachability honesty: firewall check, partial-outage verdict, published-address self-repair |
| v0.49.0 | 2026-07-31T22:13:15Z | `2a66d78` | 84 | knocking + monics + trust warning + node-wide rules; fork-loses-role fix |
| v0.50.0 | 2026-08-01T10:51:49Z | `68e50a9` | 85 | HANDRAIL (releases#69): agents refused daemon-stop, once-per-session caution, cross-machine fork |
| v0.51.0 | 2026-08-02T05:12:05Z | `6312b01` | 86 | DOORBELL (releases#80): cross-machine invite codes, knock direction required, ER bring-up on a fresh node |
| v0.52.0 | 2026-08-02T19:58:49Z | `32a8bad` | 87 | BAROMETER (releases#114): closed-subnet enforcement at the minting node, persistent shells across reboot, authenticated lifecycle kills |

**Corroboration that is actually independent:** the six tag shas came from `git ls-remote` against
the server; the same six appear in store A's release notes, written at publish time by a different
session with no access to today's measurement. Two sources, one answer.

⚠ **One disagreement, unresolved, not papered over:** `gh release list` reports v0.48.0 at
`2026-07-31T12:35:31Z`; store A's note says published `10:16:13Z`. The other five agree to the
second. Do not quote a v0.48.0 publish time from either until one is re-derived — likely a
publishedAt-vs-release.yml-completion distinction, but that is a guess, not a measurement.

### ⭐⭐ The mechanism was NOT silent decay — my first diagnosis of this was wrong

I initially wrote that a "latest = X" line simply rots unnoticed. **Operator supplied the real
cause: for several days I was operating under a DIFFERENT memory root**, so the writes never came
here to rot — they landed in another store.

- **Store A** — `C:\Users\decid\.claude\projects\C--Users-decid-Documents-projects-spt-core\memory\`
  — 153 files, MEMORY.md last written 2026-08-03 00:21. Holds the last several days: every release
  note v0.47–v0.52 with counters, `infra-register-ruling`, `ir18-lane-and-b-split-assignment`,
  `confirmation-without-postop-sha`, `stale-breadcrumb-tree-kill-class`, `gh-run-poll-jobs-not-status`.
- **Store B** — `C:\Users\decid\.ccs\instances\bigscreen\projects\C--Users-decid-Documents-projects-spt-core\memory\`
  — 329 files. **This file's store**, and the one loaded into the 2026-08-03 02:00 session.

**They are nearly DISJOINT: exactly 5 shared filenames** (`MEMORY.md`, `alarm-every-test-run`,
`v0250-published`, `v0310-published`, `v0460-published`) — 148 of A's 153 files exist nowhere in B.
This is not drift between two copies of one store; it is two separate minds, and which one I wake
up with is decided by the session's root, not by me.

⭐⭐ **Why the wrong diagnosis is the interesting part.** Staleness and a forked root produce an
IDENTICAL symptom — an index line reading older than the world — so the symptom cannot discriminate
them, and I picked the boring cause without looking for a second store. The discriminator costs one
command (`find ~ -name MEMORY.md`) and would have shown two roots immediately. **When a record is
behind reality, ask whether the writes went somewhere else before concluding they were never made.**
Same family as [[hedging-classification-is-not-grounding-the-observation]] and
[[a-predicate-without-its-tool-is-not-evidence]] — I named a mechanism without running the probe
that separates it from its twin. See [[two-memory-roots-diverged]].

## ✅ v0.53.0 PUBLISHED 2026-08-04T01:59:24Z — counter 88 — tag `b7b00c3` (LOCKSMITH #132)

Driven by me (deployah) end to end after a ~16h UNBOUND gap; doyle held the whole merge queue parked at
the golden sha the entire time. Verified from PUBLISHED artifacts, not from the publish tool's stdout:
`update-set.json` and the per-binary metadata both decode `version=88, product_version=0.53.0,
key_id=rel-primary-2026, brain_ipc_version=1, broker_resource_abi=1`. draft=false, Latest, 11 assets.
Counter 87→88 derived at time of use from v0.52.0's signed metadata, never carried from memory.

⭐⭐ **Tag the ruled sha EXPLICITLY — bare HEAD nearly pinned the tag to a docs tip.** The runbook said
`git tag v0.X.Y` at HEAD, but this is a SHARED checkout: local main sat at doyle's unpushed register
commits (`9308d52`) while origin/main was the golden sha `b7b00c3`. Bare-HEAD tagging would have broken
`tested sha == shipped sha` using the very checkout doyle froze the queue to protect. I tagged the sha
explicitly. doyle BUILT the fix same session — step 4 now reads "tag the ruled sha explicitly, never bare
HEAD". See [[hold-pushes-during-the-tag-window]] (this is its shared-checkout twin: the danger is not only
someone pushing, it is your own local main already being ahead).

⭐ **The quiet-window predicate must measure the POPULATION, not remembered pids.** My first wait polled
three hardcoded pids and returned "pool free" on poll 1 — a predicate that reads clean the moment those
pids exit even if the same lane respawns cargo under new ones. Re-measured the whole cargo/rustc/link
population with a positive control on the filter first: 7 processes, all rooted at
`Runner.Worker`/`RunnerService` (already-counted CI axis), zero user-shell-rooted. That is what I signed on.
Earlier the same probe found 3 cargos rooted at `claude.exe(34920)` — a PEER live agent (mine was `24264`),
not CI — so step 5's "user-shell-rooted blocks signing" fired correctly. Did not reap another lane's
processes. Attribute by FULL parent chain; `rustup.exe` as immediate parent tells you nothing.

See [[board-credits-a-rider-the-notes-drop]] for the changelog defect this cut surfaced.

## ✅ v0.57.0 PUBLISHED 2026-08-19T20:22:17Z — counter 92 — tag `a0f9ecd` (KEYSTONE #182, ten members)

Driven by me end to end. Verified from PUBLISHED artifacts: `version=92, product_version=0.57.0,
key_id=rel-primary-2026, brain_ipc_version=1, broker_resource_abi=1`; draft=false, 11 assets; flip
proven via `repos/.../releases/latest` → `v0.57.0`. **`gh release view --json isLatest` does not
exist** — that field errors the whole query out; use the API endpoint, which is what clients ask
anyway. Board: all ten members `state: DONE`, roundup credited **11** (the ten + #182 itself).

⭐⭐ **The golden head was NOT release-shaped, and that is the NORM — not the anomaly I first took it
for.** `901a9f5` carried `version = "0.56.0"` and no `## [0.57.0]` section; so did `main`. Tagging it
would have failed `release.yml`'s changelog extraction and shipped binaries rendering the previous
version. Measured across the last four cuts, the bump rode INSIDE the golden candidate exactly once
(v0.56.0's respin head); v0.54.0, v0.55.0 and v0.57.0 all added it afterward — and v0.54.0's own commit
subject says so out loud: *"bump, and the changelog the tested head never carried."* So the
provability-bar route is the ORDINARY outcome and the runbook's "bump rides in the candidate" is the
minority practice. Amendment landed making the release-shape check a two-command leg with that table
in it. **The intake legs that all passed on an unshaped head — ancestry, picks, patch-id, blob
fidelity, greenlit form, traceable-reqs, docs-drift, clippy — none of them imply it.**

⭐⭐ **A negative result is a claim about your instrument until a control says otherwise.** Hit twice
in one hour, same shape, both nearly reported as fact: (1) an empty grep for a test row read as "the
cell never ran" — `nextest` pads the index as `( 980/2611)` and my pattern demanded `(980/2611)`; a
plain-name control found it. (2) a single dead pid read as "the lane finished" — the lane was a LOOP
of fresh cargo pids. Fix for the second is a span, not an instant: require absence across longer than
the loop's inter-run gap, **and that gap is the loop owner's number, not the watcher's** (todlando
named the mechanism; my waiter survived it only because I had widened it against the wrong hazard).

⭐ **Thin-CI red at a code-identical sha ≠ a red against the artifact.** `ci` failed at `9ea595c`
(Windows unit only) on `rc::tests::attach_viewport_reconnects_across_a_broker_bounce`. Cleared for
publish by measurement, not narrative: the cell EXECUTED and passed at golden `901a9f5`
(`PASS [3.530s]`, read off the raw job-log row), `901a9f5..9ea595c` is one docs file with zero `.rs`
so the bytes were identical across pass and fail, and the milestone's rc change `e8a3582` (hunks
1306–1356, 3079–3132) does not intersect the failing fn (3391–3594). **Refused to file it as the
ledgered flake:** ledger line 37's signature is a 240s starvation TIMEOUT whose remedy
(`heavy-broker-pty`, `max-threads = 1`) is already in force — this was an ASSERTION at 33.65s while
serialized. Same cell, different mechanism; an entry whose mechanism no longer fits is not a
dismissal. Specimen to hertz, ledger EXTENDED not matched.

⭐ **The harm direction of the quiet window is outbound, not inbound.** Step 5 reads as protecting
*your* signing from contention; the live risk was my build stretching todlando's timing-sensitive ER
battery and fabricating a red in a lane two tickets depended on. Held the signature for it (doyle
ruled: do not preempt), then deliberately signed INTO hertz's dependency-compile phase rather than
waiting for a quiet box that would next contain his timing measurements. Same reasoning held the
runbook docs push back afterward — pushing to `main` fires a 2611-test Windows suite on the box.

## Index-line archive (compacted out of MEMORY.md 2026-07-26)
- **2026-07-30: latest = v0.46.0 c81 @`8f3e10b`** ([note](v0460-published.md) — milestone A W0-W3 access control; FIRST golden-CI release; ⭐⭐ tree-sha-before-merge is the only check that answers *which tree shipped*; ⭐⭐ counter decoded from the signed artifact twice, 80 out / 81 in; ⭐ quiet = "no non-terminal run", never a process count during release.yml). Prior **v0.45.0 c80 @899f466** ([note](v0450-published.md)).
- [Published releases ledger](v0121-published.md) — earlier: **v0.44.0 c79 @2189f87** ([note](v0440-published.md) — RESIDENT-SERVICE W1; ⭐⭐ disk-exhaustion incident cost 2 CI windows: I under-named my own discharge (ranked the 12.2GB measurement second, root was disk not load); ⭐ Windows fixture temp-dir LEAK = 14,319 `.tmp*` dirs/163GB, first symptom is always a mystery timing red — REQ seed + free-space preflight proposed; ⭐ fast-fail duration argues AGAINST load; ⭐ expect() label ≠ measurement); prior **v0.43.1 c78**, **v0.43.0 c77** (cut by another session, no notes); prior **v0.42.0 c76 @8492c75** ([note](v0420-published.md) — IDLE-EDGE W1; ⭐ generated-docs gate blind spot caught AT the cut; MINOR-vs-patch reasoning); prior **v0.41.1 c75 @0493840** ([note](v0411-published.md)); prior **v0.41.0 c74 @3aecc35** ([note](v0410-published.md) — ⚠ seed-exposure incident, OPERATOR ACCEPTED RISK, rotation WITHDRAWN — read ruling banner before acting; probe-idiom ban unconditional); 40.0=73, 39.4=72, 39.3=71, 39.2=70, 39.1=69, 39.0=68, 38.1=67; full counter table in file.
