How quiz.json Question Schemas Work for Pre, Check, and Post Stages

TLDR: The quiz.json files in rohitg00/ai-engineering-from-scratch use a strict schema where each question includes a stage field set to pre, check, or post, determining whether it appears before, during, or after lesson content, with exactly six questions required per lesson (1 pre, 3 check, 2 post).

The rohitg00/ai-engineering-from-scratch repository structures interactive learning through lesson-specific quiz.json files that follow a rigid schema defined in AGENTS.md. Each file contains exactly six questions distributed across three lifecycle stages to optimize knowledge retention. Understanding how these pre, check, and post stages function within the quiz.json question schema is essential for lesson authors and contributors.

The quiz.json Schema Structure

Each lesson stores its interactive assessment in a quiz.json file located in the lesson folder, such as phases/01-math-foundations/10-dimensionality-reduction/quiz.json. The top-level questions array contains objects with specific required fields that control presentation and validation.

Required Fields

Every question object must include these five keys:

  • stage – One of pre, check, or post
  • question – The text displayed to the learner
  • options – Array of exactly four answer strings
  • correct – Zero-based index (0-3) of the correct option
  • explanation – Rationale shown after the learner submits an answer

Stage Property Values

The stage field determines when the question appears in the lesson lifecycle:

  • pre – Assessment of prior knowledge presented before lesson content loads
  • check – Formative check interleaved during the lesson after concept introduction
  • post – Consolidation question displayed after the lesson code finishes execution

Stage Distribution Rules

The curriculum enforces a fixed count of exactly six questions per lesson. The distribution must follow this strict pattern:

Stage Required Count
pre 1
check 3
post 2

If audit_lessons.py detects any deviation from this distribution during CI, the build fails immediately. This constraint ensures consistent learning flow across all lessons in the repository.

How the Lesson Runner Processes Stages

When the lesson runner starts (via code/main.*), it loads the sibling quiz.json using pathlib:

import json, pathlib
quiz_path = pathlib.Path(__file__).with_name('quiz.json')
quiz = json.load(open(quiz_path))['questions']

The runner then partitions the questions by stage using list comprehensions:

pre_q   = [q for q in quiz if q['stage'] == 'pre']
check_q = [q for q in quiz if q['stage'] == 'check']
post_q  = [q for q in quiz if q['stage'] == 'post']

These groups are presented at specific lifecycle moments. The pre-stage question appears immediately before content, check-stage questions are inserted after key concept blocks (determined by the lesson author), and post-stage questions display after execution completes.

Validation and CI Enforcement

The scripts/audit_lessons.py script validates every quiz.json in the repository. It verifies that:

  • Exactly one pre question exists
  • Exactly three check questions exist
  • Exactly two post questions exist
  • The correct index is within range [0, 3]

If validation fails, the runner aborts with a clear error, preventing broken lessons from reaching learners.

Summary

  • The quiz.json schema requires exactly six questions per lesson with a fixed distribution: 1 pre, 3 check, and 2 post
  • Stages control timing: pre (before), check (during), and post (after)
  • The correct field uses zero-based indexing (0-3) to map directly to Python list indices
  • CI validation via audit_lessons.py enforces schema compliance before deployment
  • The lesson runner partitions questions by stage after loading from the lesson directory

Frequently Asked Questions

What is the purpose of the pre stage in quiz.json?

The pre stage assesses prior knowledge before the learner encounters new lesson content. According to the AGENTS.md specification, this placement helps identify knowledge gaps and primes the learner for the upcoming concepts.

How many questions are required for each stage?

The schema mandates exactly six questions total: one pre question, three check questions, and two post questions. This fixed distribution is enforced by the audit_lessons.py CI script.

What happens if the quiz.json schema is violated?

The lesson runner validates counts upon loading and aborts with a clear error if the stage distribution is incorrect. Additionally, the CI pipeline fails if audit_lessons.py detects any deviation from the six-question rule or invalid correct indices.

How is the correct answer index stored?

The correct field stores a zero-based integer between 0 and 3, where 0 corresponds to the first option in the options array. This design treats the value directly as a Python list index in the runner implementation.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →