diff --git a/persistent-memory.d/2026-09-01-althing-320-deploy.md b/persistent-memory.d/2026-09-01-althing-320-deploy.md index 5106148..1772627 100644 --- a/persistent-memory.d/2026-09-01-althing-320-deploy.md +++ b/persistent-memory.d/2026-09-01-althing-320-deploy.md @@ -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 diff --git a/persistent-memory.md b/persistent-memory.md index 33114d0..92c5da7 100644 --- a/persistent-memory.md +++ b/persistent-memory.md @@ -148,7 +148,14 @@ _As of 2026-09-01 — **the GX10 is on the operator's desk, NOT racked. Standing measured it on Aug 28 — didn't check whether it was already settled before calling it open. Delivery now confirmed on `claude`, `pi` and `grok` seats. ⚠ One-tick latency after `declare` reads as failure; `--discover-pid` on a non-Claude process - tree remains untested. → `persistent-memory.d/2026-09-01-althing-320-deploy.md` + tree remains untested. + 🔴 **3.2.1 SAME NIGHT (22:40)** — 3.2.0 wrote pokes into panes people were **typing in** + (append + Enter submits their half-written message; hit the operator within the hour). Guard 4 + pins `idle_cursor` and stays silent when the column moved. ⚠ **2 of 5 pane seats CANNOT be + guarded** — `kimi` and `pi` report no cursor at all, so bil- and regin-smithy-dev stay + permanently exposed; "3.2.1 fixes it" is true only where the cursor is legible. Mitigation for + those = `althing-route release` (pull-only). ⚠ Declare with an EMPTY input line or the pin + captures a composing cursor. → `persistent-memory.d/2026-09-01-althing-320-deploy.md` - **✅ A6000 window CLOSED 2026-09-01 — operator freed ComfyUI's VRAM instead of anyone stopping it.** ⚠ It was a **model unload, not a stop**: `comfyui` still up 8 days, same pid, HTTP 200, 18,500 -> 612 MiB. ⚠ **The resulting ~43.8 GB free is a snapshot, not a floor** —