Repository navigation
Explain why no features can start instead of waiting silently (#27) - #255
zwanski-start wants to merge 1 commit into
Conversation
When no feature is ready and no agent is running, the orchestrator used to print a vague 'may be blocked by dependencies' line every 10s forever. It now diagnoses the root cause (circular dependencies, dependencies on nonexistent features, features that exhausted their retries, features waiting for human input) and prints an actionable explanation once, repeating it only when it changes. Also fixes _detect_cycles reporting features that merely depend on a cycle as part of it, and logs resume failures instead of discarding them. Closes AutoForgeAI#27 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🔍 QA report: ✅ PassedTester: Dennis (cubefarm agent, in a fresh session) · Round: 1 · Author: Barbara The PR fixes #27: when no feature can start and nothing is running, the orchestrator now prints one explanation (cycles, dependencies on features that don't exist, features that failed 3 times, features waiting for input, and what depends on them) and prints it again only when the explanation changes. I checked this end to end by clicking Start Agent in the UI on a stalled project, and in a real orchestrator loop where a change to the database mid-run updated the message. The cycle-detection fix is real: master reported a bogus second cycle for a feature that only depends on a cycle. Lint, build and the targeted tests pass; the mypy and pytest failures are also on master.
🧪 Commands run
No browser screenshots were taken in this round. Posted by cubefarm · merges automatically once GitHub's checks pass |
🔍 QA report: ✅ PassedTester: Dennis (cubefarm agent, in a fresh session) · Round: 1 · Author: Barbara The PR fixes #27: when no feature is ready and no agent is running, the orchestrator now prints why (circular dependencies, dependencies on features that don't exist, features that ran out of retries, features waiting for human input, and the features waiting on those), once per change instead of every 10s, and picks up fixes without a restart. I checked this end to end with a real features.db and the real run_loop, with agent spawning stubbed out. All Python tests, ruff and security tests pass, and mypy reports no new errors. One small note: the _detect_cycles fix removes the bogus cycle, but when two cycles share a feature only the first is reported now (the second shows up once the first is broken). That doesn't block the PR.
🧪 Commands run
No browser screenshots were taken in this round. Posted by cubefarm · merges automatically once GitHub's checks pass |
) Adaptations: combined with AutoForgeAI#296's stall states, the report is printed for 'blocked' and 'human_input' stalls before the orchestrator stops (blocked) or waits (human input), replacing AutoForgeAI#296's one-line notices. Ported AutoForgeAI#255's 2-line rec_stack/path reset in _detect_cycles, which reported features that merely depend on a cycle as cyclic; new regression test. New test for the report's content and de-duplication. Integrates AutoForgeAI#306 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AeH26pcsqoxPb3CDs8g1VN
Closes #27
Problem
In the issue, 51 features stayed in Pending for hours with the agent "running", and nothing explained why. When no feature is ready and no coding agent is running, the orchestrator printed
No ready features available. All remaining features may be blocked by dependencies.every ~10s and waited forever. Several states cause this, and none of them could be told apart from the log:MAX_FEATURE_RETRIEStimes: its dependents stay pending, soget_all_complete()never returns true(Usage/rate limits, the other cause suggested in the issue comments, are already handled separately in
rate_limit_utils.py/ #19.)Changes
api/dependency_resolver.py: newdiagnose_stalled_features()sorts the non-passing features by root cause (cycles among non-passing features, missing deps, failed, needs-human-input) and records what each feature is still waiting on.parallel_orchestrator.py: in the stall branch, the orchestrator prints an actionable explanation throughformat_stall_diagnosis(), for example:orchestrator_debug.log.start_feature(resume=True)) are now printed instead of being dropped silently._detect_cycles: after it found a cycle, its DFS stack wasn't reset, so a feature that only depends on a cycle was reported as part of a second, bogus cycle.Assumptions
Verification
test_diagnose_stalled_featuresandtest_diagnose_stalled_features_ignores_passing_cycles.python test_dependency_resolver.py: 14/14 pass.pytest test_dependency_resolver.py test_rate_limit_utils.py test_client.py: 57 passed.python test_security.py: all pass.ruff check .is clean.mypy .reports no errors in the changed files (the remaining errors were already there).format_stall_diagnosisby hand on the sample graph above.🤖 Generated with Claude Code