fabro/spec-dod-multimodel.dot
Bryan Helmkamp d3e396753c Remove stale review docs, add spec DoD pipeline definitions
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-23 09:47:50 -05:00

654 lines
27 KiB
Text

digraph SpecDoDMultiModel {
graph [
goal="Satisfy every Definition of Done checkbox across all three attractor-main specs (unified-llm-spec.md, coding-agent-loop-spec.md, attractor-spec.md). The implementation is in pure C11 under src/ and include/. Do NOT modify the spec files. Only modify implementation code. Uses multi-model consensus: Opus 4.6 and GPT-5.2 compete on audits and planning, GPT-5.2-codex and Opus 4.6 alternate on implementation.",
default_max_retry="3",
retry_target="triage_merge",
default_fidelity="full",
model_stylesheet="
* { llm_model: claude-opus-4-6; llm_provider: anthropic; }
.opus { llm_model: claude-opus-4-6; llm_provider: anthropic; reasoning_effort: high; }
.gpt { llm_model: gpt-5.2; llm_provider: openai; reasoning_effort: high; }
.codex { llm_model: gpt-5.2-codex; llm_provider: openai; reasoning_effort: high; }
.merge { llm_model: claude-opus-4-6; llm_provider: anthropic; reasoning_effort: high; }
"
]
start [shape=Mdiamond]
exit [shape=Msquare]
/*========================================================================
* PHASE 1 — Dual Independent Audits (interleaved, fidelity-isolated)
*
* Each spec is audited by both models before moving to the next spec.
* Audit nodes use fidelity="truncate" so they only see the graph goal
* and NOT each other's responses — prevents anchoring bias.
* Full responses are still stored as response.<node_id> for later use.
*======================================================================*/
/* ---- LLM spec: both models ---- */
audit_llm_opus [
label="Opus: Audit LLM DoD",
shape=box,
class="opus",
fidelity="truncate",
prompt="Read attractor-main/unified-llm-spec.md Section 8 (Definition of Done) in full. Then read every source file under src/llm/, src/util/, and include/llm/, include/util/.
For EACH checkbox in sections 8.1 through 8.10, evaluate whether the current C implementation satisfies it. Be strict — a checkbox is only checked if the feature is fully implemented and would work correctly at runtime.
Output a JSON object:
{
\"spec\": \"unified-llm\",
\"model\": \"opus\",
\"sections\": {
\"8.1\": { \"title\": \"Core Infrastructure\", \"items\": [ {\"text\": \"...\", \"pass\": true/false, \"reason\": \"...\"} ] },
...
},
\"total\": N,
\"passed\": M,
\"failed\": K,
\"failed_items\": [ {\"section\": \"8.2\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be thorough. Check every single checkbox."
]
audit_llm_gpt [
label="GPT-5.2: Audit LLM DoD",
shape=box,
class="gpt",
fidelity="truncate",
prompt="Read attractor-main/unified-llm-spec.md Section 8 (Definition of Done) in full. Then read every source file under src/llm/, src/util/, and include/llm/, include/util/.
For EACH checkbox in sections 8.1 through 8.10, evaluate whether the current C implementation satisfies it. Be strict — a checkbox is only checked if the feature is fully implemented and would work correctly at runtime.
Output a JSON object:
{
\"spec\": \"unified-llm\",
\"model\": \"gpt-5.2\",
\"sections\": {
\"8.1\": { \"title\": \"Core Infrastructure\", \"items\": [ {\"text\": \"...\", \"pass\": true/false, \"reason\": \"...\"} ] },
...
},
\"total\": N,
\"passed\": M,
\"failed\": K,
\"failed_items\": [ {\"section\": \"8.2\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be thorough. Check every single checkbox."
]
/* ---- Agent spec: both models ---- */
audit_agent_opus [
label="Opus: Audit Agent DoD",
shape=box,
class="opus",
fidelity="truncate",
prompt="Read attractor-main/coding-agent-loop-spec.md Section 9 (Definition of Done) in full. Then read every source file under src/agent/ and include/agent/.
For EACH checkbox in sections 9.1 through 9.13, evaluate whether the current C implementation satisfies it. Be strict.
Output a JSON object:
{
\"spec\": \"coding-agent-loop\",
\"model\": \"opus\",
\"sections\": { ... },
\"total\": N,
\"passed\": M,
\"failed\": K,
\"failed_items\": [ {\"section\": \"9.1\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be thorough. Check every single checkbox."
]
audit_agent_gpt [
label="GPT-5.2: Audit Agent DoD",
shape=box,
class="gpt",
fidelity="truncate",
prompt="Read attractor-main/coding-agent-loop-spec.md Section 9 (Definition of Done) in full. Then read every source file under src/agent/ and include/agent/.
For EACH checkbox in sections 9.1 through 9.13, evaluate whether the current C implementation satisfies it. Be strict.
Output a JSON object:
{
\"spec\": \"coding-agent-loop\",
\"model\": \"gpt-5.2\",
\"sections\": { ... },
\"total\": N,
\"passed\": M,
\"failed\": K,
\"failed_items\": [ {\"section\": \"9.1\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be thorough. Check every single checkbox."
]
/* ---- Attractor spec: both models ---- */
audit_attractor_opus [
label="Opus: Audit Attractor DoD",
shape=box,
class="opus",
fidelity="truncate",
prompt="Read attractor-main/attractor-spec.md Section 11 (Definition of Done) in full. Then read every source file under src/attractor/, src/main.c, and include/attractor/.
For EACH checkbox in sections 11.1 through 11.13, evaluate whether the current C implementation satisfies it. Be strict.
Output a JSON object:
{
\"spec\": \"attractor\",
\"model\": \"opus\",
\"sections\": { ... },
\"total\": N,
\"passed\": M,
\"failed\": K,
\"failed_items\": [ {\"section\": \"11.1\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be thorough. Check every single checkbox."
]
audit_attractor_gpt [
label="GPT-5.2: Audit Attractor DoD",
shape=box,
class="gpt",
fidelity="truncate",
prompt="Read attractor-main/attractor-spec.md Section 11 (Definition of Done) in full. Then read every source file under src/attractor/, src/main.c, and include/attractor/.
For EACH checkbox in sections 11.1 through 11.13, evaluate whether the current C implementation satisfies it. Be strict.
Output a JSON object:
{
\"spec\": \"attractor\",
\"model\": \"gpt-5.2\",
\"sections\": { ... },
\"total\": N,
\"passed\": M,
\"failed\": K,
\"failed_items\": [ {\"section\": \"11.1\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be thorough. Check every single checkbox."
]
/*========================================================================
* PHASE 2 — Cross-Critique (fidelity=full to see all response.* keys)
*
* Each model reviews the other's audit. Like megaplan's Compete phase:
* independent work first, then adversarial review.
*======================================================================*/
critique_by_gpt [
label="GPT-5.2: Critique Opus Audits",
shape=box,
class="gpt",
fidelity="full",
prompt="You have all six audit reports available in context. The full outputs are in these context keys:
OPUS AUDITS:
- response.audit_llm_opus — Opus's audit of unified-llm-spec.md Section 8
- response.audit_agent_opus — Opus's audit of coding-agent-loop-spec.md Section 9
- response.audit_attractor_opus — Opus's audit of attractor-spec.md Section 11
GPT AUDITS (your own):
- response.audit_llm_gpt — your audit of unified-llm-spec.md Section 8
- response.audit_agent_gpt — your audit of coding-agent-loop-spec.md Section 9
- response.audit_attractor_gpt — your audit of attractor-spec.md Section 11
Compare them item by item. For every DoD checkbox where the two models DISAGREE (one says pass, the other says fail), re-read the relevant spec section and source file to determine who is correct.
Also identify items that one model flagged but the other missed entirely.
Output a JSON object:
{
\"agreements\": { \"both_pass\": N, \"both_fail\": N },
\"disagreements\": [
{
\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\",
\"opus_says\": \"pass|fail\", \"gpt_says\": \"pass|fail\",
\"verdict\": \"pass|fail\",
\"reasoning\": \"...\"
}
],
\"missed_by_opus\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"reason\": \"...\"} ],
\"missed_by_gpt\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be rigorous. When in doubt, fail the checkbox — strictness prevents false confidence."
]
critique_by_opus [
label="Opus: Critique GPT-5.2 Audits",
shape=box,
class="opus",
fidelity="full",
prompt="You have all six audit reports available in context. The full outputs are in these context keys:
GPT AUDITS:
- response.audit_llm_gpt — GPT-5.2's audit of unified-llm-spec.md Section 8
- response.audit_agent_gpt — GPT-5.2's audit of coding-agent-loop-spec.md Section 9
- response.audit_attractor_gpt — GPT-5.2's audit of attractor-spec.md Section 11
OPUS AUDITS (your own):
- response.audit_llm_opus — your audit of unified-llm-spec.md Section 8
- response.audit_agent_opus — your audit of coding-agent-loop-spec.md Section 9
- response.audit_attractor_opus — your audit of attractor-spec.md Section 11
Compare them item by item. For every DoD checkbox where the two models DISAGREE (one says pass, the other says fail), re-read the relevant spec section and source file to determine who is correct.
Also identify items that one model flagged but the other missed entirely.
Output a JSON object:
{
\"agreements\": { \"both_pass\": N, \"both_fail\": N },
\"disagreements\": [
{
\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\",
\"opus_says\": \"pass|fail\", \"gpt_says\": \"pass|fail\",
\"verdict\": \"pass|fail\",
\"reasoning\": \"...\"
}
],
\"missed_by_opus\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"reason\": \"...\"} ],
\"missed_by_gpt\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"reason\": \"...\"} ]
}
Be rigorous. When in doubt, fail the checkbox — strictness prevents false confidence."
]
/*========================================================================
* PHASE 3 — Audit Consensus
*
* Merge all findings into a single agreed-upon truth.
* Like megaplan's Merge phase: best ideas from both, disagreements resolved.
*======================================================================*/
audit_consensus [
label="Merge: Audit Consensus",
shape=box,
class="merge",
fidelity="full",
prompt="You have all prior audit and critique outputs in context. The key inputs are:
SIX AUDIT REPORTS (context keys response.audit_llm_opus, response.audit_agent_opus, response.audit_attractor_opus, response.audit_llm_gpt, response.audit_agent_gpt, response.audit_attractor_gpt)
TWO CROSS-CRITIQUES (context keys response.critique_by_gpt, response.critique_by_opus)
Produce a single definitive audit result. Resolution rules:
1. If BOTH models agree a checkbox passes → pass
2. If BOTH models agree a checkbox fails → fail
3. If they DISAGREE, use the cross-critique verdicts. If the critiques also disagree, re-read the spec and code yourself and make the call. When in doubt, fail it.
4. Include any items that were missed by one model but caught by the other.
Output a JSON object:
{
\"spec_results\": {
\"unified-llm\": { \"total\": N, \"passed\": M, \"failed\": K, \"failed_items\": [...] },
\"coding-agent-loop\": { ... },
\"attractor\": { ... }
},
\"consensus_total\": N,
\"consensus_passed\": M,
\"consensus_failed\": K,
\"disagreements_resolved\": N,
\"all_failed_items\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"reason\": \"...\", \"agreed_by\": \"both|opus_only|gpt_only|resolved\"} ]
}"
]
/*========================================================================
* PHASE 4 — Dual Triage
*
* Both models independently prioritize the failures, then merge.
* Different models weight different risks differently — consensus is stronger.
*======================================================================*/
triage_opus [
label="Opus: Triage & Prioritize",
shape=box,
class="opus",
fidelity="full",
prompt="The consensus audit results are in context key response.audit_consensus. Parse the all_failed_items list from that JSON and triage every failing DoD checkbox.
Group failures into:
1. IMPLEMENTABLE — can be fixed by writing/modifying C code (functions, handlers, logic)
2. STRUCTURAL — requires new files, new modules, or significant architecture changes
3. DEFERRED — requires external resources (real API keys, network access, interactive testing) that cannot be done in a code-only pass
For each IMPLEMENTABLE item, identify the exact file(s) to modify and briefly describe the fix. Rank them by impact (most important first).
Output a JSON object:
{
\"model\": \"opus\",
\"total_failing\": N,
\"implementable\": [ {\"rank\": 1, \"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"files\": [\"...\"], \"fix\": \"...\", \"impact\": \"high|medium|low\"} ],
\"structural\": [ ... ],
\"deferred\": [ ... ]
}"
]
triage_gpt [
label="GPT-5.2: Triage & Prioritize",
shape=box,
class="gpt",
fidelity="full",
prompt="The consensus audit results are in context key response.audit_consensus. Parse the all_failed_items list from that JSON and triage every failing DoD checkbox.
Group failures into:
1. IMPLEMENTABLE — can be fixed by writing/modifying C code (functions, handlers, logic)
2. STRUCTURAL — requires new files, new modules, or significant architecture changes
3. DEFERRED — requires external resources (real API keys, network access, interactive testing) that cannot be done in a code-only pass
For each IMPLEMENTABLE item, identify the exact file(s) to modify and briefly describe the fix. Rank them by impact (most important first).
Output a JSON object:
{
\"model\": \"gpt-5.2\",
\"total_failing\": N,
\"implementable\": [ {\"rank\": 1, \"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"files\": [\"...\"], \"fix\": \"...\", \"impact\": \"high|medium|low\"} ],
\"structural\": [ ... ],
\"deferred\": [ ... ]
}"
]
triage_merge [
label="Merge: Triage Consensus",
shape=box,
class="merge",
fidelity="full",
prompt="You have two triage reports in context: response.triage_opus and response.triage_gpt. Merge them into a single prioritized work plan.
Resolution rules:
1. If both models classify an item the same way (IMPLEMENTABLE/STRUCTURAL/DEFERRED) → keep that classification
2. If they disagree on classification → take the MORE ACTIONABLE classification (prefer IMPLEMENTABLE over STRUCTURAL over DEFERRED)
3. For ranking, average the ranks and re-sort. If one model identified files/fixes the other didn't, include all suggestions.
4. Deduplicate items that both models identified.
Output a JSON object:
{
\"total_failing\": N,
\"implementable\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"files\": [\"...\"], \"fix\": \"...\", \"opus_rank\": N, \"gpt_rank\": N} ],
\"structural\": [ ... ],
\"deferred\": [ ... ],
\"classification_disagreements\": N,
\"verdict\": \"all_clear\" | \"has_fixes\" | \"only_deferred\"
}
If total_failing == 0 or verdict == \"only_deferred\", set preferred_next_label to \"Done\".
Otherwise set preferred_next_label to \"Fix\"."
]
/*========================================================================
* PHASE 5 — Multi-Model Implementation
*
* Codex implements, Opus reviews and corrects, Codex validates.
* Like megaplan's draft→critique→merge but for code.
*======================================================================*/
fix_codex [
label="Codex: Implement Fixes",
shape=box,
class="codex",
goal_gate=true,
fidelity="full",
prompt="The merged triage report is in context key response.triage_merge. It contains a prioritized list of IMPLEMENTABLE DoD failures.
Pick the top 5 most impactful items (or all if fewer than 5) and implement the fixes in pure C11.
For each fix:
1. Read the relevant source file(s)
2. Make the minimal change needed to satisfy the DoD checkbox
3. Write the modified file(s)
4. Verify the fix compiles (mentally trace includes and types)
Constraints:
- Do NOT modify any files under attractor-main/ (those are the specs)
- Do NOT add external dependencies beyond what's already used (libcurl, pthreads, math)
- Keep changes minimal and focused — one checkbox per fix
- Maintain the existing code style
After implementing, output:
{
\"model\": \"codex\",
\"fixes_applied\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"files_changed\": [\"...\"], \"description\": \"...\"} ],
\"count\": N,
\"remaining_implementable\": M
}"
]
review_fix_opus [
label="Opus: Review & Fix",
shape=box,
class="opus",
goal_gate=true,
fidelity="full",
prompt="Codex just implemented a batch of fixes. Its report is in context key response.fix_codex.
PART A — Review Codex's work:
1. Read every file that Codex modified (check the files_changed lists in response.fix_codex)
2. For each fix, verify it actually satisfies the DoD checkbox it claims to address
3. Check for: correctness, edge cases, style consistency, missing error handling
4. If a fix is wrong or incomplete, rewrite it correctly
PART B — Implement additional fixes:
5. From the remaining IMPLEMENTABLE items (see response.triage_merge for the full list), pick up to 5 more and implement them
6. Follow the same constraints as Codex (pure C11, no new deps, minimal changes)
Output:
{
\"model\": \"opus\",
\"codex_fixes_reviewed\": N,
\"codex_fixes_correct\": N,
\"codex_fixes_corrected\": [ {\"spec\": \"...\", \"section\": \"...\", \"issue\": \"...\", \"correction\": \"...\"} ],
\"additional_fixes\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"files_changed\": [\"...\"], \"description\": \"...\"} ],
\"total_fixes_this_round\": N,
\"remaining_implementable\": M
}"
]
review_codex [
label="Codex: Validate All Changes",
shape=box,
class="codex",
fidelity="full",
prompt="Opus reviewed your fixes and implemented additional ones. Its report is in context key response.review_fix_opus. Your original report is in response.fix_codex.
Validate the full set of changes from this round:
1. Read every file modified in this round (check files_changed in both response.fix_codex and response.review_fix_opus)
2. Check each change for correctness: does it satisfy its DoD checkbox?
3. Check for regressions: did any fix break something else?
4. Check for consistency: do all the changes work together?
Output:
{
\"model\": \"codex\",
\"total_changes_reviewed\": N,
\"all_correct\": true/false,
\"issues_found\": [ {\"file\": \"...\", \"issue\": \"...\", \"severity\": \"critical|minor\"} ],
\"remaining_implementable\": M
}
If issues_found contains any critical items, set preferred_next_label to \"More fixes needed\".
If remaining_implementable > 0 and no critical issues, set preferred_next_label to \"More fixes needed\".
Otherwise set preferred_next_label to \"Ready for build\"."
]
/*========================================================================
* PHASE 6 — Build Verification
*======================================================================*/
build_check [
label="Build & Smoke Test",
shape=parallelogram,
tool_command="cd /Users/justin.mccarthy/code/jm-attractor && make clean && make 2>&1 && echo '---BUILD OK---' && ./attractor --dry-run test/simple.dot 2>&1 && ./attractor --dry-run test/branching.dot 2>&1 && ./attractor --dry-run test/styled.dot 2>&1 && ./attractor --dry-run test/parallel.dot 2>&1 && ./attractor --dry-run test/conditions.dot 2>&1 && echo '---ALL TESTS PASSED---'",
timeout="120s"
]
build_fix [
label="Opus: Fix Build Errors",
shape=box,
class="opus",
fidelity="full",
prompt="The build or smoke tests failed. The build output is in context key tool.output. Diagnose the compilation errors or test failures and fix them.
Read the relevant source files, identify the issue, and write corrected versions. Common issues:
- Missing includes
- Type mismatches
- Undeclared functions
- Linker errors
Output the fixes applied and ensure the code will compile cleanly with: cc -Wall -Wextra -std=c11"
]
/*========================================================================
* PHASE 7 — Dual Final Audit (interleaved, fidelity-isolated)
*
* Both models independently verify the fixes worked.
* If either model finds a remaining failure, it counts.
*======================================================================*/
final_audit_opus [
label="Opus: Final Verification",
shape=box,
class="opus",
fidelity="full",
prompt="This is a verification pass. The items that were previously failing are listed in context key response.triage_merge (the implementable list). The fixes applied are in response.fix_codex and response.review_fix_opus.
Re-read all three spec DoD sections:
- attractor-main/unified-llm-spec.md Section 8
- attractor-main/coding-agent-loop-spec.md Section 9
- attractor-main/attractor-spec.md Section 11
And re-read the implementation files that were changed in this iteration.
Check ONLY the items that were previously failing. Have they been fixed?
Output:
{
\"model\": \"opus\",
\"verified_fixed\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\"} ],
\"still_failing\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"reason\": \"...\"} ],
\"newly_broken\": [ ... ],
\"remaining_total\": N
}"
]
final_audit_gpt [
label="GPT-5.2: Final Verification",
shape=box,
class="gpt",
fidelity="full",
prompt="This is a verification pass. The items that were previously failing are listed in context key response.triage_merge (the implementable list). The fixes applied are in response.fix_codex and response.review_fix_opus.
Re-read all three spec DoD sections:
- attractor-main/unified-llm-spec.md Section 8
- attractor-main/coding-agent-loop-spec.md Section 9
- attractor-main/attractor-spec.md Section 11
And re-read the implementation files that were changed in this iteration.
Check ONLY the items that were previously failing. Have they been fixed?
Output:
{
\"model\": \"gpt-5.2\",
\"verified_fixed\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\"} ],
\"still_failing\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"reason\": \"...\"} ],
\"newly_broken\": [ ... ],
\"remaining_total\": N
}"
]
final_consensus [
label="Merge: Final Consensus",
shape=box,
class="merge",
fidelity="full",
prompt="You have final audit results from both models in context: response.final_audit_opus and response.final_audit_gpt. Merge them into a definitive status.
Rules:
1. An item is only \"verified_fixed\" if BOTH models agree it's fixed
2. If EITHER model says an item is still failing, it counts as still failing
3. Union all newly_broken items from both models
Output:
{
\"verified_fixed\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"agreed_by\": \"both|opus_only|gpt_only\"} ],
\"still_failing\": [ {\"spec\": \"...\", \"section\": \"...\", \"text\": \"...\", \"flagged_by\": \"both|opus_only|gpt_only\", \"reason\": \"...\"} ],
\"newly_broken\": [ ... ],
\"remaining_total\": N
}
If remaining_total == 0 (ignoring DEFERRED items), set preferred_next_label to \"Complete\".
Otherwise set preferred_next_label to \"More work needed\"."
]
/*========================================================================
* PHASE 8 — Human Gate
*======================================================================*/
review_gate [
label="A) Accept & finish\nB) Push for another round",
shape=hexagon
]
/*========================================================================
* EDGES — Serial interleaved chain
*
* The engine is single-path, so we interleave model audits per-spec.
* fidelity="truncate" on audit nodes prevents cross-model anchoring.
*======================================================================*/
/* Phase 1: Interleaved audits (Opus then GPT for each spec) */
start -> audit_llm_opus
audit_llm_opus -> audit_llm_gpt
audit_llm_gpt -> audit_agent_opus
audit_agent_opus -> audit_agent_gpt
audit_agent_gpt -> audit_attractor_opus
audit_attractor_opus -> audit_attractor_gpt
/* Phase 2: Cross-critique (now sequential — GPT critiques Opus, then Opus critiques GPT) */
audit_attractor_gpt -> critique_by_gpt
critique_by_gpt -> critique_by_opus
/* Phase 3: Consensus */
critique_by_opus -> audit_consensus
/* Phase 4: Dual triage (sequential — Opus then GPT then merge) */
audit_consensus -> triage_opus
triage_opus -> triage_gpt
triage_gpt -> triage_merge
/* Triage decision */
triage_merge -> exit [label="Done", condition="preferred_label=Done"]
triage_merge -> fix_codex [label="Fix", condition="preferred_label=Fix", weight=10]
triage_merge -> exit [label="Only deferred remain"]
/* Phase 5: Multi-model implementation (sequential alternation) */
fix_codex -> review_fix_opus
review_fix_opus -> review_codex
/* Implementation loop */
review_codex -> fix_codex [label="More fixes needed", condition="preferred_label=More fixes needed", loop_restart=true]
review_codex -> build_check [label="Ready for build", condition="preferred_label=Ready for build"]
/* Phase 6: Build */
build_check -> final_audit_opus [label="Build OK", condition="outcome=success"]
build_check -> build_fix [label="Build failed", condition="outcome=fail"]
build_fix -> build_check
/* Phase 7: Dual final audit (sequential — Opus then GPT then consensus) */
final_audit_opus -> final_audit_gpt
final_audit_gpt -> final_consensus
/* Final decision */
final_consensus -> review_gate [label="Complete", condition="preferred_label=Complete"]
final_consensus -> triage_merge [label="More work needed", condition="preferred_label=More work needed"]
/* Phase 8: Human gate */
review_gate -> exit [label="A) Accept"]
review_gate -> triage_merge [label="B) Another round"]
}