Graph Engineering Cheat Sheet

By the Syncfusion DevTutorials team · Last updated

One page to come back to: loop or graph, the graph file format, the five patterns, state contract rules, exits, caps, join policies, gates, the scorecard, graph pack files per tool, and an error index for every linter rule.

How to Use This Page

This page collects everything from the course in one place: the decision, the file format, the patterns, the rules, the files for each tool, and every message the Graph Lab can show you. Keep it open while you build.

Tool paths and commands change often. The tool table below was checked against the official docs on 19 Oct 2026. Check again before you rely on a path.

Loop or Graph?

Start with one loop. Add nodes only when you can name what they buy.

AskIf yesPattern
Does the work split into independent parts?Run them at the same timeParallelization
Does the work mix risk levels?Send risky work down a careful pathRouting
Does one step leave dead ends the next should not see?Hand over a clean, typed resultPrompt chaining
Is the work list only found while running?Start capped workers for itOrchestrator-workers
Is there a clear pass test, and fixes need several tries?Fix and check until it passesEvaluator-optimizer
Is it a strict step-by-step plan one agent does well?Keep one loop—

Research on 260 agent setups: extra agents helped independent, parallel work by up to 80.8%, made strict step-by-step planning 39–70% worse, and hurt tasks one agent already did well.

The Five Patterns

Every graph in the course is built from these five patterns.

PatternWhat it buysHow it failsThe fix
Prompt chainingClean context for the next stepForwarding everythingWriter reads only a typed handoff
RoutingCost matched to riskQuiet misroutesStrong router, confidence threshold, careful else
ParallelizationLess waitingRaces; a hung branchOne field per branch; join timeout and policy
Orchestrator-workersWork found at run timeNo limitsCaps on width, depth and spend; topology record
Evaluator-optimizerFix until a test passesWeak exitsOscillation, no progress, flat score, budget

Graph File Template

Each node on one line. Copy this and change it.

graph: my-graph
checkpoint: after_each_node
kill_switch: GRAPH_PAUSED
nodes:
  - { id: route, kind: router, model: large, min_confidence: 0.7, reads: [ticket], writes: [route, risk_reason] }
  - { id: quick_fix, kind: agent, model: small, reads: [ticket], writes: [diff], exit: { checker: npm test, max_iterations: 4 } }
  - { id: careful_fix, kind: agent, model: large, on_bound: escalate, reads: [ticket], writes: [careful_diff, test_result], exit: { checker: npm test, max_iterations: 8, oscillation: true, no_progress: 2, flat_score: 3, budget: 20000 } }
  - { id: approve, kind: gate, evidence: [careful_diff, test_result, risk_reason], reads: [careful_diff, test_result, risk_reason], writes: [approval] }
  - { id: merge, kind: function, reads: [diff, careful_diff, approval], writes: [merged] }
edges:
  - { from: route, to: quick_fix, when: risk == low }
  - { from: route, to: careful_fix, when: risk == high }
  - { from: route, to: careful_fix, when: else }
  - { from: careful_fix, to: careful_fix }
  - { from: quick_fix, to: merge }
  - { from: careful_fix, to: approve }
  - { from: approve, to: merge }
state:
  route: { type: "low | high", writer: route }
  careful_diff: { type: diff, writer: careful_fix }
  test_result: { type: "pass | fail", writer: careful_fix }
  approval: { type: "approve | reject", writer: approve }

Node Kinds

KindWhat it is
functionPlain code: tests, a schema check, a build
modelOne prompt in, one answer out
agentA full agent running its own loop
routerPicks the next edge
joinWaits for branches and merges them
orchestratorFinds work and starts workers
gateWaits for a person

Edge Kinds

Written asKind
{ from: a, to: b }fixed
{ from: a, to: b, when: risk == high }conditional (when: else is the fallback)
{ from: a, to: a }loop-back
{ from: a, to: [b, c, d] }fan-out (each target then has an edge to a join)

State Contract Rules

One writer per field. Every node lists the fields it reads.

  1. Every field has one writer.
  2. Every node lists the fields it reads. Nobody reads *.
  3. Fields another node decides with get a small, exact type.
  4. Handoffs between chained nodes are typed shapes, like "{cause, steps, file}".
  5. checkpoint: after_each_node saves the state, so a crash resumes and a gate can wait.

Limits at a Glance

WhereSettingTypical value
Fixer exit:oscillationtrue
Fixer exit:no_progress2
Fixer exit:flat_score3
Fixer exit:budgettokens for this node
Fixer exit:max_iterations12 or less (backstop)
Fixeron_boundescalate
Routermodel, min_confidencelarge, 0.7
Jointimeout, policy10m, all / quorum / partial
Each parallel branchtimeoutshorter than the join's, e.g. 5m
Join after an orchestratorcheck_plantrue
Orchestrator caps:width, depth, spendat or below the API limit, 1, sized for the biggest job
Orchestratorrecord_topologytrue
Graphcheckpoint, kill_switchafter_each_node, GRAPH_PAUSED
Gateevidencediff, test result, risk reason

The Scorecard

A graph is graded on its run, never on its drawing.

NumberBar
Correct outcomes36 of 40 or more
Races0
Hung joins0
High-risk on the cheap path0
False "done"0
Size (nodes + edges)no more than the reference

Graphs in Each Tool

Graph Pack Files

FileClaude CodeCodexCursor
The plangraph.mdgraph.mdgraph.md
One subagent per node.claude/agents/<node>.md.codex/agents/<node>.toml.cursor/agents/<node>.md
Required fieldsname, descriptionname, description, developer_instructionsname, description
Per-node modelmodel: (sonnet, opus, haiku, a full id, inherit)model, model_reasoning_effortmodel:
Shared stategraph-state.json + state-contract.yamlsamesame
Supervisorsupervisor subagentsupervisor agentsupervisor subagent

None of the three tools has a visual graph runtime. The main agent follows graph.md and calls one subagent per node.

Debugging a Run

  1. Find a run that worked on the same kind of input.
  2. Read both logs from the top: node, inputs, tokens, time, verdict.
  3. The first row that differs is the cause. Rows after it are effects.
  4. Fix that node only, and run again.

Practise finding the broken node

Human Gates

  • Gate the paths with a large blast radius: auth, payments, data migrations.
  • Show the diff, the test result and the risk reason.
  • Never gate the quick path. Too many approvals means nobody reads them.
  • Ticket text never decides whether it needs review.

First Real Run Checklist

  • Run the test command by hand once.
  • Create GRAPH_PAUSED, start the graph, check that it stops. Delete the file.
  • Run the graph on 2 or 3 small tickets.
  • Change a state field by hand between two nodes. The supervisor must stop the graph.
  • Check that graph-state.json updates after every node.
  • Read every diff on the first day.

Keep the graph's health numbers each week: tokens per node, which exits fire, how many tickets reach a gate, and how many changes were later reverted. A number that moves is your cue to diff a run.

Error Index

The Graph Lab's linter rules and the common check messages, what causes them, and the fix. A check message starts with the version it failed on, for example "Version 2: …".

Graph Linter

RuleCauseFixLesson
router-no-fallbackA router has no when: else edgeAdd when: else to the careful pathRouting
two-writersTwo nodes write the same fieldGive each field one writerNodes, Edges, Shared State
join-no-timeoutA join waits foreverAdd timeout: 10mParallelization
orchestrator-no-capsNo limits on workersAdd caps: { width, depth, spend }Orchestrator-Workers
loop-back-no-exitA loop-back node has no exit:Add exits and a turn capEvaluator-Optimizer
whole-stateA node reads *List the fields it needsNodes, Edges, Shared State
risk-no-gateA high-risk path has no gateAdd a kind: gate node before the mergeHuman Gates
could-be-loopThe graph does one loop's jobUse one loopLoop or Graph?
no-checkpointNo checkpoint:Add checkpoint: after_each_nodeNodes, Edges, Shared State
no-kill-switchAn orchestrator with no stop switchAdd kill_switch: GRAPH_PAUSEDOrchestrator-Workers

Check Messages

Message starts withCauseFix
"… has 2 writers"Two nodes own a fieldOne writer per field
"… reads the whole state"reads: ["*"]List the fields
"The final status is …"A result was lost or never readLet one node read both results and decide
"After the crash …"No checkpointcheckpoint: after_each_node
"The script writer's context is …%"The writer reads too muchGive it only findings
"The handoff is not typed"findings is plain textGive it a shape in state:
"The router is right on …%"A weak routermodel: large
"… high-risk ticket(s) took the cheap path"Misroutes, no safe fallbackmin_confidence and a careful else
"Only … low-risk tickets took the quick path"Threshold too highLower min_confidence
"Branches write the same field"A raceOne field per branch
"One branch hung …"No join timeouttimeout: on the join
"The join has no policy:"No rule for missing branchespolicy: all, quorum or partial
"Branch … has no timeout: of its own"Only the join has a timeoutA shorter timeout: on each branch
"The join trusted the results …"Silent worker failurescheck_plan: true on the join
"Only … of 10 scripts test the real cause"Dead ends still reach the writerGive the writer only the typed findings
"No width cap …" / "… more than the API allows"Too many workers at oncewidth at or below the limit
"No depth cap …"Workers start workersdepth: 1
"The spend cap … stopped the run"Spend cap too lowSize it for the biggest job
"The realized topology is not recorded"No record of what ranrecord_topology: true
"The fixer went back and forth …"No oscillation exitoscillation: true
"Only the budget stopped it …"Exits missingAdd the exit for that stuck state
"A stop on a bound is reported as plain failure"No escalationon_bound: escalate
"… merged with no human gate"No gate on the risky pathGate before the merge
"A gate shows no evidence"Reviewer sees nothingevidence: [careful_diff, test_result, risk_reason]
"… the reference does the job with …" / "… does this job with …"The graph is bigger than neededRemove nodes that move no number
"The writer does not read findings" / "The investigator does not write findings"The handoff is brokenInvestigator writes findings; writer reads it
"The fixer made the same change again and again …"No no-progress exitno_progress: 2
"The score stayed flat while each try cost more …"No flat-score exitflat_score: 3
"max_iterations: … is a weak backstop"Turn cap too high12 or less
"… low-risk tickets wait for a person"Gates on the quick pathGate only the careful path
"The join waits … minutes"Join timeout too long30 minutes or less
"policy: … is not known"A typo in the policyall, quorum or partial
"The join does not read …" / "The verifier does not read …"A branch's result is never mergedList every branch field in the join's reads
"Add a verifier …" / "The verifier join has no timeout: …"Audits go straight to the fixer, or the verifier can hangA kind: join with a timeout and a policy
"The fixer has no test checker …"Fixes marked done with failing testsexit: { checker: <your test command> }
"The … export does not validate"A node or file is missingCheck the Export tab's message

Glossary

  • Node: one step of work: code, a model call, an agent loop, a router, a join, an orchestrator or a gate.
  • Edge: a route from one node to the next: fixed, conditional, loop-back or fan-out.
  • Shared state: the typed record that travels with the work.
  • State contract: each field's type, its one writer and its readers.
  • Handoff: the field one node writes for the next.
  • Join policy: what a join does when a branch is missing: all, quorum or partial.
  • Caps: limits on an orchestrator's width, depth and spend.
  • Realized topology: what a run actually started.
  • Stopped on bound: a loop that stopped because an exit fired, not because it failed.
  • Blast radius: how much damage a wrong change can do.
  • Graph pack: the exported files: graph.md, subagents, state contract, supervisor, notes.

Further Reading