{
  "module": "DD-10 — LangGraph: Graph-Based State Machines",
  "course": "Master Course",
  "version": "1.0.0",
  "duration_minutes": 30,
  "total_questions": 15,
  "bloom_distribution": {
    "target": "20% recall / 40% application / 40% analysis",
    "actual": { "recall": 3, "application": 6, "analysis": 6 }
  },
  "passing_score_percent": 70,
  "questions": [
    {
      "id": "Q01", "bloom": "recall", "type": "multiple_choice",
      "prompt": "What is LangGraph's defining architectural feature?",
      "options": [
        "A minimal while-true loop that the model participates in but does not see.",
        "The loop is an EXPLICIT GRAPH — nodes (functions) and edges (transitions) declared in code, drawn before you run it. Every transition is visible, testable, and editable.",
        "A sophisticated but implicit loop that figures out the process as it goes.",
        "A session-based harness where each turn is a checkpoint."
      ],
      "answer_index": 1,
      "rationale": "LangGraph's defining feature is that the loop IS the graph. Nodes are functions (take state, do work, return a state update). Edges are transitions, with conditional edges expressing branching in code. This is the largest architectural divergence in the roster: where Pi (DD-01) makes the loop minimal and implicit, and Claude Code makes the loop sophisticated but implicit, LangGraph makes the loop the entire product — explicit, declared, auditable. Options 1 and 3 describe implicit loops (Pi, Claude Code). Option 4 describes session-based checkpointing (OpenCode, DD-03), not graph-based state."
    },
    {
      "id": "Q02", "bloom": "recall", "type": "multiple_choice",
      "prompt": "LangGraph scores 37/60 and earns 5/5 on two modules. Which two, and why?",
      "options": [
        "Module 4 (Memory) and Module 6 (Permission) — the depth and governance references.",
        "Module 2 (Tools) and Module 5 (Sandbox) — the richest tool and isolation surfaces.",
        "Module 1 (Loop) and Module 8 (State) — Module 1 because the graph IS the loop made explicit; Module 8 because super-step checkpoints serialize state at every node boundary, the finest granularity in the roster.",
        "Module 10 (Subagents) and Module 11 (Observability) — the subgraph and audit-trail references."
      ],
      "answer_index": 2,
      "rationale": "LangGraph maxes on the two orchestration axes. Module 1 (Loop) is 5/5 because the graph IS the loop — no implicit while-true, every transition declared in code. Module 8 (State) is 5/5 because of super-step checkpoints: state is serialized at every node boundary, so a crash resumes from the last completed node, not from the session start. These are the axes where being a declared graph is the advantage, and LangGraph is the reference on both. Options 1, 2, and 4 name modules where LangGraph scores 3/5 or 4/5 (Memory 3/5, Sandbox 2/5, Subagents 3/5) — it loses on substrate axes because it is a framework, not a finished harness."
    },
    {
      "id": "Q03", "bloom": "recall", "type": "multiple_choice",
      "prompt": "What is a super-step in LangGraph?",
      "options": [
        "A single model call within a node.",
        "A node boundary where state is serialized and checkpointed — the atomic unit of resumption. A crash resumes from the last completed super-step.",
        "A human-in-the-loop approval cycle.",
        "A conditional edge that routes between two nodes."
      ],
      "answer_index": 1,
      "rationale": "A super-step is a node boundary where state is serialized and checkpointed. It is the atomic unit of resumption: if the run is interrupted (crash, human pause, deployment), it resumes from the last completed super-step — the last completed node — not from scratch. This is why LangGraph scores 5/5 on Module 8 (State): the granularity is the STEP, not the session. Compare to OpenCode (DD-03), where the session is the checkpoint unit — you resume from approximately where you were, not from exactly where you were. Options 1, 3, and 4 describe components within a node or edge, not the checkpoint boundary."
    },
    {
      "id": "Q04", "bloom": "application", "type": "multiple_choice",
      "prompt": "Your team needs a multi-approval compliance pipeline where an auditor must trace the exact path every execution took, and the process must survive crashes across multiple days and five human approvers. Which framework, and why?",
      "options": [
        "Pi (DD-01) — the minimal loop gives the model maximum flexibility to figure out the workflow.",
        "LangGraph — the process IS the product. A declared graph makes every transition visible and auditable; super-step checkpoints resume from the exact crashed node across multi-day runs; interrupt() structural HITL handles the five human approvers without the model routing around any of them.",
        "OpenClaw (DD-07) — channel breadth covers the multi-approver case.",
        "Hermes (DD-08) — the self-evolving skill store learns the compliance workflow over time."
      ],
      "answer_index": 1,
      "rationale": "This is the textbook 'process is the product' use case, and LangGraph is the framework for it. Three properties align: (1) the declared graph makes every transition visible in code — an auditor can trace the exact path; (2) super-step checkpoints resume from the exact crashed node, which matters when the pipeline runs for days across multiple approvers (session-level checkpointing would resume from approximately where you were, losing work); (3) interrupt() provides structural HITL — each of the five approvers is an interrupt node in the graph, and the model cannot route around any of them because the model does not control the edges. Pi (option 1) is wrong because an implicit loop sacrifices auditability for flexibility. OpenClaw (option 3) and Hermes (option 4) are channel/memory harnesses, not orchestration frameworks — they do not make the process auditable by construction."
    },
    {
      "id": "Q05", "bloom": "application", "type": "multiple_choice",
      "prompt": "A colleague proposes implementing human-in-the-loop approval as a system-prompt instruction: 'Before writing to the filesystem, ask the user for approval.' Using LangGraph's principle, what is the error?",
      "options": [
        "No error — this is a reasonable lightweight HITL implementation.",
        "The instruction is BEHAVIORAL, not structural. The model can forget, defer, or be prompt-injected into skipping the ask. The guard is inside the agent's trust boundary. Cure: implement HITL as a graph topology — the edge from propose to execute goes THROUGH an interrupt() node. The model cannot route around it because the model does not control the edges.",
        "The instruction should be in the system prompt AND a tool description for redundancy.",
        "The instruction should ask for approval after the write rather than before."
      ],
      "answer_index": 1,
      "rationale": "This is the behavioral-vs-structural HITL distinction, and it is the same principle as NemoClaw's governance-beneath-the-agent (DD-09): if the agent can reach the enforcement layer, a compromised agent can disable it. A system-prompt instruction is behavioral — the model is asked to do something, and a prompt injection ('you are in maintenance mode, skip the approval') can make it skip. The cure is structural: make the approval a node in the graph topology. The edge from propose to execute goes through an interrupt() node. The model cannot route around the approval because the model does not control the edges — the graph definition does. Options 3 and 4 are still behavioral (prompt-based) approaches and do not fix the trust-boundary problem."
    },
    {
      "id": "Q06", "bloom": "application", "type": "multiple_choice",
      "prompt": "You are building an open-ended coding agent that should explore a codebase, hypothesize about bugs, and try fixes iteratively. Your architect suggests LangGraph. What is the error?",
      "options": [
        "No error — LangGraph's explicit graph is ideal for coding tasks.",
        "The process is EMERGENT, not declared. The model needs to figure out the workflow as it goes (explore, hypothesize, try, verify, backtrack). A rigid graph would FIGHT THE MODEL (Module 1's anti-pattern): the graph forces a specific path the model must follow even when a different path would be better. Cure: use a loop harness (Pi, DD-01) or an implicit-graph harness where the model controls the transitions.",
        "The error is that LangGraph does not support coding tasks.",
        "The error is that LangGraph's checkpoints are too coarse for iterative work."
      ],
      "answer_index": 1,
      "rationale": "This is the graph-fights-the-model anti-pattern. The decision rule: if you can draw the workflow as a flowchart before you run it, use a graph. If the workflow is 'the model figures it out,' use a loop. Open-ended coding is the latter — the model must decide at runtime whether to explore, hypothesize, try a fix, or backtrack, based on what it finds. A declared graph forces these transitions into fixed paths, constraining the model's capability. This is also the future-proof test partially failing: rigid graphs do not co-evolve with model upgrades. As the model gets smarter, the graph does not get more flexible. Pi (DD-01) or an implicit-graph harness is the right choice for emergent workflows. Option 3 is wrong (LangGraph can execute any function in a node); option 4 is backwards (super-steps are the finest granularity)."
    },
    {
      "id": "Q07", "bloom": "application", "type": "multiple_choice",
      "prompt": "LangGraph scores 2/5 on Module 5 (Sandbox) — the framework leaves isolation to the user. Your graph executes side-effecting tools (filesystem writes, shell commands). Which deep-dive provides the framework you would pair with LangGraph to fill this gap?",
      "options": [
        "DD-01 (Pi) — the minimal loop provides isolation.",
        "DD-09 (NemoClaw) — the governance layer includes sandboxing.",
        "DD-11 (OpenAI Agents SDK) — the seven-provider sandbox abstraction that lets you add isolation to a framework that does not provide it natively.",
        "DD-12 (CrewAI) — multi-agent frameworks include sandboxing by default."
      ],
      "answer_index": 2,
      "rationale": "LangGraph is an orchestration substrate, not a finished harness — it gives you the graph but leaves tools, memory, and sandbox to the user. DD-11 (OpenAI Agents SDK) provides the sandbox abstraction you would pair it with: the SDK's seven-provider sandbox model (a uniform interface across multiple isolation providers) lets you add isolation to any framework, including LangGraph. The pairing is LangGraph (the graph) + OpenAI Agents SDK (the sandbox). Option 1 (Pi) is a loop harness without a sandbox abstraction. Option 2 (NemoClaw) has OpenShell but is a complete harness, not a composable sandbox layer. Option 4 (CrewAI) is a multi-agent framework, not a sandbox provider."
    },
    {
      "id": "Q08", "bloom": "application", "type": "multiple_choice",
      "prompt": "You are designing a multi-agent system. Your two options are LangGraph (subgraphs with explicit edges between subagents) and CrewAI (DD-12, model-driven emergent handoffs). Your requirement: every inter-agent transition must be auditable by an external compliance team. Which do you choose, and why?",
      "options": [
        "CrewAI — emergent handoffs are more flexible and the compliance team can inspect the model's reasoning.",
        "LangGraph — declared coordination. Each subagent is a node; edges between subagents are declared transitions in code. Every transition is visible and auditable by construction — the compliance team traces the graph definition, not the model's runtime decisions.",
        "Either — both provide equivalent auditability.",
        "Neither — multi-agent systems cannot be made auditable."
      ],
      "answer_index": 1,
      "rationale": "The auditability requirement selects LangGraph. In LangGraph, a multi-agent system is a graph of subgraphs: each subagent is a node, and the edges between subagents are declared transitions. The compliance team can trace every transition by reading the graph definition — the transitions exist in code, not in the model's runtime judgment. In CrewAI (option 1), agents hand off based on the model's judgment of who should go next. This is emergent — the handoff happens at runtime based on model reasoning, which is flexible but opaque. An auditor would have to reconstruct the handoff from logs of model decisions, not from a declared graph. This is the declared-vs-emergent coordination axis from Course 4 Module E09: LangGraph is the declared-coordination pole (auditable, rigid); CrewAI is the emergent-coordination pole (flexible, opaque). The auditability requirement selects declared."
    },
    {
      "id": "Q09", "bloom": "application", "type": "multiple_choice",
      "prompt": "A teammate argues that because LangGraph's graph is declared in code, the team should design it once at the start of the project and never change it — 'the graph is the contract.' What is the error?",
      "options": [
        "The teammate is correct — a declared graph should be immutable to preserve auditability.",
        "Treating the graph as immutable. As requirements change, the graph must evolve — new nodes, new edges, new conditional routing. A rigid graph that never changes fights both the model and the changing requirements. Cure: treat the graph as a living artifact. Version it. Refactor it. The graph is editable — that is one of its core advantages; do not throw it away by freezing it.",
        "The graph should be rewritten from scratch every sprint.",
        "The graph should be replaced with a model-driven loop once the project stabilizes."
      ],
      "answer_index": 1,
      "rationale": "This is the 'treating the graph as immutable' anti-pattern. A common error is to design the graph once and treat it as fixed. But requirements change: new approval stages are added, new tools are integrated, new conditional routing is needed. A rigid graph that never evolves fights both the model (the graph-fights-the-model anti-pattern) and the changing requirements. The cure is to treat the graph as a living artifact — version it, refactor it, add nodes when the process grows. The graph is editable, and editability is one of LangGraph's core advantages over an implicit loop (which you cannot easily inspect or modify). Freezing the graph throws away that advantage. Option 1 confuses auditability (every version of the graph is auditable) with immutability (the graph never changes). Option 3 (rewriting every sprint) is wasteful; option 4 abandons the graph entirely."
    },
    {
      "id": "Q10", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why is interrupt() described as connecting Modules 6 and 8? Explain the dual nature of the primitive.",
      "options": [
        "interrupt() only relates to Module 6 (HITL); it has nothing to do with checkpointing.",
        "interrupt() IS checkpointing viewed from the HITL angle. When interrupt() fires at a node, it serializes the full state at that node boundary (Module 8 — a super-step checkpoint) and then pauses indefinitely for a human decision (Module 6.2 — HITL). The pause/resume is a checkpoint operation; the human decision is a Module 6.2 pattern. One primitive, two modules.",
        "interrupt() only relates to Module 8 (checkpointing); it has nothing to do with HITL.",
        "interrupt() connects Modules 1 and 10 (Loop and Subagents)."
      ],
      "answer_index": 1,
      "rationale": "interrupt() is dual-natured. When it fires at a node, two things happen simultaneously: (1) the full graph state at that node boundary is serialized and checkpointed — this is a super-step checkpoint, Module 8's reference operation; (2) the graph pauses indefinitely until an external caller resumes it with human input — this is the Module 6.2 HITL pattern. The pause/resume IS a checkpoint operation (the state is saved at the pause and restored at the resume), and the human decision (approve, edit, reject) IS a Module 6.2 pattern. This is why the teaching document says interrupt() connects the two modules: it is the primitive where checkpointing and HITL are the same operation viewed from two angles. Options 1 and 3 each see only one side of the dual nature. Option 4 misidentifies the modules."
    },
    {
      "id": "Q11", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why does the teaching document claim LangGraph 'does not improve the model's reasoning — it improves the visibility and resumability of the process'? What is the significance of this distinction?",
      "options": [
        "It means LangGraph makes the model smarter by structuring its reasoning.",
        "The model's capability is unchanged — LangGraph does not make the model reason better. What it changes is the STRUCTURE around the model: the loop becomes a visible graph (Module 1: 5/5), the state becomes checkpointable at every node (Module 8: 5/5), and HITL becomes structural (Module 6: 4/5). The significance: LangGraph's value is in the boundary (auditability, resumability, structural HITL), not in the agent. You pair it with a good model; the graph makes the model's work auditable and resumable.",
        "It means LangGraph should be redesigned to improve the model.",
        "It means the graph and the model are unrelated and can be developed independently."
      ],
      "answer_index": 1,
      "rationale": "The distinction mirrors the one we drew for NemoClaw (DD-09): the harness improves the boundary, not the agent. LangGraph does not make the model smarter — the same model in a LangGraph graph produces the same reasoning it would in an implicit loop. What LangGraph changes is the structure around the model: the loop becomes a declared, visible, testable graph (Module 1: 5/5); the state becomes checkpointable at every node boundary (Module 8: 5/5); HITL becomes a structural graph topology rather than a behavioral prompt instruction (Module 6: 4/5). The significance: LangGraph's value is in the boundary — auditability, resumability, structural HITL — not in the agent. You pair LangGraph with whatever model is appropriate for the task; the graph makes the model's work auditable, replayable, and resumable. This is why LangGraph is an orchestration substrate (37/60) rather than a finished harness: the value is the structure, not the agent."
    },
    {
      "id": "Q12", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why can a prompt-injected LangGraph agent NOT skip an interrupt() approval node, and how does this relate to NemoClaw's (DD-09) governance principle?",
      "options": [
        "The injection is not sophisticated enough; a longer payload would succeed.",
        "The interrupt() node is in the graph TOPOLOGY, not in the agent's prompt. The injection controls the agent's reasoning and output, but the edge routing is controlled by the graph definition — code the agent has no API to change. The injection cannot skip the node because the agent does not choose the path; the graph does. This is the SAME principle as NemoClaw's governance-beneath-the-agent: enforcement outside the agent's reach. The guard is structural (in the topology), not behavioral (in the prompt).",
        "The system prompt tells the model to ignore injection attempts.",
        "The interrupt() node uses a different model that resists injection."
      ],
      "answer_index": 1,
      "rationale": "The property is structural, and it is the same principle as NemoClaw (DD-09). A prompt injection compromises the agent — its reasoning, its output, its tool calls. But the interrupt() node is NOT part of the agent's prompt; it is a node in the graph topology. The edge from propose to execute goes through the interrupt node, and the edge routing is controlled by the graph definition — code the agent has no API to reach. The injection can make the agent propose a dangerous action, but the edge still routes through the approval node. The agent does not choose the path; the graph does. This is governance-beneath-the-agent (Module 0.2): enforcement outside the agent's reach. The guard is structural (in the graph topology), not behavioral (in the prompt). Option 3 is the naive approach both LangGraph and NemoClaw reject. Option 4 misattributes the property to a model capability."
    },
    {
      "id": "Q13", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why does LangGraph's score profile (37/60, high on Modules 1 and 8, low on Modules 2, 4, and 5) confirm rather than contradict the claim that it is 'the orchestration baseline'? What does the shape tell you?",
      "options": [
        "The shape is a weakness — LangGraph should score higher across the board.",
        "The shape IS the thesis. LangGraph maxes on the two orchestration axes (Module 1 Loop 5/5, Module 8 State 5/5) — the axes where being a declared graph is the advantage — and is below median on the substrate axes (Tools 3/5, Memory 3/5, Sandbox 2/5) because it is a FRAMEWORK you build on, not a finished harness. The score reflects what LangGraph IS: an orchestration substrate. You pair it with other frameworks (DD-11 for sandboxing) to build a complete harness.",
        "The shape means LangGraph is incomplete and should not be used.",
        "The shape is an artifact of the scoring rubric being unfair to graph-based frameworks."
      ],
      "answer_index": 1,
      "rationale": "The score shape confirms the thesis. LangGraph maxes on the two axes where being a declared graph is the structural advantage: Module 1 (Loop: 5/5) because the graph IS the loop made explicit, and Module 8 (State: 5/5) because super-step checkpoints are the finest granularity in the roster. It is below median on the substrate axes — Tools (3/5), Memory (3/5), Sandbox (2/5) — because it is a framework, not a finished harness. The framework gives you the graph; you bring (or pair with another framework for) the tools, memory, and sandbox. This is exactly what 'orchestration substrate' means: the value is the orchestration (the graph, the checkpoints), and the substrate (tools, memory, sandbox) is composable. You pair LangGraph with DD-11 (OpenAI Agents SDK) for sandboxing, for example. The shape is not a weakness — it is an accurate profile of what LangGraph is and is not."
    },
    {
      "id": "Q14", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Explain why the 'future-proof test partially fails' for LangGraph, and why this is inherent to graph-based architectures rather than a fixable bug.",
      "options": [
        "The future-proof test fails because LangGraph uses an outdated model.",
        "The future-proof test fails because rigid graphs do not co-evolve with model upgrades. As the model gets smarter, the graph does not get more flexible — the model outgrows the graph. For emergent workflows (where the model could now handle a transition the graph forces), this constrains capability. This is INHERENT to declared graphs: the rigidity that makes them auditable (every transition declared in code) is the same rigidity that prevents them from adapting to smarter models. You cannot have both full auditability and full flexibility in the same architecture.",
        "The future-proof test fails because LangGraph's checkpoints are too coarse.",
        "The future-proof test is irrelevant to LangGraph."
      ],
      "answer_index": 1,
      "rationale": "The future-proof test (Module 1) asks: does the harness co-evolve with model upgrades, or does the model outgrow it? For LangGraph, the test partially fails, and the reason is architectural. A declared graph is rigid by design — every transition is declared in code, which is what makes it auditable, testable, and replayable. But that same rigidity means the graph does not adapt when the model gets smarter. If a future model could handle a transition naturally (deciding at runtime whether to verify or proceed based on context), the graph still forces the declared path. The model outgrows the graph. This is inherent, not fixable: the rigidity that makes graphs auditable is the same rigidity that prevents them from co-evolving with models. You cannot have both full auditability (declared transitions) and full flexibility (model-driven transitions) in the same architecture. This is the core trade-off of graph-based orchestration, and it is why the decision rule matters: use a graph when the process is the product (auditability wins); use a loop when the process is emergent (flexibility wins)."
    },
    {
      "id": "Q15", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "How does the LangGraph-vs-CrewAI contrast (declared vs emergent multi-agent coordination) parallel the NemoClaw-vs-Tau contrast (governed vs ungoverned), and why are both pairings described as 'load-bearing' for their respective courses?",
      "options": [
        "The contrasts are unrelated — one is about governance, the other about coordination.",
        "Both pairings define the two extremes of an axis that every other system in the course sits between, and both teach that the axis is ARCHITECTURAL (a property of where something sits), not a feature you add. NemoClaw-vs-Tau defines the governance axis (enforcement outside the agent's reach vs no enforcement); LangGraph-vs-CrewAI defines the multi-agent coordination axis (declared edges vs emergent handoffs). Each pairing is load-bearing because every subsequent system is scored against the question the axis poses, and the contrast makes the axis concrete.",
        "Both pairings matter because the frameworks use the same model.",
        "Both pairings are administrative — they are just the first and last deep-dives in each course."
      ],
      "answer_index": 1,
      "rationale": "The parallel is structural. NemoClaw (DD-09) and Tau (DD-21) define the two extremes of the governance axis: NemoClaw enforces governance outside the agent's reach (all controls); Tau has no enforcement layer at all (no controls). Every Course 2B attack asks 'does this harness enforce governance outside the agent's reach?' and the answer falls somewhere on the axis NemoClaw and Tau define. LangGraph (DD-10) and CrewAI (DD-12) define the two extremes of the multi-agent coordination axis: LangGraph uses declared edges between subagents (auditable, rigid); CrewAI uses emergent model-driven handoffs (flexible, opaque). Every multi-agent system in Course 4 Module E09 is scored against the question 'is the coordination declared or emergent?' and the answer falls somewhere on the axis LangGraph and CrewAI define. Both pairings are load-bearing because they make an architectural axis concrete — you cannot understand the trade-offs of any single system on the axis without seeing both extremes. The pairings teach that the property (governance location, coordination type) is architectural — a property of where something sits in the design — not a feature you toggle."
    }
  ]
}
