You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Keep unknown pane ownership legible through tolerant reads
Ordinary renderer polling could erase the very evidence the strict
column-agent launch depends on: tolerant recovery swept a pane whose
record it could not read out of the coordinator record, so a later
strict read found a clean set and could open a second review agent
beside a process nobody can account for. A pane whose record is present
but untrustworthy is now marked ownership-unknown and kept in the record
on both paths, while a pane that left no record at all is still swept as
the dead pane it is. The coordinator record gets the same treatment via
a strict read that separates ENOENT from corrupt. Failure copy selection
is now exhaustive over the reason codes, so a new recognised reason
cannot compile without its localized copy.
Copy file name to clipboardExpand all lines: decisions/197-column-agent-pane-ownership-and-failure-reason.md
+1Lines changed: 1 addition & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,6 +12,7 @@ Reproduced on a native task through the card's status menu: `launchColumnAgent S
12
12
13
13
The pane is owned by purpose, not by a remembered id: `launchColumnAgent` goes through `openAuxPane` under a new `AuxPanePurpose` value `columnAgent` whose marker is the existing `col-agent.sh` temp path, the `col-agent-pane` id file is gone, and `replaceAuxPanes` closes every pane the purpose owns and re-reads the set to prove they went — a launch that cannot prove it refuses rather than risk two agents in one worktree.
14
14
Proof covers the LOOKUP too, because several production paths turn an undecidable read into an empty list (`readPaneSet` catches every recovery exception, a `null` pane set becomes `[]`, an unreadable pane record becomes `command: []`, a tmux error becomes no rows), so the replacement path reads through `readPaneSetStrict` / `nativeTaskPaneCommandsStrict` and, at the root, through `recoverPaneSet(..., { strict: true })` — which throws `PaneOwnershipUnknownError` before reconciling an unknown-owner pane away, since sweeping it would delete the evidence while its shell keeps running.
15
+
The line is drawn at whether there was anything to read: no record and no coordinator file mean the pane really is gone and it is swept exactly as before, while a record (or coordinator record) that is present and untrustworthy — corrupt, foreign-schema, unreadable — marks the pane ownership-unknown, and `recoverPaneSet` keeps that pane in the record even on the tolerant path, so ordinary renderer polling can no longer erase the evidence before a strict launch reads it.
15
16
A stopped task terminal is never resurrected (that would cut across decision 184's explicit wake); the task is parked in Your Review with an actionable message instead.
16
17
The failure is reported as well as parked: `columnAgentFailed` carries `column: ColumnAgentIdentity`, `movedTo?` and `reason?`, `columnAgentFailureCopy` picks one of four localized keys and localizes a built-in column from its status, and the report is emitted only after the fallback move's column write lands — a rejected or failed write stops the effect run, so the toast can never claim a move that did not happen, and the renderer never reads the English `error` string.
0 commit comments