Skip to content

Launch the AI Review agent on native tasks, and report it when the launch fails - #1229

Merged
h0x91b merged 10 commits into
mainfrom
fix/dev3-pr-ai-review-launch
Aug 3, 2026
Merged

Launch the AI Review agent on native tasks, and report it when the launch fails#1229
h0x91b merged 10 commits into
mainfrom
fix/dev3-pr-ai-review-launch

Conversation

@h0x91b

@h0x91b h0x91b commented Aug 2, 2026

Copy link
Copy Markdown
Owner

Hey — Claude here, the AI assistant that wrote this branch.

Moving a task to AI Review did nothing on any task using the native terminal backend, which is every task created since the native rollout default flipped. Two independent defects, both in that one path:

  1. launchColumnAgent still opened the review agent with a raw tmux split-window into dev3-task-<id>. A native task has no such session, so the split died on the socket (can't find pane: dev3-… / Socket operation on non-socket).
  2. machine.ts handled the resulting columnAgentFailed for review-by-ai by returning only the fallback move to Your Review — no push, no toast. The card hopped back on its own and said nothing, which is exactly the "AI Review does nothing" symptom.

What changed

  • The review agent now opens its pane through the backend-neutral seam (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: ownership is re-derived from the launch command, so a repeated activation replaces the running review agent instead of stacking a second one, and it keeps working after an app restart. The native path touches no tmux; the tmux path keeps its 40% right split and still hands focus back to pane 0.
  • A failed launch is now reported as well as parked. columnAgentFailed gained movedTo?: TaskStatus so the copy can say where the task went, and reason?: ColumnAgentFailureReason so a failure the app recognises is explained in localized copy. terminal-not-running is the first such reason; the renderer picks one of four keys (en/ru/es) from reason × movedTo and never reads the English error string — that stays diagnostic interpolation for failures we can only quote.
  • A stopped task terminal is deliberately not resurrected: an auxiliary-agent launch requires a live terminal, and the toast says to open the task and retry. Auto-starting it would cut across the explicit hibernation/wake semantics of decision 184.

Rationale and rejected alternatives: decisions/197-column-agent-pane-ownership-and-failure-reason.md.

@h0x91b
h0x91b force-pushed the fix/dev3-pr-ai-review-launch branch 3 times, most recently from d90ec30 to 406c3da Compare August 3, 2026 09:39
h0x91b-wix and others added 10 commits August 3, 2026 13:04
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.
Structural validity was being read as ownership. A coordinator record
copied from another coordinator, or one binding a pane to a session that
coordinator never derives, passed every field check while describing
processes we cannot account for; the same went for a per-pane record
found under one session while claiming another. All three now mark the
set undecidable rather than owned, on the tolerant path as well.

Recovery also handed back the pre-sweep tree whenever any pane was
ownership-unknown, so a proved-dead pane could be cached and republished
under the same epoch by a later focus. It now returns the reconciled tree
it just persisted, in every case.

The per-pane check deliberately compares sessionId only: the host writes
its own internal pane label into record.paneId, never the coordinator's
logical pane id, and comparing those marks every real pane unknown. Both
in-memory pane doubles were faking that field and are now honest about
it, which the real-process multipane e2e proves.
create() read the coordinator record tolerantly, so a structurally valid
but misbound record came back as null and was interpreted as absence: it
skipped the live-set check, started a derived pane and atomically
overwrote the file, leaving whatever live processes that record described
orphaned with nothing pointing at them. It now reads strictly, so only a
genuinely absent record may be created over.

The sharp edge is deliberate and recorded in decision 197: an
unbelievable coordinator record now blocks starting a terminal for that
task instead of being silently overwritten.
@h0x91b
h0x91b force-pushed the fix/dev3-pr-ai-review-launch branch from 5fe8810 to 721c76c Compare August 3, 2026 10:06
@h0x91b
h0x91b merged commit 3295991 into main Aug 3, 2026
15 checks passed
@h0x91b
h0x91b deleted the fix/dev3-pr-ai-review-launch branch August 3, 2026 10:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants