Fix Multi-Agent Run Hanging and Finalization Issues · Entire
This is stuck for way too long
There's just no indicator what the final agent is still doing. Also, Status says "done" but footer says 3 succeeded and 1 failed?
AGENT STATUS DURATION TOKENS PREVIEW
- claude-code:opus ✓ done 3m32s 1196.8k I have enough to finalize. The code is well-structured and well-tested; cross-f…
- claude-code:sonnet ✓ done 5m29s 650.3k/… Now I have everything I need. Let me write the final review.
- codex ✓ done 4m22s 1496.4k request changes - review gates can pass without enforcing configured signals, a…
- codex:gpt-5-4-mini ✓ done 16m43s 3612.0k request changes, because the new reviews gate has two fail-open paths that can …
4 agent(s) done — 3 succeeded, 1 failed, 0 cancelled
Finalizing output...
Root cause — found and reproduced
It's not a deadlock; it's a super-linear blowup in glamour markdown rendering during the post-run finalize phase.
Finalization process:
TUISink.RunFinished→ sets finished, footer shows "Finalizing output..."DumpSink.RunFinished→ renders EACH agent's narrative through glamourSynthesisSink.RunFinished→ "Final judge is consolidating..." (never reached)tuiPostRunCompleteSink→ quits the TUI (never reached)
Rendering latency:
| input | render time |
|---|---|
| 500 KB | 1.1 s |
| 2 MB | 6 s |
| 4 MB | 49 s |
| 8 MB | 4m30s |
| 16 MB | didn't finish (>5 min) |
Investigation Summary:
- The finalize sink chain for a TTY multi-agent run caused delays in the rendering of multi-MB narratives, leading to hanging.
- When an agent has a large output, the rendering delays are exacerbated.
Fixes Implemented:
- Added a rendering cap at 256 KB — rendering larger inputs returns raw markdown instead of processing it.
- Added a live spinner and elapsed timer to the UI during the finalization process to make it clear that finalization is ongoing.
The bug
When a review run finishes, the CLI prints each agent's output as nicely formatted markdown via a library called glamour. That formatting step is really slow on large inputs.
The solution
- Cap the formatting size: If the text is bigger than 256 KB, skip the fancy formatting and just print it plain.
- Make the wait visible: The footer shows a spinning indicator and a climbing timer during the finalization.
Findings Persistence Fix
When a review run is cancelled during synthesis, findings were lost because the context was reused. To fix this:
- A detached context is used for persisting findings after a cancellation to ensure they are saved regardless of user cancellation during finalization.
Test Implemented
Added tests to ensure that findings persist despite being previously cancelled.
Process Group Kill on Cancel
Fixed cancellation to properly kill all processes spawned by agents to prevent the hanging issue when terminating the run. Now the system can cleanly cancel all related processes.
Overall Branch Summary
- Finalizing hang addressed with plain-text dumps and render cap.
- Findings persistence on cancel implemented.
- Comment verbosity cleaned up across all changes.
- Process-group kill feature added to ensure smooth cancellations.