{
  "id": "dd-11-exam",
  "title": "DD-11 OpenAI Agents SDK — 2-Layer Harness/Compute Split",
  "deep_dive": "dd-11-openai-agents-sdk",
  "course": "master-course",
  "duration_minutes": 30,
  "pass_threshold": 0.70,
  "question_count": 15,
  "bloom_distribution": {"recall": 3, "application": 6, "analysis": 6},
  "questions": [
    {
      "id": "q01",
      "bloom": "recall",
      "type": "multiple_choice",
      "prompt": "What is the OpenAI Agents SDK's category, and why does the category matter for how you should use it?",
      "options": [
        "A finished harness — you configure it and run it, like Pi or Claude Code.",
        "An SDK / primitives library — you build the harness WITH it; the value is the architectural defaults it bakes in, not what it does out of the box.",
        "An orchestration framework — you declare the whole graph up front, like LangGraph.",
        "A memory system — you add it to an existing harness for persistent skills, like Hermes."
      ],
      "answer_index": 1,
      "rationale": "The Agents SDK is an SDK / primitives library. Where Pi (DD-01) is a harness you run and Claude Code is a harness you configure, the Agents SDK is a kit you assemble with. Its value is the architectural decisions it bakes in as defaults (2-layer split, 7-provider sandbox, handoffs + agents-as-tools), not what it does out of the box (it does little). You add the operational layers yourself."
    },
    {
      "id": "q02",
      "bloom": "recall",
      "type": "multiple_choice",
      "prompt": "Which list correctly names all 7 sandbox providers in the OpenAI Agents SDK?",
      "options": [
        "local bash, Docker, Kubernetes, AWS Lambda, Azure Functions, GCP Cloud Run, Fly.io",
        "local bash, Docker, E2B, Modal, Daytona, Cloudflare, Vercel",
        "local bash, Docker, Podman, E2B, Modal, Fly.io, Render",
        "local bash, Docker, E2B, Modal, Replit, Deno Deploy, Netlify"
      ],
      "answer_index": 1,
      "rationale": "The 7 providers are: local bash (dev, no isolation), Docker (local/CI, container), E2B (cloud, ephemeral microVM), Modal (serverless cloud), Daytona (dev env provisioning), Cloudflare (edge-proximate), Vercel (serverless, deploy-integrated). Behind a uniform abstraction; swap by config, not code change."
    },
    {
      "id": "q03",
      "bloom": "recall",
      "type": "multiple_choice",
      "prompt": "On which module does the SDK score 5/5, the highest score in the roster on that module?",
      "options": [
        "Module 4 (Memory) — the SDK's self-evolving skill store is the reference.",
        "Module 5 (Sandboxing) — the 7-provider abstraction is the most architecturally thoughtful sandboxing.",
        "Module 9 (Verification) — the SDK's built-in verification gates are first-class.",
        "Module 11 (Observability) — the SDK's built-in tracing covers long runs."
      ],
      "answer_index": 1,
      "rationale": "The SDK scores 5/5 on Module 5 (Sandboxing) — the 7-provider abstraction is the most architecturally thoughtful sandboxing in the roster. The harness code is provider-agnostic. The SDK scores LOW on memory (3/5, bring your own), verification (2/5, you add gates), and observability (2/5, bring your own tracing) — these are the operational layers you add."
    },
    {
      "id": "q04",
      "bloom": "application",
      "type": "multiple_choice",
      "prompt": "You are deploying an Agents SDK harness to production. During development you used local bash. What is the correct action, and why does the SDK architecture make it low-friction?",
      "options": [
        "Keep local bash in production — the SDK's 2-layer split makes it safe regardless of provider.",
        "Switch to an isolation provider (E2B, Docker, Modal) via configuration. The provider-agnostic abstraction means the swap is a config change, not a code change — but the discipline is in not forgetting to switch.",
        "Rewrite the tool code to target E2B directly, since each provider requires its own tool implementation.",
        "Remove the sandbox provider entirely in production — credentials are isolated by the 2-layer split, so sandboxing is unnecessary."
      ],
      "answer_index": 1,
      "rationale": "Local bash in production is the Module 5 footgun — an agent running tools on the host with no isolation. The cure is to switch to an isolation provider (E2B, Docker, Modal) via configuration. The SDK's provider-agnostic abstraction means the swap is a config change, not a code rewrite — the same tool code runs in any regime. The discipline is in gating the provider by environment and not forgetting to switch. The 2-layer split isolates credentials; it does not make the host safe from the sandboxed tool's actions."
    },
    {
      "id": "q05",
      "bloom": "application",
      "type": "multiple_choice",
      "prompt": "A parent agent needs to ask the DB agent a question and then continue orchestrating based on the answer. Which subagent pattern should you use, and why?",
      "options": [
        "Handoffs — transfer control to the DB agent so it owns the task to completion.",
        "Agents-as-tools — call the DB agent like a tool, get a structured result, retain control and continue orchestrating.",
        "Neither — the parent agent should query the database directly to avoid delegation overhead.",
        "Both simultaneously — use a handoff and an agents-as-tools call in parallel for redundancy."
      ],
      "answer_index": 1,
      "rationale": "Agents-as-tools is delegation by query: the parent calls the subagent like a tool, gets a structured result back synchronously, and retains control to continue orchestrating. This is the right pattern when the parent should keep visibility (ask the DB agent a question, continue). Handoffs are for genuine transfer — the DB agent owns the task to completion and the parent stops. The SDK offers both because different tasks need different control models."
    },
    {
      "id": "q06",
      "bloom": "application",
      "type": "multiple_choice",
      "prompt": "You deployed an Agents SDK harness without adding observability/tracing. What failure mode will you hit, and what is the cure?",
      "options": [
        "Credential leaks — the cure is to add a second sandbox provider.",
        "The harness is un-debuggable on long runs — you cannot see the loop steps, handoff routing, or sandbox dispatch. The cure is to add a tracing layer (Module 11) before deploying.",
        "Skills compound poisoning — the cure is to add a write gate.",
        "The sandbox provider abstraction fails — the cure is to hardcode a single provider."
      ],
      "answer_index": 1,
      "rationale": "The SDK scores 2/5 on Module 11 (Observability) — there is no built-in tracing. A harness without observability is un-debuggable on long runs: you cannot see what the loop did, how handoffs were routed, or which sandbox executed which tool. The cure is to add a tracing layer (Module 11) before deploying. This is the first bring-your-own layer to add. The anti-pattern of 'treating the SDK as a finished harness' includes skipping this step."
    },
    {
      "id": "q07",
      "bloom": "application",
      "type": "multiple_choice",
      "prompt": "You want to build a multi-tenant harness where different tenants require different isolation regimes (Tenant A needs E2B microVMs, Tenant B needs Docker containers). How does the SDK's architecture support this?",
      "options": [
        "You must maintain two separate codebases — one per provider — since the SDK is provider-specific.",
        "The provider-agnostic abstraction lets you target each tenant's isolation regime by configuration. The harness code is identical; only the config differs per tenant. This is the architectural payoff of the 7-provider model.",
        "The SDK does not support multi-tenant deployments — you need LangGraph for that.",
        "You must deploy two separate SDK instances on different backends, each hardcoded to one provider."
      ],
      "answer_index": 1,
      "rationale": "The provider-agnostic abstraction is the payoff. The harness code is identical across tenants; only the config differs (Tenant A: provider=E2B, Tenant B: provider=Docker). You write the tool once, target the provider by config. This is why the SDK scores 5/5 on Module 5 — it treats the sandbox as a swappable runtime concern rather than a baked-in deployment decision. This is the use case where the SDK's architecture shines."
    },
    {
      "id": "q08",
      "bloom": "application",
      "type": "multiple_choice",
      "prompt": "A team wants to build a custom harness and is choosing between the Agents SDK and a finished harness like Pi (DD-01). When is the Agents SDK the better choice?",
      "options": [
        "When the team wants a working harness immediately with minimal setup and no custom architecture.",
        "When the team wants the strongest architectural foundation (2-layer split, 7-provider sandbox, both subagent patterns) and is willing to add the operational layers (memory, observability, verification) themselves — especially for multi-tenant or multi-sandbox deployments.",
        "When the team wants maximum ceremony and wants to declare every graph edge up front.",
        "When the team has no need for sandboxing or credential isolation."
      ],
      "answer_index": 1,
      "rationale": "The Agents SDK is the better choice when the team wants the strongest architectural foundation and is willing to add the operational layers. The SDK bakes in the hardest architectural decisions (credential isolation, sandbox portability, subagent delegation) as defaults. You build on it when you want a custom harness — especially for multi-tenant or multi-sandbox deployments where swapping isolation regimes by configuration matters. If you want a working harness immediately with minimal setup, use a finished harness like Pi."
    },
    {
      "id": "q09",
      "bloom": "application",
      "type": "multiple_choice",
      "prompt": "You are using a handoff to delegate a task to a subagent, but you are losing visibility into the task after the handoff — the parent stops and cannot monitor progress. What pattern should you switch to, and why?",
      "options": [
        "Keep the handoff but add more logging to the subagent — the visibility loss is inherent and cannot be fixed.",
        "Switch to agents-as-tools for this task — the parent retains control, calls the subagent like a tool, and can continue orchestrating or monitoring. Use handoffs only for genuine transfer where the parent should stop.",
        "Switch to LangGraph (DD-10) and declare the whole graph to recover visibility.",
        "Remove the delegation entirely — the parent should do all work itself."
      ],
      "answer_index": 1,
      "rationale": "Handoffs are terminal — the parent transfers control and stops, losing visibility. If the parent should retain oversight (monitor progress, continue orchestrating), agents-as-tools is the right pattern: the parent calls the subagent like a tool, gets a structured result, and retains control. The anti-pattern is 'using handoffs when agents-as-tools would preserve visibility.' Default to agents-as-tools for query-style delegation; reserve handoffs for genuine transfer."
    },
    {
      "id": "q10",
      "bloom": "analysis",
      "type": "multiple_choice",
      "prompt": "The SDK's 2-layer split and NemoClaw's (DD-09) governance gate demonstrate the same architectural principle applied to different trust boundaries. What is the shared principle?",
      "options": [
        "Both use a single sandbox provider to isolate the agent from the host.",
        "Both enforce a property by placing the enforcement OUTSIDE the principal's reach — the enforcement lives in a different address space (harness layer), making it structurally unreachable by the principal (agent or sandbox).",
        "Both rely on the model to self-regulate its behavior through prompt engineering.",
        "Both use Docker containers as the primary isolation mechanism."
      ],
      "answer_index": 1,
      "rationale": "The shared principle is 'enforcement outside the principal's reach.' In NemoClaw, the governance gate is outside the agent's reach — the agent cannot bypass the gate because the gate is in the harness layer, beneath the agent. In the SDK, credentials are outside the sandbox's reach — the sandbox cannot access credentials because they live in the harness layer. Both convert a discipline you maintain into a structural property you inherit. The enforcement is in a different address space, making it structurally unreachable. This is the cross-cutting pattern the course wants you to internalize."
    },
    {
      "id": "q11",
      "bloom": "analysis",
      "type": "multiple_choice",
      "prompt": "Why does the SDK score 5/5 on Module 5 (Sandboxing) while OpenCode (DD-03) scores lower, despite both having a client/server or 2-layer split?",
      "options": [
        "The SDK has more GitHub stars than OpenCode.",
        "OpenCode's split enables sandboxing but the sandbox is Docker-or-nothing. The SDK's 7-provider abstraction means one harness runs in 7 isolation regimes without code change — treating the sandbox as a swappable runtime concern, not a baked-in deployment decision. This is the most architecturally thoughtful sandboxing.",
        "OpenCode does not have a client/server split — it is a single-layer harness.",
        "The SDK uses Kubernetes for orchestration, which OpenCode lacks."
      ],
      "answer_index": 1,
      "rationale": "Both have a split, but OpenCode's sandbox is Docker-or-nothing — one isolation regime, baked in. The SDK's 7-provider abstraction means the harness code is provider-agnostic: you write the tool once, target the provider by config, and a single harness runs in 7 different isolation regimes without code change. The SDK treats the sandbox as a swappable runtime concern; OpenCode treats it as a baked-in deployment decision. That abstraction difference is why the SDK scores 5/5 — the highest in the roster."
    },
    {
      "id": "q12",
      "bloom": "analysis",
      "type": "multiple_choice",
      "prompt": "The SDK scores 5/5 on Module 5 and 2/5 on Module 11 (Observability). Why are these two scores 'the same design decision read from two sides'?",
      "options": [
        "Because sandboxing and observability are technically incompatible — you cannot observe a sandboxed agent.",
        "Because the SDK is an SDK, not a finished product: it bakes in the hardest architectural decisions (sandboxing abstraction) as defaults, and leaves the operational layers (observability) to you. The high Module 5 and low Module 11 are the same choice — architecture in, operations out.",
        "Because the SDK team forgot to add observability — it is an oversight, not a design decision.",
        "Because observability requires a sandbox provider, and only 2 of the 7 providers support it."
      ],
      "answer_index": 1,
      "rationale": "The SDK is an SDK, not a finished product. It bakes in the hardest architectural decisions (the 2-layer split, the 7-provider sandbox abstraction, the subagent primitives) as defaults, and leaves the operational layers (memory, observability, verification) to you. The 5/5 on Module 5 and the 2/5 on Module 11 are the same design decision: architecture in, operations out. This is the SDK-specialist shape — you read the score as a profile, not a ranking."
    },
    {
      "id": "q13",
      "bloom": "analysis",
      "type": "multiple_choice",
      "prompt": "Compare the orchestration models of LangGraph (DD-10), the Agents SDK, and Pi (DD-01). Where does the Agents SDK sit, and what is its model called?",
      "options": [
        "LangGraph hand-writes the loop; the SDK declares the whole graph; Pi composes agents.",
        "LangGraph declares the whole graph up front (maximum structure, maximum ceremony); the SDK uses 'declarative-by-composition' — you define agents, the runtime drives the loop (middle of the spectrum); Pi hand-writes the loop (maximum control, maximum effort).",
        "All three use the same orchestration model — the differences are in sandboxing, not orchestration.",
        "The SDK declares the whole graph; LangGraph composes agents; Pi hand-writes the loop."
      ],
      "answer_index": 1,
      "rationale": "The SDK sits in the middle of the orchestration spectrum. LangGraph (DD-10) declares the whole graph up front — nodes, edges, conditional routing (maximum structure, maximum ceremony). Pi (DD-01) hand-writes the loop — you own the ReAct cycle, context, dispatch (maximum control, maximum effort). The Agents SDK uses 'declarative-by-composition' — you define agents (model, instructions, tools, handoff targets), the SDK runtime drives the loop, routes handoffs, dispatches sandboxes. Structure without forcing you to declare every edge."
    },
    {
      "id": "q14",
      "bloom": "analysis",
      "type": "multiple_choice",
      "prompt": "A team argues that because the SDK has a 2-layer split, they can safely use local bash in production — 'credentials are isolated, so the sandbox provider doesn't matter.' What is the flaw in this reasoning?",
      "options": [
        "The reasoning is correct — the 2-layer split makes the sandbox provider irrelevant.",
        "The 2-layer split isolates CREDENTIALS (they cannot cross to the compute layer), but it does not isolate the HOST from the sandboxed tool's actions. Local bash runs tools on the host with no isolation — a malicious or buggy tool can modify or destroy host files. The sandbox provider determines the blast radius of tool actions, which is a separate concern from credential isolation.",
        "The flaw is that local bash does not support handoffs — you must use Docker.",
        "The flaw is that the 2-layer split only works with cloud providers (E2B, Modal), not local bash."
      ],
      "answer_index": 1,
      "rationale": "The 2-layer split isolates credentials — they cannot cross from the harness layer to the compute layer. But the sandbox provider determines the blast radius of tool ACTIONS. Local bash runs tools directly on the host with no isolation — a malicious or buggy tool can read, modify, or destroy host files, escalate privileges, or pivot to network resources. Credential isolation and tool-action isolation are separate concerns. The Module 5 footgun is using local bash in production: credentials are safe, but the host is not. Always match the provider to the deployment's blast-radius tolerance."
    },
    {
      "id": "q15",
      "bloom": "analysis",
      "type": "multiple_choice",
      "prompt": "The course pairs the OpenAI Agents SDK with Codex CLI (DD-04) as 'the OpenAI camp.' What is the axis of contrast between them, and what does it teach about harness design?",
      "options": [
        "Codex CLI scores higher on sandboxing; the SDK scores higher on observability.",
        "Codex CLI is a finished product (you run it); the SDK is primitives (you build with it). The contrast teaches that 'harness' spans a spectrum from finished product to SDK foundation — the right choice depends on whether you want to run a harness or build one. Both are valid OpenAI-camp answers to different problems.",
        "Codex CLI uses handoffs; the SDK uses agents-as-tools — they differ on the subagent pattern.",
        "Codex CLI is for multi-agent; the SDK is for single-agent — they differ on orchestration."
      ],
      "answer_index": 1,
      "rationale": "The axis of contrast is finished-product vs SDK. Codex CLI (DD-04) is a finished product — you install it and run it. The Agents SDK is primitives — you build a harness with it. The contrast teaches that 'harness' spans a spectrum: at one end, a product you run (Pi, Claude Code, Codex CLI); at the other, an SDK foundation you build on (OpenAI Agents SDK). The right choice depends on whether you want to run a harness or build one. Both are valid OpenAI-camp answers to different problems, and the course pairs them to make this spectrum explicit."
    }
  ]
}
