mirror of
https://github.com/stablyai/orca.git
synced 2026-10-29 16:17:51 +00:00
fix(agent-status): let a stop's own inventory veto removal-driven done
Review finding round 5: after a restart the listener can miss a child's start; another child's stop still lists it running in background_tasks. A running non-teammate task or live shell/cron now vetoes the no-lead removal->done into working. Veto only — folding the inventory at stop time would reap a just-parked teammate row before its TeammateIdle confirmation arrives.
This commit is contained in:
@@ -3177,6 +3177,40 @@ describe('shared agent-hook-listener', () => {
|
||||
expect(duplicatePark).toBeNull()
|
||||
})
|
||||
|
||||
it('keeps working when a no-lead stop carries an inventory with another live child', () => {
|
||||
// Why: after a restart the listener can miss a2's start; a1's stop still
|
||||
// lists a2 running in background_tasks — the removal must not retire it.
|
||||
claudeEvent({
|
||||
hook_event_name: 'SubagentStart',
|
||||
agent_id: 'a1',
|
||||
agent_type: 'general-purpose'
|
||||
})
|
||||
const stopped = claudeEvent({
|
||||
hook_event_name: 'SubagentStop',
|
||||
agent_id: 'a1',
|
||||
background_tasks: [
|
||||
{ id: 'a2', type: 'subagent', status: 'running', agent_type: 'general-purpose' }
|
||||
]
|
||||
})
|
||||
// Why: veto only — a2's row materializes from its own events or the next
|
||||
// lead Stop's fold; the stop must merely not retire the pane.
|
||||
expect(stopped?.payload.state).toBe('working')
|
||||
})
|
||||
|
||||
it('keeps working when a no-lead drain leaves a live shell in the inventory', () => {
|
||||
claudeEvent({
|
||||
hook_event_name: 'SubagentStart',
|
||||
agent_id: 'a1',
|
||||
agent_type: 'general-purpose'
|
||||
})
|
||||
const stopped = claudeEvent({
|
||||
hook_event_name: 'SubagentStop',
|
||||
agent_id: 'a1',
|
||||
background_tasks: [{ id: 's1', type: 'shell', status: 'running' }]
|
||||
})
|
||||
expect(stopped?.payload.state).toBe('working')
|
||||
})
|
||||
|
||||
it('never claims done from a no-lead TeammateIdle park', () => {
|
||||
claudeEvent({
|
||||
hook_event_name: 'SubagentStart',
|
||||
|
||||
@@ -2594,8 +2594,16 @@ function buildClaudeChildDrivenStatusPayload(
|
||||
})
|
||||
}
|
||||
if (evidence.removedRow) {
|
||||
// Why: the stop's own inventory can list work this listener never saw start (post-restart);
|
||||
// a running non-teammate task or live shell/cron vetoes done. Teammate-typed entries prove
|
||||
// nothing ("running" even while idle), and full folding here would reap a just-parked
|
||||
// teammate row before its TeammateIdle confirmation arrives — veto only, no reconcile.
|
||||
const inventory = readClaudeBackgroundAgentTasks(hookPayload)
|
||||
const inventoryShowsLiveWork =
|
||||
inventory.tasks.some((task) => task.running && !task.teammate) ||
|
||||
hasActiveClaudeNonAgentBackgroundWork(hookPayload)
|
||||
return buildClaudeStatusPayload(state, eventName, '', paneKey, hookPayload, {
|
||||
stateName: 'done',
|
||||
stateName: inventoryShowsLiveWork ? 'working' : 'done',
|
||||
updateToolSnapshot: false
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user