{
  "module": "SDD-B05 — IronCurtain Offensive Analysis",
  "course": "2B — Securing & Attacking Harnesses and LLMs",
  "version": "1.0.0",
  "duration_minutes": 30,
  "total_questions": 15,
  "bloom_distribution": {
    "target": "20% recall / 40% application / 40% analysis-design",
    "actual": { "recall": 3, "application": 6, "analysis": 6 }
  },
  "passing_score_percent": 70,
  "questions": [
    {
      "id": "Q01", "bloom": "recall", "type": "multiple_choice",
      "prompt": "IronCurtain's central thesis is 'the agent is untrusted; security does not depend on the model being good.' If IronCurtain has no runtime LLM judge, where does the attack surface live?",
      "options": [
        "There is no attack surface — IronCurtain is unbreakable.",
        "Three surfaces, each a structural property of the deterministic design: (1) compilation fidelity (a probabilistic LLM compiles the deterministic rules at build time); (2) the V8 isolate boundary (the credential quarantine depends on it holding); (3) escalation fatigue (the human-in-the-loop can be fatigued). The runtime enforcement engine itself has no surface — pure if/then cannot be injected.",
        "Only in the network egress controls.",
        "Only in the audit log, which can be tampered with."
      ],
      "answer_index": 1,
      "rationale": "The LLM was not eliminated; it was relocated to build time. The compilation pipeline is all LLM calls. The runtime engine (pure if/then JSON rule eval) genuinely has no semantic surface — you cannot inject an if-statement. The surfaces are everything around the runtime: the build-time compilation, the isolate boundary, and the escalation channel."
    },
    {
      "id": "Q02", "bloom": "recall", "type": "multiple_choice",
      "prompt": "What does it mean that 'the LLM was not eliminated, it was relocated'?",
      "options": [
        "IronCurtain uses a smaller LLM than CrabTrap.",
        "IronCurtain removes the LLM from RUNTIME (deterministic if/then enforcement, zero LLM) but the compilation pipeline (Annotate, Compile, Resolve Lists, Generate Scenarios, Verify & Repair) is ALL LLM calls at BUILD time. The probabilistic component was concentrated in the compilation step. A miscompilation is baked into the deterministic runtime and enforced CONSISTENTLY — predictable enforcement of potentially-wrong rules.",
        "IronCurtain runs the LLM on a separate server.",
        "IronCurtain encrypts the LLM so the agent cannot reach it."
      ],
      "answer_index": 1,
      "rationale": "This is the structural insight of B05.1. The deterministic thesis is correct about runtime — there is no judge to inject. But it is incomplete about build time: the compilation is itself probabilistic. Relocating the LLM concentrates the risk in a single step (compilation) rather than distributing it across runtime requests. The runtime is safe; the build is the new surface."
    },
    {
      "id": "Q03", "bloom": "recall", "type": "multiple_choice",
      "prompt": "How does IronCurtain's credential quarantine work, and on what does its integrity depend?",
      "options": [
        "It encrypts the real keys with a password only the human knows.",
        "The agent is configured with FAKE API keys. A TLS-terminating MITM proxy hot-swaps fake→real at the boundary before forwarding to the provider, and scrubs key reflection from responses. The agent never sees a real credential. Its integrity depends ENTIRELY on the V8 isolate holding — the agent cannot reach the proxy's host process (where real keys live) unless it escapes the isolate.",
        "It stores the real keys in a hardware token the agent cannot access.",
        "It rotates the keys every 60 seconds so a compromised agent never has time to exfiltrate."
      ],
      "answer_index": 1,
      "rationale": "The quarantine is the strongest primitive in the course. But it is one memory-corruption bug from defeat: the isolation between the agent's execution environment (the isolate) and the proxy's (the host process) is the only thing preventing a compromised agent from reaching the real keys. This is Break 2's structural dependence — the quarantine holds only as long as the isolate does."
    },
    {
      "id": "Q04", "bloom": "application", "type": "multiple_choice",
      "prompt": "You want to execute the compilation-fidelity attack (Break 1). You can influence a resolved list that the compilation uses. Which vector is this, and what is the attack?",
      "options": [
        "Constitution ambiguity — rewrite the constitution to be more permissive.",
        "Resolved-list poisoning — add an attacker-controlled domain to @trusted-endpoints, or omit the target action from @sensitive-ops. The poisoning is baked into compiled-policy.json and enforced deterministically, consistently, every time. Verify-and-repair may not catch it if the scenario set does not exercise the poisoned entry.",
        "Scenario coverage gap — remove scenarios from the test set.",
        "Escalation fatigue — flood the list-resolution step with requests."
      ],
      "answer_index": 1,
      "rationale": "The Resolve Lists stage turns @list-name symbols into concrete values via LLM knowledge or MCP tool-use. An attacker who can influence a resolved list (trusted endpoints, sensitive operations) bakes the poisoning into the deterministic policy. This is one of three Break 1 vectors; the others are constitution ambiguity and scenario coverage gaps. The measurement is the compilation-fidelity drift rate over a fuzz harness."
    },
    {
      "id": "Q05", "bloom": "application", "type": "multiple_choice",
      "prompt": "You run a compilation-fidelity fuzz harness: 500 fuzzed constitution variants, 11 produce a compiled policy that permits the target exfil action the un-fuzzed constitution denies. What is the drift rate, and what does it mean?",
      "options": [
        "11% — IronCurtain is broken and must be removed.",
        "2.2% (11/500) — the compilation-fidelity drift rate. Verify-and-repair catches ~98% of miscompilations; the 2.2% residual is the build-time analogue of the InjecAgent runtime delta. It is an honest effectiveness claim about the compilation step, measured. The B05.3 prescription (human review gate) is designed to catch this residual.",
        "500 — the number of tests that passed.",
        "0% — because verify-and-repair caught everything."
      ],
      "answer_index": 1,
      "rationale": "The drift rate is the measured effectiveness claim for Break 1, exactly analogous to how InjecAgent measures runtime injection rates. 11/500 = 2.2%. A low rate means verify-and-repair is working; a high rate means it is not. The residual is real and expected — the prescription adds a human review of the compiled policy before deploy to catch what the verifying LLM agreed with. No delta, no finding."
    },
    {
      "id": "Q06", "bloom": "application", "type": "multiple_choice",
      "prompt": "An attacker wants to exploit escalation fatigue (Break 3). Which tactic generates contextual fatigue, and why does it work?",
      "options": [
        "Send many escalations in a short window to overwhelm the human with volume.",
        "Generate escalations that are similar but not identical to previously-approved calls. The human, having approved the similar call, approves the new one by analogy — without noticing the difference that makes it an attack. This is the semantic analogue of the SDD-B04 allowlist-widening pattern.",
        "Send escalations at 3am when the human is asleep.",
        "Disable the auto-approver so everything escalates."
      ],
      "answer_index": 1,
      "rationale": "Contextual fatigue exploits the human's pattern-matching. A call that looks like a previously-approved call is approved by analogy, missing the small difference that makes it an attack. Volume fatigue (option A) and timing fatigue (option C) are the other two patterns. The measurement is a fatigue simulator: approval-rate delta rested vs fatigued."
    },
    {
      "id": "Q07", "bloom": "application", "type": "multiple_choice",
      "prompt": "Your engagement discovers IronCurtain's deployed V8 version has a known isolate-escape CVE. How do you frame this finding, and what is the prescription?",
      "options": [
        "IronCurtain is broken; replace it with CrabTrap.",
        "This is Break 2 — the V8 isolate boundary. The credential quarantine holds only as long as the isolate does; a known escape CVE means the quarantine is one exploit from defeat. This is a dependency-CVE audit finding (like SDD-B04's configuration-drift audit). The prescription is sandbox defense-in-depth: layer isolate (inner) → seccomp/capability (middle) → egress controls (outer), so an escape defeats 3 layers, not 1. Also: update the V8 version immediately.",
        "Ignore it — V8 escapes are too hard to exploit.",
        "Disable Code Mode and only use Docker Agent Mode."
      ],
      "answer_index": 1,
      "rationale": "Break 2 is an escape-path analysis, not a constructed exploit. The measurement is a dependency-CVE audit: is the deployed version current, are there known escape CVEs. The honest framing is structural dependence — the quarantine is one memory-corruption bug from defeat. The prescription treats the isolate as one layer among several, not the load-bearing boundary. Updating V8 is the immediate fix; layering is the durable one."
    },
    {
      "id": "Q08", "bloom": "application", "type": "multiple_choice",
      "prompt": "Why does verify-and-repair NOT catch a compilation-fidelity miscompilation where the verifying LLM agrees with the error?",
      "options": [
        "Because verify-and-repair is disabled by default.",
        "Because verify-and-repair is a SECOND LLM checking the FIRST. If the miscompilation is a permissive interpretation of an ambiguous clause, and the verifying LLM shares the same interpretive tendency, it AGREES with the error. Two probabilistic systems agreeing is NOT a deterministic guarantee. The defense catches naive miscompilations (rules that obviously contradict the constitution) but not the residual where the verifier concurs.",
        "Because verify-and-repair only runs once, not twice.",
        "Because verify-and-repair checks syntax, not semantics."
      ],
      "answer_index": 1,
      "rationale": "Verify-and-repair mitigates but does not eliminate. It is a real defense — it catches many miscompilations via the scenario test cases. But the residual is the case where the verifying LLM's interpretation matches the compiling LLM's error. This is why B05.3's Layer 1 adds a HUMAN review of the compiled policy — the human catches what the second LLM missed."
    },
    {
      "id": "Q09", "bloom": "application", "type": "multiple_choice",
      "prompt": "You build an escalation-fatigue simulator. Rested baseline: attacker-intended actions approved at 4%. Under volume fatigue (50 escalations/hour): 31%. What does this delta mean, and what controls address it?",
      "options": [
        "The simulator is buggy — humans never approve at 31%.",
        "The delta (4%→31%) is the honest measurement of the escalation-fatigue surface. A defense expensive to honor (in human attention) is a defense the human defeats. Partial controls: rate-limiting (cap escalations/hour; deny-by-default above), smart batching (evaluate one representative call, not 20 near-duplicates), two-person rule for high-impact allows. None eliminates — the human is irreducibly probabilistic.",
        "IronCurtain should remove the escalation mechanism entirely.",
        "The auto-approver should handle all cases, removing the human."
      ],
      "answer_index": 1,
      "rationale": "The fatigue simulator measures what a rested-baseline test cannot — the degradation under load. The 4%→31% delta is the surface, measured. The controls (rate-limiting, batching, two-person rule) bound the residual but do not eliminate it, because the human is the irreducible probabilistic component in a deterministic system that escalates edge cases."
    },
    {
      "id": "Q10", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why is the compilation-fidelity break the load-bearing break among IronCurtain's three surfaces?",
      "options": [
        "Because it is the easiest to execute.",
        "Because it is the ONLY place a probabilistic system touches the deterministic enforcement. The runtime engine has no surface (pure if/then), and the isolate and escalation surfaces are boundaries around the runtime — but the compiled policy IS what the runtime enforces. A miscompilation becomes the deterministic truth. Everything else (the isolate holding, the human approving carefully) assumes the compiled policy is correct. Break 1 attacks that assumption at its root.",
        "Because it requires the most GPU compute.",
        "Because it is the only break that works against Docker Agent Mode."
      ],
      "answer_index": 1,
      "rationale": "The runtime enforcement engine is the part of IronCurtain with no attack surface — but it enforces whatever the compilation produced. The compilation is the single probabilistic input to the deterministic runtime. If the compilation is wrong, the runtime faithfully enforces the wrong rule. The isolate and escalation surfaces are real, but they are boundaries around a runtime that is only as correct as its compiled policy."
    },
    {
      "id": "Q11", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why does the B05.3 prescription add a probabilistic second layer (Layer 4) when SDD-B04 showed the LLM-as-judge is injectable?",
      "options": [
        "Because the deterministic layer is too slow.",
        "Because of POSITIONING. In SDD-B04, the judge was the PRIMARY surface — every novel request reached it. In B05.3, the judge is positioned AFTER the deterministic layer and handles only the ESCALATED subset (ambiguous cases the deterministic rules cannot resolve). The judge's injectability becomes a RESIDUAL on the small escalated subset, not the primary surface — and the human still reviews high-impact decisions. The deterministic layer handles the bulk with zero injectability.",
        "Because the client demanded an LLM in the architecture.",
        "Because IronCurtain requires an LLM to function."
      ],
      "answer_index": 1,
      "rationale": "Layering changes the role of the judge. As the primary surface (SDD-B04 CrabTrap), its injectability is the main attack vector. As a second layer after deterministic enforcement (B05.3), its injectability is a bounded residual on the subset the deterministic layer escalates. The deterministic layer handles the high-volume, clearly-decidable traffic with no judge at all; the judge adds semantic flexibility only where rules are ambiguous. This is defense-in-depth — each layer's weakness is bounded by the others."
    },
    {
      "id": "Q12", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "How does SDD-B05 complete the argument that SDD-B03 and SDD-B04 began about defense-in-depth?",
      "options": [
        "It shows IronCurtain is the only defense you need.",
        "SDD-B03 MEASURED that layered defenses reach single-digit injection rates where single defenses sit near baseline. SDD-B04 DEMONSTRATED that CrabTrap alone has residuals and prescribed the deterministic-first fix (IronCurtain). SDD-B05 COMPLETES it: even IronCurtain, the strongest single defense, has its own residuals (compilation fidelity, isolate boundary, escalation fatigue) — structural properties of any single-layer defense. The conclusion: the only complete answer is LAYERS. No single layer suffices.",
        "It proves defense-in-depth is unnecessary.",
        "It shows all defenses are equally effective."
      ],
      "answer_index": 1,
      "rationale": "This is the throughline of the course. B2's thesis is that defense-in-depth is a structural necessity, not a best practice. SDD-B03 provides the measurement. SDD-B04 provides the first demonstration (a probabilistic defense with residuals). SDD-B05 provides the clincher: even the strongest deterministic defense has residuals. The residuals are not bugs — they are structural. Therefore layers, always."
    },
    {
      "id": "Q13", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "An attacker cannot break IronCurtain's compilation (verify-and-repair holds) and cannot escape the isolate (V8 is current). How might they still get a disallowed action through via escalation fatigue?",
      "options": [
        "They cannot — if compilation and isolate hold, IronCurtain is secure.",
        "Via contextual fatigue (Break 3): generate tool calls that are ambiguous under the compiled policy (forcing escalation) but similar to previously-approved calls. The human, under volume and pattern-matching pressure, approves the new call by analogy — missing the difference that makes it an attack. The deterministic engine delegated the decision to a fatigued human. Rate-limiting and batching bound this but do not eliminate it.",
        "By rewriting the constitution during runtime.",
        "By disabling the auto-approver through a bug."
      ],
      "answer_index": 1,
      "rationale": "Escalation fatigue is the third surface and it does not require breaking compilation or the isolate. The attacker exploits the human's decision-making under load. Contextual fatigue is the semantic analogue of the allowlist-widening pattern — the human widens their internal 'approved' pattern to include the attack. This is why rate-limiting, batching, and the two-person rule are in the prescription: they bound the residual without eliminating the human (who is irreducibly probabilistic)."
    },
    {
      "id": "Q14", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Why is the V8 isolate break (Break 2) measured as a dependency-CVE audit rather than an InjecAgent delta?",
      "options": [
        "Because InjecAgent cannot measure sandbox escapes.",
        "Because the escape depends on a SPECIFIC V8 version and a SPECIFIC bug — it is a zero-day with a short shelf life, not a reproducible attack pattern. The course does not teach V8 exploitation. The measurement that matters for an engagement is the dependency-CVE audit: is the deployed V8/isolated-vm version current? Are there known escape CVEs? This is the same class of finding as SDD-B04's configuration-drift audit — an audit, not a benchmark number.",
        "Because V8 escapes are impossible.",
        "Because the isolate is not part of IronCurtain."
      ],
      "answer_index": 1,
      "rationale": "Break 2 is an escape-path analysis, not a constructed exploit. The structural finding is the dependence: the quarantine holds only as long as the isolate does. The engagement measurement is whether the deployed version is vulnerable (audit), not a success rate over N attempts (benchmark). The prescription (sandbox defense-in-depth) treats the isolate as one layer among several precisely because no single version is guaranteed escape-free forever."
    },
    {
      "id": "Q15", "bloom": "analysis", "type": "multiple_choice",
      "prompt": "Design the four-layer prescription a B12 engagement would deliver for a client relying on IronCurtain alone. What are the layers, and which residual does each address?",
      "options": [
        "Replace IronCurtain with CrabTrap, then add a firewall, then add encryption, then add logging.",
        "(1) HUMAN REVIEW GATE — review compiled-policy.json before deploy, diff vs last-reviewed; addresses compilation fidelity (the residual verify-and-repair agreed with). (2) SANDBOX DEFENSE-IN-DEPTH — isolate→seccomp/capability→egress controls; addresses the V8 isolate boundary (escape defeats 3 layers). (3) ESCALATION RATE-LIMITING — cap/hour + batching + two-person rule; addresses escalation fatigue (bounded residual). (4) PROBABILISTIC SECOND LAYER — LLM-as-judge for escalated cases only, after deterministic; handles ambiguous cases without making the judge the primary surface.",
        "Remove the deterministic runtime and use only an LLM judge.",
        "Disable escalation and auto-approve everything."
      ],
      "answer_index": 1,
      "rationale": "The prescription keeps the deterministic runtime (the strongest single layer) and addresses each residual with a dedicated layer. Human review catches compilation fidelity (build-time). Sandbox defense-in-depth contains the isolate boundary (runtime). Rate-limiting bounds escalation fatigue (human). The probabilistic second layer handles the ambiguous subset the deterministic layer escalates, without reintroducing the judge as the primary surface (SDD-B04's mistake). Each layer addresses a residual the others leave — this is defense-in-depth."
    }
  ]
}
