memory: snapshot — althing 3.2.1 deployed; guard 4 cannot cover two of five seats

3.2.0 wrote its pokes into pane input lines and pressed Enter, so anyone
mid-sentence had their half-written message submitted with the herald's
line stapled on. It hit the operator within an hour of this evening's
deploy. 3.2.1 adds a fourth guard that pins the pane's idle cursor column
and stays silent when the live column has moved.

Deployed all three steps at 22:40 and re-declared this seat, which pinned
idle_cursor=3 as expected for a claude TUI.

The finding worth keeping is the hole the fix leaves. forseti's own
measurements say kimi and pi report no cursor at all, which means
bil-smithy-dev and regin-smithy-dev can never acquire guard 4 no matter
what they run. Two of the five pane seats on this box stay permanently
exposed to the bug 3.2.1 fixes, so the sentence "3.2.1 fixes the
write-into-a-typing-pane bug" is only true where the cursor is legible.
All four seats were told, differentiated: a pre-filled re-declare and the
expected column for the two that can be guarded, and the honest version
plus the release-to-pull-only option for the two that cannot.

Also keeping forseti's post-mortem line, because it generalises: three
guards that all answer "is this the right pane" and none that asks
whether it is a good moment are one check wearing three hats.
This commit is contained in:
vh
2026-09-01 22:42:54 -07:00
parent 28dd516be1
commit 1c7bd40c9c
2 changed files with 68 additions and 1 deletions
@@ -177,6 +177,66 @@ failure, in case anyone else reports it as one."* Asked forseti for a line in th
**Withdrawn:** non-Claude delivery risk (was forseti's own prior work).
**Moot:** log back-off — zero stale routes, the log went quiet on its own.
## 🔴 3.2.1 SAME NIGHT (22:40) — 3.2.0 WROTE INTO PANES PEOPLE WERE TYPING IN
**The bug, which hit the operator within an hour of the 3.2.0 deploy:** the herald writes its
poke into a pane's input line and presses Enter. If someone is **mid-sentence there**,
`write-chars` **APPENDS** to what they typed and the Enter **submits the lot** — their
half-written message with the herald's line stapled on.
forseti's post-mortem, worth keeping verbatim because it generalises well past althing:
> The contract named this hazard on one road only — a submit after a FAILED write — and I
> built three guards that all answer the same question, "is this the right pane". **None of
> them asked whether it was a good MOMENT.**
⚠ **Three independent checks that share a premise are one check wearing three hats.**
**The fix — guard 4.** The route pins `idle_cursor`, the cursor column the pane sits at with
its input line empty, captured at declare time. Before writing, the herald reads the live
column; if it moved, someone is composing and it stays silent. The signal was already in the
`list-panes` response fetched every tick and was being parsed and thrown away — the fix cost
nothing at the wire.
22:40:xx uv tool install --force . 3.2.0 -> 3.2.1 (cb699f2), 7 executables
22:40:37 systemctl --user restart althing-po-herald 2850064 -> 2913820
22:40:40 scripts/sync_skill.sh --check clean
## ⚠⚠ THE HOLE 3.2.1 LEAVES — 2 OF 5 PANE SEATS CANNOT BE GUARDED, EVER
forseti measured the idle columns; applied to the live route table this is not a footnote:
handle TUI guard 4?
infra-ops claude YES idle_cursor=3 (pinned 22:41)
eitri-smithy-dev codex YES expects 3
dvalin-smithy-dev grok YES expects 7
bil-smithy-dev kimi NO -- reports no cursor at all
regin-smithy-dev pi NO -- reports no cursor at all
**40% of pane seats stay permanently exposed to the bug 3.2.1 fixes, and no command changes
it.** "3.2.1 fixes the write-into-a-typing-pane bug" is true only where the cursor is legible —
⚠ **do not quote that framing flat.** The design fails honestly (missing `idle_cursor` is
logged, not silently assumed safe) but logged-and-poked is still poked.
**Exposure only materialises when a human composes in that pane** — in practice the operator,
in whichever agent pane he is talking to. Mitigation for an unguardable seat is
`althing-route release` (pull-only; the bug becomes structurally impossible), reversible with
`althing-route declare --discover-pid`.
⚠ **Declare with an EMPTY input line** or the pin captures a composing cursor and the seat goes
needlessly quiet.
**Two costs forseti named:** a deferred poke **spends a rung** (refused at rung 0 it returns in
5 min; at the terminal rung, an hour), and the check runs **before** the write so a ~200 ms
collision window remains.
All four seats notified, differentiated: re-declare instructions with pre-filled pid and the
expected column for the two that can be guarded; the honest "this cannot cover you, here are
your two real options" for the two that cannot.
**Migration:** none beyond the restart. Routes without `idle_cursor` are poked as-is. CC seats
re-pin at next SessionStart; TUI peers when they next re-declare.
## Rollback (unused)
`uv tool install althing-core==3.1.2` restores the six binaries; the SessionStart hook returns