fabro/test/attractor/reference_template.dot
2026-04-30 06:48:47 -04:00

396 lines
18 KiB
Text

digraph reference_template {
graph [
goal="$goal",
rankdir=LR,
default_max_retries=3,
retry_target="implement",
fallback_retry_target="debate_consolidate",
provenance_version="1",
model_stylesheet="
* { model: DEFAULT_MODEL; provider: DEFAULT_PROVIDER; }
.hard { model: HARD_MODEL; provider: HARD_PROVIDER; }
.verify { model: VERIFY_MODEL; provider: VERIFY_PROVIDER; }
.branch-a { model: BRANCH_A_MODEL; provider: BRANCH_A_PROVIDER; }
.branch-b { model: BRANCH_B_MODEL; provider: BRANCH_B_PROVIDER; }
.branch-c { model: BRANCH_C_MODEL; provider: BRANCH_C_PROVIDER; }
"
]
// =======================================================================
// TEMPLATE USAGE
//
// This template defines TOPOLOGY ONLY: node shapes, edges, routing,
// and structural patterns. It contains NO prompt text.
//
// The ingestor must compose every prompt from scratch based on the
// actual project spec, DoD, and repo contents. Prompt requirements
// are listed in comments above each shape=box node. See Phase 4 of
// the create-dotfile skill for the full prompt contract.
//
// Common requirements for ALL shape=box prompts (do not repeat per node):
// - Reference $goal
// - Full status contract: write to $KILROY_STAGE_STATUS_PATH,
// fall back to $KILROY_STAGE_STATUS_FALLBACK_PATH, do not write
// nested status.json after cd, use schema {"status":"..."}
// - For status=fail or status=retry: include failure_reason, details,
// and failure_class
// =======================================================================
exit [shape=Msquare, label="Exit"]
subgraph cluster_bootstrap {
label="Bootstrap"
start [shape=Mdiamond, label="Start"]
// Toolchain gate — fail fast before LLM stages.
// Replace tool_command with project-specific checks.
check_toolchain [
shape=parallelogram,
max_retries=0,
tool_command="echo 'Replace with project-specific toolchain checks'; exit 0"
]
// PROMPT: expand_spec
// Role: create or reuse canonical spec at .ai/spec.md
// Must address:
// - Reuse existing .ai/spec.md or repo spec if adequate
// - Copy user-declared verbatim specs without rewriting
// - Expand from $goal only when no adequate spec exists
// - Spec must include: scope, constraints, assumptions, acceptance
// criteria, verification approach, non-goals
// Reads: $goal, existing .ai/spec.md (if any), repo docs
// Writes: .ai/spec.md
// Note: auto_status=true — no explicit status write needed
expand_spec [
shape=box,
auto_status=true
]
// PROMPT: check_dod
// Role: determine if .ai/definition_of_done.md is adequate
// Must address:
// - Check file existence and content (not placeholder)
// - Apply DoD rubric: scope, deliverables, AC, verification,
// quality/safety gates, non-goals
// - Apply coverage checklist: build, tests, lint, docs,
// compatibility, security, ops, perf
// Reads: .ai/definition_of_done.md
// Outcomes: has_dod or needs_dod
check_dod [
shape=box,
label="DoD exists?"
]
}
subgraph cluster_dod {
label="DoD Fanout"
node [shape=box]
dod_fanout [shape=component, label="DoD Fan-Out"]
// PROMPT: dod_a, dod_b, dod_c
// (identical prompt — diversity comes from different models)
// Role: propose a project DoD from the spec
// Must address:
// - Read .ai/spec.md
// - DoD is outcomes/evidence, not a plan
// - Each item verifiable (pass/fail)
// - Don't prescribe implementation approach
// - Include: scope, deliverables, AC, verification, non-goals
// - Apply coverage checklist
// Writes: .ai/dod_a.md (or _b, _c)
dod_a [class="branch-a"]
dod_b [class="branch-b"]
dod_c [class="branch-c"]
// PROMPT: consolidate_dod
// Role: synthesize dod_a/b/c into consensus DoD
// Must address:
// - Read branch outputs via parallel_results.json + worktree_dir
// - Fall back to current worktree if parallel_results.json missing
// - Read .ai/spec.md for context
// - Resolve contradictions, apply DoD rubric + coverage checklist
// Writes: .ai/definition_of_done.md
consolidate_dod [auto_status=true]
}
subgraph cluster_planning {
label="Planning Fanout"
node [shape=box]
plan_fanout [shape=component, label="Plan Fan-Out"]
// PROMPT: plan_a, plan_b, plan_c
// (identical prompt — diversity comes from different models)
// Role: create implementation plan from spec + DoD
// Must address:
// - Read .ai/spec.md and .ai/definition_of_done.md
// - If .ai/postmortem_latest.md exists, incorporate its lessons
// - Plan must cover all deliverables and acceptance criteria
// from the DoD, with project-specific implementation detail
// - Plan must be grounded in the actual project domain,
// technology stack, and repo structure
// Writes: .ai/plan_a.md (or _b, _c)
plan_a [class="branch-a"]
plan_b [class="branch-b"]
plan_c [class="branch-c"]
// PROMPT: debate_consolidate
// Role: synthesize plan_a/b/c into best-of-breed final plan
// Must address:
// - Read branch outputs via parallel_results.json + worktree_dir
// - Fall back to current worktree if parallel_results.json missing
// - If .ai/postmortem_latest.md exists, verify plan addresses
// every identified issue
// - Resolve conflicts, ensure dependency order
// Writes: .ai/plan_final.md
debate_consolidate [auto_status=true]
}
// OPTIONAL: For porting/reading-existing-source tasks — add analyze cluster here.
// analyze_fanout [shape=component, label="Analyze Fan-Out"]
// analyze_module_a [shape=box, auto_status=true, prompt="...read source, write .ai/design_a.md..."]
// analyze_module_b [shape=box, auto_status=true, prompt="..."]
// merge_analysis [shape=box, auto_status=true, prompt="...verify all design docs..."]
// See reference_template.dot OPTIONAL stubs below for pattern.
// OPTIONAL: For 5+ discrete deliverable files — use worker pool instead of flat fan-out.
// plan_work [shape=box, auto_status=true, label="Plan Work Queue", prompt="...write .ai/work_queue.json..."]
// work_pool [shape=component, label="Worker Pool"]
// worker_0 [shape=box, auto_status=true, label="Worker 0", prompt="...id%3==0..."]
// worker_1 [shape=box, auto_status=true, label="Worker 1", prompt="...id%3==1..."]
// worker_2 [shape=box, auto_status=true, label="Worker 2", prompt="...id%3==2..."]
// check_work_complete [shape=box, auto_status=true, label="Work Complete?", prompt="...pass counter..."]
subgraph cluster_implement_verify {
label="Implement And Verify"
// PROMPT: implement
// Role: single-writer code implementation (fresh or repair)
// Must address:
// - REPAIR FIRST: if .ai/postmortem_latest.md exists, read it
// FIRST, fix ONLY identified gaps, do NOT regenerate working
// systems, preserve all passing code and tests
// - FRESH: if no postmortem, execute .ai/plan_final.md
// - Read .ai/spec.md and .ai/definition_of_done.md
// - Implementation instructions must be specific to the project's
// deliverables, domain, technology, and constraints — derived
// from the ingestor's reading of the spec and DoD
// - Incremental implementation: each module complete before next
// - Log progress to .ai/implementation_log.md
// Failure: also include failure_signature in meta
implement [
shape=box,
class="hard",
max_retries=2
]
check_implement [shape=diamond, label="Implement OK?"]
// Auto-fix formatting before verify gate.
// Replace tool_command with project-specific auto-formatter.
fix_fmt [
shape=parallelogram,
max_retries=0,
tool_command="echo 'Replace with project-specific auto-formatter'; exit 0"
]
// Replace tool_command with project-specific formatter check.
verify_fmt [
shape=parallelogram,
max_retries=0,
tool_command="echo 'Replace with project-specific formatter check'; exit 0"
]
check_fmt [shape=diamond, label="Fmt OK?"]
// Replace tool_command with project-specific build command.
verify_build [
shape=parallelogram,
tool_command="echo 'Replace with project-specific build check'; exit 0"
]
check_build [shape=diamond, label="Build OK?"]
// Replace tool_command with project-specific test command.
verify_test [
shape=parallelogram,
tool_command="echo 'Replace with project-specific test check'; exit 0"
]
check_test [shape=diamond, label="Tests OK?"]
// Replace tool_command with artifact hygiene check.
// Confirm deliverables meet their interface contract (exports, endpoints,
// CLI behavior, observable outputs); file existence alone is insufficient.
verify_artifacts [
shape=parallelogram,
max_retries=0,
tool_command="echo 'Replace with artifact hygiene check'; exit 0"
]
check_artifacts [shape=diamond, label="Artifacts OK?"]
// PROMPT: verify_fidelity
// Role: semantic review after all deterministic checks pass
// Must address:
// - Read implementation outputs and verify against
// .ai/definition_of_done.md and .ai/spec.md
// - Verification must be specific to the project's acceptance
// criteria — enumerate the actual areas to check, derived from
// the ingestor's reading of the DoD
// - Write results to .ai/verify_fidelity.md
// Failure: also include failure_signature in meta — sorted
// comma-separated list of specific failed criteria identifiers
verify_fidelity [
shape=box,
class="verify"
]
check_impl [shape=diamond, label="Impl OK?"]
}
subgraph cluster_review {
label="Review Fanout"
node [shape=box]
review_fanout [shape=component, label="Review Fan-Out"]
// PROMPT: review_a, review_b, review_c
// (identical prompt — diversity comes from different models)
// Role: review implementation against DoD
// Must address:
// - Read .ai/definition_of_done.md for acceptance criteria
// - Read implementation outputs
// - Check build, completeness, correctness, tests against all
// DoD criteria — enumerate what to check, derived from the
// ingestor's reading of the DoD
// - Verdict: APPROVED or REJECTED with specific evidence
// Failure: include specific gaps with criteria identifiers
// Writes: .ai/review_a.md (or _b, _c)
review_a [class="branch-a"]
review_b [class="branch-b"]
review_c [class="branch-c"]
// PROMPT: review_consensus
// Role: synthesize reviews into consensus verdict
// Must address:
// - Read branch outputs via parallel_results.json + worktree_dir
// - Fall back to current worktree if parallel_results.json missing
// - Read .ai/definition_of_done.md for criteria
// - Consensus: 2+ APPROVED with no critical gaps -> success;
// otherwise -> retry with specific issues
// Writes: .ai/review_consensus.md
review_consensus [auto_status=true, goal_gate=true, retry_target="postmortem"]
}
subgraph cluster_postmortem {
label="Postmortem"
node [shape=box]
// PROMPT: postmortem
// Role: analyze failure and guide next repair iteration
// Must address:
// - Read .ai/review_consensus.md (if review stage reached)
// - Read .ai/verify_fidelity.md (if semantic verify ran)
// - Read branch review outputs via parallel_results.json +
// worktree_dir if available
// - Read .ai/implementation_log.md
// - Output: root causes, what worked (preserve), what failed
// (fix), concrete next changes
// - Must NOT direct from-scratch restart — preserve working code
// Outcome classification (recovery routing):
// - impl_repair: code repair needed; plan/toolchain still valid
// - needs_replan: plan/approach is inadequate; regenerate plan branches
// - needs_toolchain: environment/bootstrap/toolchain issue detected
// - When uncertain, default to impl_repair
// Writes: .ai/postmortem_latest.md (overwrite previous)
// Note: status reflects analysis completion, not implementation state
postmortem [auto_status=true]
}
// =========================================================================
// Flow
// =========================================================================
// Linear start: toolchain gate -> spec -> DoD check
start -> check_toolchain
check_toolchain -> expand_spec [condition="outcome=succeeded"]
check_toolchain -> check_toolchain [condition="outcome=failed && context.failure_class=transient_infra", loop_restart=true]
check_toolchain -> postmortem [condition="outcome=failed && context.failure_class!=transient_infra"]
check_toolchain -> postmortem
expand_spec -> check_dod
// DoD fan-out (if needed)
check_dod -> dod_fanout [condition="outcome=needs_dod"]
check_dod -> dod_fanout
dod_fanout -> dod_a
dod_fanout -> dod_b
dod_fanout -> dod_c
dod_a -> consolidate_dod
dod_b -> consolidate_dod
dod_c -> consolidate_dod
consolidate_dod -> plan_fanout
// Skip to planning if DoD exists
check_dod -> plan_fanout [condition="outcome=has_dod"]
// Planning fan-in -> debate -> implement
plan_fanout -> plan_a
plan_fanout -> plan_b
plan_fanout -> plan_c
plan_a -> debate_consolidate
plan_b -> debate_consolidate
plan_c -> debate_consolidate
debate_consolidate -> implement
// Verify/check inner loop (tool gates first, semantic review last)
implement -> check_implement
check_implement -> fix_fmt [condition="outcome=succeeded"]
fix_fmt -> verify_fmt
check_implement -> implement [condition="outcome=failed && context.failure_class=transient_infra", loop_restart=true]
check_implement -> postmortem [condition="outcome=failed && context.failure_class!=transient_infra"]
check_implement -> postmortem
verify_fmt -> check_fmt
check_fmt -> verify_build [condition="outcome=succeeded"]
check_fmt -> implement [condition="outcome=failed && context.failure_class=transient_infra", loop_restart=true]
check_fmt -> postmortem [condition="outcome=failed && context.failure_class!=transient_infra"]
check_fmt -> postmortem
verify_build -> check_build
check_build -> verify_test [condition="outcome=succeeded"]
check_build -> implement [condition="outcome=failed && context.failure_class=transient_infra", loop_restart=true]
check_build -> postmortem [condition="outcome=failed && context.failure_class!=transient_infra"]
check_build -> postmortem
verify_test -> check_test
check_test -> verify_artifacts [condition="outcome=succeeded"]
check_test -> implement [condition="outcome=failed && context.failure_class=transient_infra", loop_restart=true]
check_test -> postmortem [condition="outcome=failed && context.failure_class!=transient_infra"]
check_test -> postmortem
verify_artifacts -> check_artifacts
check_artifacts -> verify_fidelity [condition="outcome=succeeded"]
check_artifacts -> implement [condition="outcome=failed && context.failure_class=transient_infra", loop_restart=true]
check_artifacts -> postmortem [condition="outcome=failed && context.failure_class!=transient_infra"]
check_artifacts -> postmortem
verify_fidelity -> check_impl
check_impl -> review_fanout [condition="outcome=succeeded"]
review_fanout -> review_a
review_fanout -> review_b
review_fanout -> review_c
check_impl -> implement [condition="outcome=failed && context.failure_class=transient_infra", loop_restart=true]
check_impl -> postmortem [condition="outcome=failed && context.failure_class!=transient_infra"]
check_impl -> postmortem
// Review fan-in -> consensus
review_a -> review_consensus
review_b -> review_consensus
review_c -> review_consensus
// Consensus routing: success -> exit, anything else -> postmortem
review_consensus -> exit [condition="outcome=succeeded"]
review_consensus -> postmortem
// Domain-routed recovery: classify failure and choose the right re-entry
postmortem -> check_toolchain [condition="outcome=failed && context.failure_class=transient_infra"]
postmortem -> implement [condition="outcome=impl_repair"]
postmortem -> plan_fanout [condition="outcome=needs_replan"]
postmortem -> check_toolchain [condition="outcome=needs_toolchain"]
postmortem -> implement
}