fix: orphan reconciliation never killed a still-alive subprocess, letting two agents race the same worktree - #582
Conversation
…ting two agents race the same worktree A daemon restart doesn't kill an already-spawned agent subprocess tree — it's deliberately placed in its own process group (cmd.process_group(0), needed so kill_tree's targeted kill works during normal timeouts), so it survives as a genuine orphan invisible to the new daemon. reconcile_orphaned_running only updated the DB row and released the claim, then immediately restored ready-for-work — letting a fresh dispatch race the still-running orphan into editing the same files concurrently. Hit in production 2026-08-21 (item #164): a claude-code and an opencode process both ended up bound to the same worktree, corrupting it. Kill anything still touching the item's worktree (pgrep -f against the worktree path, robust to any process-tree shape) before releasing the claim or relabeling ready-for-work. Agentflare-Agent: claude-code Agentflare-Branch: docs/opencode-model-mapping-fallback
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 36 minutes Limit details: You’ve used the included review currently available. Your 61 included PR review attempts over the past 7 days set your current allowance at 1 review per hour. Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?Wait for the limit to reset, then comment An organization admin can change what happens after included review limits in Billing. How do review limits work?CodeRabbit enforces per-developer PR review limits within each organization. For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
Comment |
…had no pgrep) The original fix used pgrep -f directly, which doesn't exist on Windows (caught by CI: build (windows-latest) failed). Split into #[cfg(unix)] (pgrep, unchanged) and #[cfg(windows)] (Get-CimInstance Win32_Process CommandLine match via PowerShell) implementations. Gated the new test #[cfg(unix)] since its yes-based orphan simulation isn't portable. Trimmed comments to stay under the LOC gate. Agentflare-Agent: claude-code Agentflare-Branch: fix/orphan-reconcile-kill-live-process
Summary
Opened by claude for item #172 via agentflare.
A daemon restart doesn't kill an already-spawned agent subprocess tree — it's deliberately placed in its own process group (
cmd.process_group(0)inagent_launch::run_captured, needed sokill_tree's targeted kill works during normal timeouts), so it survives as a genuine orphan invisible to the new daemon.reconcile_orphaned_runningonly updated the DB row and released the claim, then immediately restoredready-for-work— letting a fresh dispatch race the still-running orphan into editing the same files concurrently.Hit in production 2026-08-21 (item #164): a
claude-codeprocess and anopencodeprocess both ended up bound to the same worktree simultaneously, corrupting it.src/dashboard/orphan_reconcile.rsnow kills anything still touching the item's worktree (pgrep -fagainst the worktree path, robust to any process-tree shape) before releasing the claim or relabelingready-for-work.Test plan
reconcile_orphaned_jobsactually terminates itorphan_reconciletests still passcargo check --workspacecleancargo fmtapplied