diff --git a/assets/agents/coder/README.md b/assets/agents/coder/README.md
index a855876..8016993 100644
--- a/assets/agents/coder/README.md
+++ b/assets/agents/coder/README.md
@@ -10,22 +10,30 @@ implement-fix loop enforced as graph edges rather than prose.
## Workflow
-```
-analyze_request (llm + output_schema) plan + complexity extraction
- ↓
-route_complexity (script) opt-out approval gate (complexity ≥ 7)
- ↓
-gate_approval (approval, optional)
- ↓
-implement (llm + fs tools) actual file edits
- ↓
-verify_build (script)
- ↓
-verify_tests (script)
- ↓
-fix_loop_gate (script) back-edge to implement (bounded)
- ↓
-end_success / end_rejected / end_failure
+```mermaid
+flowchart TD
+ resolve_paths{"resolve_paths
script"} --> analyze_request
+ analyze_request["analyze_request
llm + output_schema"] --> route_complexity
+ route_complexity{"route_complexity
script"}
+ route_complexity -->|"complexity ≥ 7"| gate_approval
+ route_complexity -->|else| implement
+ gate_approval{{"gate_approval
approval"}}
+ gate_approval -->|yes| implement
+ gate_approval -->|no| end_rejected
+ implement["implement
llm + fs tools"] --> verify_build
+ verify_build{"verify_build
script"}
+ verify_build -->|pass| verify_tests
+ verify_build -->|fail| fix_loop_gate
+ verify_tests{"verify_tests
script"}
+ verify_tests -->|pass| end_success
+ verify_tests -->|fail| fix_loop_gate
+ fix_loop_gate{"fix_loop_gate
script"}
+ fix_loop_gate -->|"budget left"| implement
+ fix_loop_gate -->|"budget spent"| end_failure
+
+ end_success(["end_success
CODER_COMPLETE"])
+ end_rejected(["end_rejected
CODER_REJECTED"])
+ end_failure(["end_failure
CODER_FAILED"])
```
End nodes emit one of three sentinel outcomes for the caller:
diff --git a/assets/agents/deep-research/README.md b/assets/agents/deep-research/README.md
index f15c970..ea5f2ab 100644
--- a/assets/agents/deep-research/README.md
+++ b/assets/agents/deep-research/README.md
@@ -22,28 +22,43 @@ agent, this is the file to read alongside the
## Workflow
-17 nodes. `->` is the static route; a script node can also route
-dynamically via `_next`. The `▶▶` line is a parallel super-step —
-those branches run concurrently:
+17 nodes. Solid arrows are static `next` / `routes` edges declared in
+`graph.yaml`; script nodes can also route dynamically via `_next` (shown as
+labeled branches out of the diamond). Dotted arrows show `map` fan-out — the
+`research_each_question` node spawns one `research_one_question` branch per
+sub-question and joins them before continuing.
-```
-parse_request (script) -> bootstrap_research (or -> ask_topic if no topic)
-ask_topic (input) -> bootstrap_research
-bootstrap_research (script) -> [plan, knowledge_lookup] ▶▶ parallel
-plan (llm + output_schema) -> research_each_question
-knowledge_lookup (rag) -> research_each_question
-research_each_question (map) -> combine_findings (spawns one branch per question)
- └─ research_one_question (llm) (atomic; runs N×, joins at map)
-combine_findings (script) -> vet_sources
-vet_sources (llm + custom tool) -> critique
-critique (llm) -> reflexion_gate
-reflexion_gate (script) -> synthesize (or -> research_each_question: reflexion loop)
-synthesize (agent: report-writer) -> verify_sources
-verify_sources (script) -> approve
-approve (approval) -> end_accepted ("accept")
- -> end_rejected ("reject")
- -> incorporate_feedback (any free-form answer)
-incorporate_feedback (script) -> research_each_question (the human-feedback loop)
+```mermaid
+flowchart TD
+ parse_request{"parse_request
script"}
+ parse_request -->|"topic given"| bootstrap_research
+ parse_request -->|"no topic"| ask_topic
+ ask_topic[/"ask_topic
input"/] --> bootstrap_research
+ bootstrap_research{"bootstrap_research
script"}
+ bootstrap_research --> plan
+ bootstrap_research --> knowledge_lookup
+ plan["plan
llm + output_schema"] --> research_each_question
+ knowledge_lookup[("knowledge_lookup
rag")] --> research_each_question
+ research_each_question[\research_each_question
map/]
+ research_each_question -. "spawns × N" .-> research_one_question["research_one_question
llm + web tools"]
+ research_each_question --> combine_findings
+ combine_findings{"combine_findings
script"} --> vet_sources
+ vet_sources["vet_sources
llm + classify_source"] --> critique
+ critique["critique
llm"] --> reflexion_gate
+ reflexion_gate{"reflexion_gate
script"}
+ reflexion_gate -->|"PASS"| synthesize
+ reflexion_gate -->|"REVISE (budget left)"| research_each_question
+ reflexion_gate -->|"REVISE (budget spent)"| synthesize
+ synthesize[["synthesize
agent → report-writer"]] --> verify_sources
+ verify_sources{"verify_sources
script"} --> approve
+ approve{{"approve
approval"}}
+ approve -->|"accept"| end_accepted
+ approve -->|"reject"| end_rejected
+ approve -->|"other (free-form feedback)"| incorporate_feedback
+ incorporate_feedback{"incorporate_feedback
script"} --> research_each_question
+
+ end_accepted(["end_accepted
report"])
+ end_rejected(["end_rejected"])
```
### Node-type breakdown
diff --git a/assets/agents/librarian/README.md b/assets/agents/librarian/README.md
index cb7597b..068a898 100644
--- a/assets/agents/librarian/README.md
+++ b/assets/agents/librarian/README.md
@@ -10,13 +10,25 @@ library, API, or framework is involved.
## Workflow
+```mermaid
+flowchart TD
+ triage["triage
llm"] --> search
+ triage --> search_oss
+ search["search
llm + ddg-search MCP"] --> synthesize
+ search_oss["search_oss
llm + personal-github MCP"] --> synthesize
+ synthesize["synthesize
llm + fetch_url_via_curl"] --> final_format
+ final_format{"final_format
script"} --> end_success
+
+ end_success(["end_success
LIBRARIAN_COMPLETE"])
+ end_failure(["end_failure
LIBRARIAN_FAILED"])
```
-search (llm + ddg-search) identify 3-5 authoritative sources
- ↓
-synthesize (llm + fetch_url_via_curl) fetch, extract, cite, synthesize
- ↓
-end_success / end_failure LIBRARIAN_COMPLETE / LIBRARIAN_FAILED
-```
+
+`triage` parses the prompt into language / doc-domain / query hints, then fans
+out to `search` (authoritative docs via `ddg-search`) and `search_oss`
+(production OSS examples via the `personal-github` MCP) in parallel. Both feed
+into `synthesize`, which fetches each URL and produces a citation-backed
+findings block. `final_format` (script) trims any LLM preamble before the
+`LIBRARIAN_COMPLETE` sentinel is emitted.
Iteration 1 (this) is the happy-path MVP: single search pass, single synthesis
pass, no quality-check loop. Future iterations may add:
diff --git a/assets/agents/step-runner/README.md b/assets/agents/step-runner/README.md
index 81ae5e2..7514368 100644
--- a/assets/agents/step-runner/README.md
+++ b/assets/agents/step-runner/README.md
@@ -18,32 +18,61 @@ plans/
## Workflow
-```
-resolve_step (script) locate plan + previous handoff, check depends_on,
- ↓ mark plan in-progress [→ gate_blocked if deps unsatisfied]
-orient (llm, read-only) merge handoff directives + staleness-check the plan
- ↓
-route_staleness (script) major deviation → gate_deviation (approval)
- ↓
-implement (agent → coder) coder runs its own build/test/self-review fix-loop
- ↓
-route_coder_result (script) COMPLETE → verify | REJECTED / FAILED → end
- ↓
-verify_format_lint (script) format BEFORE evidence, then lint
-verify_build (script) step-level build/typecheck
-verify_tests (script) FULL test suite
- ↓ [failures → fix_loop_gate, back-edge to implement]
-edge_case_sweep (llm) missed edge cases; annotate downstream plans
- ↓ (Edge cases sections ONLY - scope changes become proposals)
-route_sweep (script) 5+ files or architectural boundary → independent_review
-independent_review (agent) code-reviewer; 🔴 findings loop back to implement (bounded)
- ↓
-write_handoff (llm) evidence-backed handoff per handoff-protocol + NOTES.md
-check_handoff (script) deterministic schema gate; marks plan status complete
- ↓
-gate_user_review (approval) HARD STOP - approve, or send revision comments
- ↓ (revisions loop through implement → verify → handoff again)
-end_success / end_blocked / end_rejected / end_failure
+```mermaid
+flowchart TD
+ resolve_step{"resolve_step
script"}
+ resolve_step -->|"deps satisfied"| orient
+ resolve_step -->|"deps unsatisfied"| gate_blocked
+ gate_blocked{{"gate_blocked
approval"}}
+ gate_blocked -->|"yes"| orient
+ gate_blocked -->|"no"| end_blocked
+ orient["orient
llm, read-only"] --> route_staleness
+ route_staleness{"route_staleness
script"}
+ route_staleness -->|"major deviation"| gate_deviation
+ route_staleness -->|"else"| implement
+ gate_deviation{{"gate_deviation
approval"}}
+ gate_deviation -->|"proceed"| implement
+ gate_deviation -->|"abort"| end_rejected
+ gate_deviation -->|"other (user guidance)"| implement
+ implement[["implement
agent → coder"]] --> route_coder_result
+ route_coder_result{"route_coder_result
script"}
+ route_coder_result -->|"CODER_COMPLETE"| verify_format_lint
+ route_coder_result -->|"REJECTED / FAILED"| end_failure
+ verify_format_lint{"verify_format_lint
script"}
+ verify_format_lint -->|"pass"| verify_build
+ verify_format_lint -->|"fail"| fix_loop_gate
+ verify_build{"verify_build
script"}
+ verify_build -->|"pass"| verify_tests
+ verify_build -->|"fail"| fix_loop_gate
+ verify_tests{"verify_tests
script"}
+ verify_tests -->|"pass"| edge_case_sweep
+ verify_tests -->|"fail"| fix_loop_gate
+ fix_loop_gate{"fix_loop_gate
script"}
+ fix_loop_gate -->|"budget left"| implement
+ fix_loop_gate -->|"budget spent"| end_failure
+ edge_case_sweep["edge_case_sweep
llm"] --> route_sweep
+ route_sweep{"route_sweep
script"}
+ route_sweep -->|"5+ files or boundary"| independent_review
+ route_sweep -->|"else"| write_handoff
+ independent_review[["independent_review
agent → code-reviewer"]] --> route_review
+ route_review{"route_review
script"}
+ route_review -->|"🔴 critical findings"| implement
+ route_review -->|"else"| write_handoff
+ write_handoff["write_handoff
llm"] --> check_handoff
+ check_handoff{"check_handoff
script"}
+ check_handoff -->|"schema valid"| gate_user_review
+ check_handoff -->|"one retry"| write_handoff
+ gate_user_review{{"gate_user_review
approval"}}
+ gate_user_review -->|"approve"| end_success
+ gate_user_review -->|"revise"| get_revision
+ gate_user_review -->|"other (comments)"| revise_from_choice
+ get_revision[/"get_revision
input"/] --> implement
+ revise_from_choice{"revise_from_choice
script"} --> implement
+
+ end_success(["end_success
STEP_COMPLETE"])
+ end_blocked(["end_blocked
STEP_BLOCKED"])
+ end_rejected(["end_rejected
STEP_REJECTED"])
+ end_failure(["end_failure
STEP_FAILED"])
```
End nodes emit sentinel outcomes for the caller: