AutoProjectClaw is a 6-stage pipeline (Stage 0-5) that transforms a vague research direction into an evidence-backed grant proposal topic.
cli.py ──→ config.py ──→ pipeline/runner.py ──→ pipeline/stages.py
│ │
│ ├──→ stage_impls/_context_pack.py (Stage 0)
│ ├──→ stage_impls/_project_init.py (Stage 1)
│ ├──→ stage_impls/_aim_decompose.py (Stage 2)
│ ├──→ stage_impls/_multi_dim_search.py (Stage 3)
│ ├──→ stage_impls/_evidence_collect.py (Stage 4)
│ └──→ stage_impls/_candidate_evaluate.py (Stage 5)
│
├──→ llm/client.py (5 providers)
├──→ prompts.py (3-layer: defaults → YAML → runtime)
├──→ literature/search.py
│ ├── cache.py (SHA256, per-source TTL)
│ ├── circuit_breaker.py (CLOSED→OPEN→HALF_OPEN)
│ └── novelty.py (Jaccard + SequenceMatcher)
├──→ modules/
│ ├── avoidance_checker.py (5-dim overlap)
│ ├── grant_scorer.py (FINER + differentiation)
│ └── data_assessor.py (wording calibration)
├──→ quality.py (template detection)
├──→ reports.py (run scanning, weekly reports)
└──→ knowledge.py (markdown KB archival)
Each stage reads artifacts from the prior stage's output directory and writes to its own:
Config YAML → Stage 0 → Stage 1 → Stage 2 → Stage 3 → Stage 4 → Stage 5 (HITL gate)
│ │ │ │ │ │
└→ context_ └→ project_ └→ research_ └→ search_ └→ evidence_ └→ scoring_
pack.yaml framework aims.md plan.yaml cards.jsonl matrix.json
The runner (pipeline/runner.py) orchestrates this flow:
- Validates prior stage outputs via
StageContract - Dispatches to the correct
execute_*function - Verifies expected outputs after completion
- Writes
stage_health.json,decision.json,checkpoint.json,pipeline_summary.json
Each stage has a contract (pipeline/contracts.py) defining:
| Stage | Key Inputs | Key Outputs | LLM? | Gate? |
|---|---|---|---|---|
| 0 | Config YAML | context_pack.yaml, input_inventory.md |
No | No |
| 1 | Stage 0 outputs | project_framework.md, assumption_registry.yaml |
Yes | No |
| 2 | Stage 1 outputs | research_aims.md, aim_graph.json |
Yes | No |
| 3 | research_aims.md |
search_plan.yaml, queries.json |
Yes | No |
| 4 | search_plan.yaml |
evidence_cards.jsonl, quality_checked_evidence.jsonl |
Yes | No |
| 5 | Evidence + aims | scoring_matrix.json, final_recommendation.md, provenance_report.json |
Yes | Yes |
LLMClient protocol (llm/client.py) with 5 adapters:
| Adapter | Transport | Use case |
|---|---|---|
DryRunLLMClient |
None | Testing, no network |
CodexCLIClient |
subprocess → codex exec |
Local Codex CLI |
ClaudeCLIClient |
subprocess → claude --print |
Local Claude CLI |
OpenAIResponsesClient |
HTTP POST (stdlib urllib) |
OpenAI API |
AnthropicMessagesClient |
HTTP POST (stdlib urllib) |
Anthropic API |
All adapters use Python stdlib only — no external HTTP libraries.
Three-layer override (prompts.py):
- Python defaults — hardcoded in
prompts.py - YAML overrides —
prompts.project.yamlat project root - Runtime variables —
{variable}placeholders filled at call time
Each stage has system and user prompt templates.
Stage 5 is the only gate stage. It blocks at blocked_approval:
approve→ marks run asdone, generatesdeliverables/manifest.jsonreject→ marks asrejected, rolls back to Stage 3 by defaultresume→ continues from the saved checkpoint
Gate decisions are recorded in gate_decision.json.
6 academic API sources (literature/search.py):
- PubMed — biomedical/epidemiologic evidence
- OpenAlex — broad metadata and citation coverage
- Semantic Scholar — semantic expansion and citation graphs
- arXiv — methods, statistics, AI preprints
- bioRxiv/medRxiv — biology/medical preprints
Resilience features:
- Cache (
literature/cache.py): SHA256-keyed file cache with per-source TTL - Circuit Breaker (
literature/circuit_breaker.py): CLOSED→OPEN→HALF_OPEN with exponential backoff - Novelty (
literature/novelty.py): Blended similarity (70% Jaccard + 30% SequenceMatcher)
grant_scorer.py uses FINER + differentiation + grant story:
| Dimension | Weight |
|---|---|
| Feasible | 20% |
| Novel | 20% |
| Interesting | 15% |
| Relevant | 15% |
| Differentiation | 15% |
| Ethical | 10% |
| Grant Story | 5% |
avoidance_checker.py checks 5-dimension overlap with prior projects:
- Population, Outcome, Method, Data Path, Question
- Levels:
none/partial/full - Configurable red/yellow thresholds
reports.py provides:
scan_runs()— scans allpipeline_summary.jsonfiles underoutput_rootgenerate_weekly_report()— writes markdown report with summary stats, run details, failure reasons
Safe against malformed data via _safe_int(), _safe_float(), _md_cell() helpers.
runs/
reports/ # weekly reports (runs/reports/weekly_<date>.md)
<run_id>/
pipeline_summary.json # overall status
checkpoint.json # resume point
stage-00-context-pack/
context_pack.yaml
input_inventory.md
stage_health.json
decision.json
stage-01-project-init/
project_framework.md
...
stage-05-candidate-evaluate/
scoring_matrix.json
final_recommendation.md
provenance_report.json
gate_decision.json # after approve/reject
kb/ # markdown knowledge base