| name | design-dag-loops |
| description | Design and operate efficient multi-agent coding DAGs for medium or large software projects. Use when Codex needs to decompose a specification into parallel executor leaves, define dependencies and integration gates, choose GPT-5.6 models, isolate worktrees, control executor-reviewer loops, prevent graph drift, use risk-based validation, maintain deterministic run state, or recover a long-running DAG that is slow, expensive, cyclic, or blocked. |
Design DAG Loops
Mission
Turn a product specification into a directed acyclic graph of small, independently verifiable coding loops. Optimize for trustworthy output, short wall-clock time, low coordination cost, and bounded token use.
Use this skill as the complete operating workflow.
Non-negotiable principles
- Treat the product specification and accepted decisions as the contract.
- Prefer the smallest independently useful leaf, not the smallest possible edit.
- Give each leaf one outcome, one primary risk, one owner, one bounded write scope, and one acceptance check.
- Decompose by responsibility and hidden design decision, not only by workflow phase.
- Run graph preflight before spawning any executor.
- Parallelize only leaves proven independent by contracts, data ownership, migration ownership, runtime mounts, and write scope.
- Keep executors cheap by making work simple; do not use a stronger model instead of reducing scope.
- Validate at the narrowest level that proves the change. Run full exact-head E2E only at a risk-bearing final gate or when a shared contract changed.
- Bound every executor-reviewer loop. Redesign architectural uncertainty instead of patching it forever.
- Keep deterministic state outside conversation context. Repository state is evidence; conversation summaries are navigation.
- Use real services, real data paths, and real integrations. Never substitute mocks, demos, fallbacks, or fake completion unless explicitly requested.
Decide whether a DAG is warranted
Use a single coding loop when work is one small sequential change, one tightly coupled module, or cannot produce two independently verifiable leaves.
Use a DAG when at least two leaves can proceed independently and later converge through explicit contracts. Do not build a DAG merely to keep agent slots busy.
Required artifacts
Before execution, create or identify:
PRODUCT_SPEC.md or an equivalent accepted functional specification;
DAG_PLAN.md with nodes, edges, contracts, acceptance checks, and model routing;
DAG_STATE.json as the deterministic current checkpoint;
DECISIONS.md as an append-only record of accepted contract or scope changes;
- one issue, branch, and isolated worktree per implementation leaf when Git is available.
Use the exact templates in references/templates.md.
Workflow
1. Freeze the product contract
Extract behavior, domain boundaries, data/API contracts, security invariants, external dependencies, acceptance criteria, missing inputs, and explicit stop conditions.
Do not start executors while material product behavior is ambiguous. Record unresolved product decisions as blockers, not executor freedom.
2. Design leaves
Apply the leaf test in references/leaf-design.md.
Split a candidate leaf if it owns more than one independent outcome or combines multiple primary risk classes such as:
- a new external integration;
- a new state machine or retry/recovery model;
- a security or permissions boundary;
- concurrency or distributed ownership;
- a schema/migration family;
- a substantial UI workflow.
A leaf may cross backend and frontend only when the user-visible behavior cannot be independently completed or verified otherwise. Keep shared wiring for an integration node when possible.
3. Run mandatory graph preflight
Build the preflight matrix from references/graph-preflight.md.
Reject parallel execution when two leaves share any unresolved mutable contract, migration chain, shared model, runtime mount, route registry, generated artifact, or overlapping write scope.
Do not solve a bad graph by inventing complex merge infrastructure. Change the edges or serialize the leaves.
4. Review contracts only where needed
Run a pre-code contract review when a leaf creates or changes a shared API, data model, authorization boundary, concurrency protocol, external-service contract, migration strategy, or cross-leaf invariant.
Skip contract review when the leaf is tiny, follows an already accepted contract, and has no shared mutable decision. Small leaves should make contract review rare, not ceremonial.
Contract review returns one of:
CONTRACT_APPROVED;
CONTRACT_CHANGES_REQUIRED with a single consolidated list;
GRAPH_REDRAFT_REQUIRED when the proposed leaf is not independently safe.
5. Freeze model routing before execution
Use the minimum sufficient GPT-5.6 model:
| Work | Model | Reasoning |
|---|
| Tiny fixed-contract implementation or mechanical change | gpt-5.6-luna | medium |
| Ordinary small implementation leaf | gpt-5.6-terra | low |
| Read-heavy exploration or targeted fix re-review | gpt-5.6-terra | medium |
| Major independent PR review or integration gate | gpt-5.6-sol | medium |
| Critical security, destructive, or complex data-migration review | gpt-5.6-sol | high |
Use Sol high rarely. First try to reduce scope, strengthen the contract, or split the leaf.
Always set model and reasoning explicitly. Never raise reasoning indefinitely to compensate for an oversized leaf.
6. Launch one isolated loop per ready leaf
Only launch nodes whose dependencies are merged or represented by frozen accepted contracts.
Give every executor:
- exact node ID and outcome;
- accepted input/output contracts;
- absolute worktree path and branch;
- allowed write scope and prohibited paths;
- one primary risk;
- exact acceptance checks;
- real services/data required;
- stop conditions;
- instruction not to merge or modify DAG state.
The executor must begin with a preflight proof: current directory, repository root, branch, clean/expected worktree, base SHA, and readable plan revision. Stop immediately on mismatch.
7. Validate proportionally to risk
Use the validation ladder in references/review-and-validation.md:
- reproduction or narrow regression;
- changed module checks;
- affected contract/integration checks;
- full CI and real external proof only for the final candidate or a changed shared contract.
Do not repeat expensive IMAP, browser, migration, or full E2E suites after an unrelated tiny fix. Do not weaken validation for security, data-loss, accessibility, or trust-boundary changes.
8. Review without restarting the world
Use a Terra medium reviewer for a small leaf or a narrow fix verification. Use a fresh read-only Sol medium reviewer for a major PR, integration node, or final gate. Reserve Sol high for the rare critical cases in the routing table.
The first reviewer returns one consolidated set of findings. The same reviewer verifies its own narrow findings after fixes. Do not create a new full reviewer after every small commit.
Use a fresh final reviewer only when the node is large/risky, the exact head changed materially, or the integration gate requires independent confirmation.
9. Enforce the cycle budget
Default budget:
- one implementation pass;
- one independent review;
- at most two targeted fix passes with the same reviewer;
- one final candidate verification;
- one fresh final review only for a major/risk-bearing node.
If the budget is exhausted, do not merge and do not keep patching. Classify the cause:
- implementation bug -> replace or re-scope the executor;
- unclear contract -> return to contract design;
- false independence -> redraw graph edges;
- oversized leaf -> split it;
- external blocker -> stop and escalate with exact evidence.
Read the full rules in references/state-and-cycle-budget.md.
10. Integrate accepted leaves
An integration node consumes only accepted SHAs and frozen contracts. It must not be the first place where migration ownership, shared schemas, route mounts, or cross-node invariants are discovered.
The integration agent checks contracts, resolves expected wiring, runs affected integration checks, and creates a stable checkpoint. Run full E2E only when this gate is responsible for the full path.
11. Update state and memory on transitions
The root orchestrator is the only writer of DAG_STATE.json.
Update state after:
- spawn;
- implementation completion;
- PR opened;
- review verdict;
- accepted decision or dependency change;
- merge;
- blocker;
- node split, abandonment, or graph redraft.
Update GitHub and memory after every significant transition. Do not update memory for unchanged polls.
12. Wait cheaply
Wait on agent, CI, or external events. On wake-up, read only:
DAG_STATE.json;
- events newer than its recorded cursor;
- the active node contract.
Re-read the full plan only when changing nodes, resolving a conflict, accepting a contract change, or recovering from inconsistent state.
Never emit repeated status reasoning merely to say that an agent is still working.
13. Finish with an evidence audit
Re-read the product spec and DAG plan. Verify every requirement against merged SHAs, tests, runtime behavior, external proofs, and remaining issues. Confirm no open integration worktree, unreviewed PR, dirty tree, stale state, or false completion claim.
Stop and escalate
Stop a node when:
- required credentials, real data, infrastructure, or a user decision is missing;
- the only remaining path uses fake data, a fallback, or unverified behavior;
- work requires an unaccepted shared contract change;
- the leaf proves non-independent or exceeds its cycle budget;
- a destructive or irreversible action requires owner approval;
- repository state contradicts
DAG_STATE.json and cannot be reconciled safely.
Do not stop for ordinary test failures. Fix them within the cycle budget.
Reference routing