System Information
ralph-tui: 0.12.0
runtime: bun 1.3.14
os: win32 10.0.26200 (x64)
agent: opencode v1.17.15
tracker: beads
global-config: yes
project-config: no
templates: beads-bv.hbs, beads-rust-bv.hbs, beads-rust.hbs, beads.hbs, default.hbs, jira.hbs, json.hbs
bundled-skills: 4
skills-installed: claude:0, opencode:0, droid:0, gemini:0, codex:0, kiro:0, cursor:0, github-copilot:0, kimi:0, pi:0
Steps to reproduce
- In beads, create an epic with tasks that are strictly ordered — each task blocked by the previous one (
bd dep add <task> --blocked-by <prev>), so only one task is ever "ready".
- Run headless, scoped to the epic:
ralph-tui run --epic <epic> --headless --iterations 50 --serial --agent opencode
- Ralph claims the first task (sets it
in_progress) and runs iteration 1. The agent does NOT close the task that iteration (any reason — needs another turn, is interrupted, etc.).
- Ralph re-queries for the next task and immediately stops with
Reason: no_tasks, even though the iteration budget is untouched (stopped at iteration 1 of 50).
Expected: Ralph resumes the in_progress task on the next iteration. The engine even asks for it — getNextAvailableTask() calls getNextTask({ status: ['open', 'in_progress'], … }).
Actual: the task is stranded in_progress. Because bd ready excludes in_progress (and its blocked dependents), the run stops no_tasks and the whole epic stalls until a human manually resets the status (bd update <task> --status open). This isn't specific to strict ordering — any task not closed in a single iteration becomes unresumable; strict blocking just turns it into a full-epic stall instead of a skipped task.
Root cause (source @ commit 8191b80):
src/engine/index.ts → getNextAvailableTask() passes status: ['open', 'in_progress'].
src/plugins/trackers/builtin/beads/index.ts → getNextTask() builds bd ready --json --limit 10 [--parent …] and IGNORES filter.status. bd ready is defined to exclude in_progress/blocked/deferred, so an in_progress task is never returned.
Relevant logs / terminal output
[session] Session <session-id> created. Agent: opencode, Tracker: beads
[engine] Ralph started. Total tasks: 5
[progress] Iteration 1/50: Working on proj-1.1 - <task 1 title>
[progress] Iteration 1 finished. Task proj-1.1: in progress. Duration: 49s
[engine] Ralph stopped. Reason: no_tasks. Iterations: 1, Tasks completed: 0
Configuration (if relevant)
agent = "opencode"
tracker = "beads"
configVersion = "2.1"
maxIterations = 50
autoCommit = true
[agentOptions]
provider = "<provider>"
model = "<model>"
variant = "<variant>"
Additional context
State of the epic right after the claim — the work exists and is loadable, but bd ready (what getNextTask calls) returns nothing:
bd ready --parent proj-1 --json:
bd list --parent proj-1 --json (trimmed):
[
{ "id": "proj-1.1", "title": "Task 1", "status": "in_progress", "parent": "proj-1" },
{ "id": "proj-1.2", "title": "Task 2", "status": "open", "parent": "proj-1",
"dependencies": [ { "depends_on_id": "proj-1.1", "type": "blocks" } ] },
{ "id": "proj-1.3", "title": "Task 3", "status": "open", "parent": "proj-1",
"dependencies": [ { "depends_on_id": "proj-1.2", "type": "blocks" } ] },
{ "id": "proj-1.4", "title": "Task 4", "status": "open", "parent": "proj-1",
"dependencies": [ { "depends_on_id": "proj-1.3", "type": "blocks" } ] },
{ "id": "proj-1.5", "title": "Task 5", "status": "open", "parent": "proj-1",
"dependencies": [ { "depends_on_id": "proj-1.4", "type": "blocks" } ] }
]
So: proj-1.1 is in_progress (excluded by bd ready), and .2–.5 are blocked by it → bd ready is empty → no_tasks. bd list still shows all of it.
Suggested fix: in the beads adapter's getNextTask, honor the engine's filter.status. When it includes in_progress, surface the claimed task too — e.g. union bd ready with bd list --status in_progress [--parent …] (preferring an in_progress task so the engine resumes it, which matches the engine's existing "prefer in_progress" logic). Manual workaround today: bd update <task> --status open to un-strand it.
System Information
Steps to reproduce
bd dep add <task> --blocked-by <prev>), so only one task is ever "ready".ralph-tui run --epic <epic> --headless --iterations 50 --serial --agent opencodein_progress) and runs iteration 1. The agent does NOT close the task that iteration (any reason — needs another turn, is interrupted, etc.).Reason: no_tasks, even though the iteration budget is untouched (stopped at iteration 1 of 50).Expected: Ralph resumes the
in_progresstask on the next iteration. The engine even asks for it —getNextAvailableTask()callsgetNextTask({ status: ['open', 'in_progress'], … }).Actual: the task is stranded
in_progress. Becausebd readyexcludesin_progress(and its blocked dependents), the run stopsno_tasksand the whole epic stalls until a human manually resets the status (bd update <task> --status open). This isn't specific to strict ordering — any task not closed in a single iteration becomes unresumable; strict blocking just turns it into a full-epic stall instead of a skipped task.Root cause (source @ commit 8191b80):
src/engine/index.ts→getNextAvailableTask()passesstatus: ['open', 'in_progress'].src/plugins/trackers/builtin/beads/index.ts→getNextTask()buildsbd ready --json --limit 10 [--parent …]and IGNORESfilter.status.bd readyis defined to excludein_progress/blocked/deferred, so an in_progress task is never returned.Relevant logs / terminal output
Configuration (if relevant)
Additional context
State of the epic right after the claim — the work exists and is loadable, but
bd ready(whatgetNextTaskcalls) returns nothing:bd ready --parent proj-1 --json:bd list --parent proj-1 --json(trimmed):[ { "id": "proj-1.1", "title": "Task 1", "status": "in_progress", "parent": "proj-1" }, { "id": "proj-1.2", "title": "Task 2", "status": "open", "parent": "proj-1", "dependencies": [ { "depends_on_id": "proj-1.1", "type": "blocks" } ] }, { "id": "proj-1.3", "title": "Task 3", "status": "open", "parent": "proj-1", "dependencies": [ { "depends_on_id": "proj-1.2", "type": "blocks" } ] }, { "id": "proj-1.4", "title": "Task 4", "status": "open", "parent": "proj-1", "dependencies": [ { "depends_on_id": "proj-1.3", "type": "blocks" } ] }, { "id": "proj-1.5", "title": "Task 5", "status": "open", "parent": "proj-1", "dependencies": [ { "depends_on_id": "proj-1.4", "type": "blocks" } ] } ]So:
proj-1.1isin_progress(excluded bybd ready), and.2–.5are blocked by it →bd readyis empty →no_tasks.bd liststill shows all of it.Suggested fix: in the beads adapter's
getNextTask, honor the engine'sfilter.status. When it includesin_progress, surface the claimed task too — e.g. unionbd readywithbd list --status in_progress [--parent …](preferring anin_progresstask so the engine resumes it, which matches the engine's existing "prefer in_progress" logic). Manual workaround today:bd update <task> --status opento un-strand it.