{
  "module": "7 — Error Handling & Recovery",
  "course": "Master Course — Harness Engineering",
  "version": "1.0.0", "duration_minutes": 30, "total_questions": 12,
  "bloom_distribution": { "target": "20% recall / 40% application / 40% analysis", "actual": { "recall": 3, "application": 5, "analysis": 4 } },
  "passing_score_percent": 70,
  "questions": [
    { "id": "Q01", "bloom": "recall", "type": "multiple_choice", "prompt": "Name the 4 error categories and responses.", "options": ["Low/medium/high/critical", "Transient (retry) · LLM-recoverable (self-correct) · User-fixable (interrupt) · Fatal (halt)", "Retry/log/abort/ignore", "1/2/3/4"], "answer_index": 1, "rationale": "The taxonomy. Each category has a specific correct response. Misclassify → wrong response." },
    { "id": "Q02", "bloom": "recall", "type": "multiple_choice", "prompt": "10-step process at 99% per-step = ?% end-to-end.", "options": ["99%", "~90%", "50%", "100%"], "answer_index": 1, "rationale": "0.99^10 ≈ 0.90. At 50 steps, ~60%. Error rates compound multiplicatively — error handling determines whether the agent ships." },
    { "id": "Q03", "bloom": "recall", "type": "multiple_choice", "prompt": "What is the circuit breaker?", "options": ["A fuse in the datacenter", "Disable the failing tool for the session after N consecutive failures (stuck-loop). Model cannot call it again.", "A retry limit", "An error message"], "answer_index": 1, "rationale": "Tool-level realization of the error-threshold stop (Module 1.2). Prevents one misbehaving tool from trapping the agent." },
    { "id": "Q04", "bloom": "application", "type": "multiple_choice", "prompt": "A tool returns 503 (service unavailable). Category + response?", "options": ["Fatal — halt", "Transient — retry with exponential backoff + jitter, cap at 2 (Stripe). If still failing, escalate to LLM-recoverable.", "User-fixable — interrupt", "LLM-recoverable — return to model"], "answer_index": 1, "rationale": "503 is the canonical transient error. Backoff+jitter, cap 2. Beyond 2, it's likely not transient — escalate." },
    { "id": "Q05", "bloom": "application", "type": "multiple_choice", "prompt": "Model calls read_file with a nonexistent path. Category + response?", "options": ["Transient — retry", "LLM-recoverable — return precise error ('path not found') as tool result. Model self-corrects next turn.", "Fatal — halt", "User-fixable — interrupt"], "answer_index": 1, "rationale": "Wrong path is a model mistake. The error as tool result lets the model try a different path. Retrying the same path = stuck loop." },
    { "id": "Q06", "bloom": "application", "type": "multiple_choice", "prompt": "Budget exhausted at step 15 of 30. Is this a failure?", "options": ["Yes — abort everything", "No — a planned stop. Save state (checkpoint), exit cleanly, write handoff. Continuation session resumes at 15.", "Yes — retry", "Ask the user"], "answer_index": 1, "rationale": "Budget exhaustion is expected behavior, not a failure. Graceful degradation: checkpoint + handoff so a new session resumes." },
    { "id": "Q07", "bloom": "application", "type": "multiple_choice", "prompt": "Model calls the same failing tool 5 times with identical input. What fires?", "options": ["Nothing — normal", "Stuck-loop detection (same input_hash + output_hash x N). Circuit breaker trips; tool disabled for session.", "The budget check", "The permission gate"], "answer_index": 1, "rationale": "Same input + same output = no progress. The detector (Module 1.4 hashes) catches it; the circuit breaker disables the tool." },
    { "id": "Q08", "bloom": "analysis", "type": "multiple_choice", "prompt": "Anti-pattern: 'retry everything.' Why does it fail?", "options": ["Retries are slow", "A FATAL error retried forever consumes the entire budget (infinite loop). Cure: the taxonomy — fatal halts, doesn't retry.", "Retries use too many tokens", "The model gets confused"], "answer_index": 1, "rationale": "The danger of no taxonomy. Fatal errors are unrecoverable; retrying them is guaranteed to fail and burns all resources. The taxonomy distinguishes retryable from not." },
    { "id": "Q09", "bloom": "analysis", "type": "multiple_choice", "prompt": "Why cap transient retries at 2 (Stripe)?", "options": ["2 is a lucky number", "Beyond 2, the error is likely not transient. Further retries waste budget. Cap at 2, then escalate to LLM-recoverable (model self-corrects).", "The API limits it", "More retries are slower"], "answer_index": 1, "rationale": "If a transient error persists past 2 retries, it's probably not transient (could be LLM-recoverable or fatal). Escalate rather than waste budget." },
    { "id": "Q10", "bloom": "analysis", "type": "multiple_choice", "prompt": "Why is partial completion better than full abort?", "options": ["It's faster", "Partial preserves the value created (steps 1-12). Full abort loses everything. The human gets 12 steps of value + a clear next action.", "It uses fewer tokens", "The model prefers it"], "answer_index": 1, "rationale": "Value preservation. Silent failure loses all value; full abort loses completed work; partial completion keeps what was done and reports what remains." },
    { "id": "Q11", "bloom": "analysis", "type": "multiple_choice", "prompt": "Why does the stuck-loop detector use hashes, not full content?", "options": ["Hashes are newer", "Cheap, comparable, privacy-safe (Module 1.4). Same hash = same content. Full content comparison is expensive and may expose secrets in logs.", "Hashes are more accurate", "Full content is illegal"], "answer_index": 1, "rationale": "Same engineering reason as Module 1.4's payload design. Hashes give the 'no progress' signal without the cost or risk of full-content comparison." },
    { "id": "Q12", "bloom": "analysis", "type": "multiple_choice", "prompt": "Anti-pattern: 'swallow everything' (silent failure). What goes wrong?", "options": ["Nothing — silence is safe", "The model gets NO error feedback → hallucinates success. State corruption. Cure: return errors as structured tool results (Module 2.2).", "The user gets confused", "The log fills up"], "answer_index": 1, "rationale": "The opposite anti-pattern from 'retry everything.' Without error feedback, the model assumes success and proceeds on a false premise. Structured errors (Module 2.2) are the cure." }
  ]
}
