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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user