Failure scenario
Create a plan step whose tool awaits forever or sleeps for 60 seconds, with timeout: 1.
StepExecutor awaits the tool without any deadline. It compares elapsed time only after the tool returns. A hung tool therefore hangs the entire plan forever, and a 60-second tool performs all of its work before the planner finally labels it a one-second timeout. Because the planner waits for each ready batch with asyncio.gather, one such step also prevents completion/reporting of every sibling in that batch.
Sites
src/odin/executor.py:38-45 awaits the tool with no asyncio.timeout()/wait_for() enforcement and checks elapsed time only afterward.
src/odin/planner.py:118-121 waits for the entire concurrent batch, so a non-returning timed step stalls plan progress.
Expected result
Apply the configured deadline around each attempt, cancel and cleanly settle timed-out work, return StepStatus.TIMEOUT at the deadline, and define whether timeout attempts are retryable without letting an abandoned attempt continue mutating state.
Failure scenario
Create a plan step whose tool awaits forever or sleeps for 60 seconds, with
timeout: 1.StepExecutorawaits the tool without any deadline. It compares elapsed time only after the tool returns. A hung tool therefore hangs the entire plan forever, and a 60-second tool performs all of its work before the planner finally labels it a one-second timeout. Because the planner waits for each ready batch withasyncio.gather, one such step also prevents completion/reporting of every sibling in that batch.Sites
src/odin/executor.py:38-45awaits the tool with noasyncio.timeout()/wait_for()enforcement and checks elapsed time only afterward.src/odin/planner.py:118-121waits for the entire concurrent batch, so a non-returning timed step stalls plan progress.Expected result
Apply the configured deadline around each attempt, cancel and cleanly settle timed-out work, return
StepStatus.TIMEOUTat the deadline, and define whether timeout attempts are retryable without letting an abandoned attempt continue mutating state.