core / project_advancer.py
Single autoadvance tick for long-running projects. Classifies the next task, runs one constrained step, and bookkeeps budget / runtime / contradictions.
API
| Function | Purpose |
|---|---|
classify_task(description) -> "needs_user" | "coding" | "research" | Keyword-driven classifier (line 85). |
async advance_once(context, project_id, tool_runner, llm_classifier) -> AdvanceResult | One full advancement tick — returns the result of running one task (line 126). |
project_dream_pass(store, llm_summarize) | Consolidate accumulated project events into a daily digest (line 314). |
Classification keywords
- needs_user:
decide · approve · sign off · delete production. - coding:
implement · build · fix · debug · deploy. - research (default):
research · investigate · compare · analyze.
Tick flow
- Load project plan; find next READY/PENDING leaf.
- Classify task type.
- Mark IN_PROGRESS.
- If
needs_user: flip to NEEDS_USER, log event, return. - Pick tool: coding →
execute, research →web_search. - Run tool through the injected runner.
- Store result as a project artifact.
- Check human-gate postconditions (project_safety) → flip to NEEDS_USER if any fire.
- Detect contradictions with DONE siblings.
- Mark DONE; increment
steps_used; record runtime + tool_calls.
Budget enforcement
_get_budget() reads steps_cap / steps_used from project metadata; _increment_budget() bumps after each tick. Checked via check_budget() across steps, runtime_seconds, and tool_calls.
AdvanceResult
AdvanceResult(ok: bool, task_id: str, classification: str, summary: str, artifact_id: Optional[str])
Async; tool_runner and llm_classifier are optional callbacks so the advancer can be tested without a real agent.