# Lesson Contract for Contributing New Lessons to the AI Engineering Curriculum

> Discover the lesson contract for AI Engineering From Scratch. Learn the three-part specification for new lessons: structured docs, a six-question quiz, and runnable code with unit tests.

- Repository: [Rohit Ghumare/ai-engineering-from-scratch](https://github.com/rohitg00/ai-engineering-from-scratch)
- Tags: how-to-guide
- Published: 2026-06-16

---

**The lesson contract is a strict three-part specification defined in [`AGENTS.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/AGENTS.md) that requires every new lesson to include structured front-matter documentation, a standardized six-question quiz, and runnable code with at least five unit tests.**

The rohitg00/ai-engineering-from-scratch repository maintains a rigorous lesson contract to ensure all contributions integrate seamlessly with automated CI pipelines and render correctly on the generated site. This contract governs everything from markdown metadata to testing requirements, creating a predictable structure that validators like [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) can automatically verify. Understanding these requirements is essential before submitting a new lesson to the curriculum.

## What Is the Lesson Contract?

The lesson contract is the canonical specification stored in the repository's **AGENTS.md** file that defines exactly how new educational content must be structured. It ensures that every lesson can be built, tested, and displayed automatically without manual intervention. The contract is enforced by continuous integration scripts, specifically [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) and [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js), which validate each lesson against the specification before accepting contributions.

## The Three Contract Requirements

Every new lesson must satisfy three distinct structural requirements to pass automated validation.

### 1. Structured Documentation in [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md)

Each lesson requires a markdown file with a fixed front-matter header block that defines metadata fields including the lesson title, hook, type, languages, prerequisites, estimated time, and learning objectives. The **Languages** field must exactly match the language(s) for which a `main.*` file exists in the `code/` directory. This metadata enables the site generator to index content correctly and establish prerequisite chains between lessons.

Example front-matter structure:

```markdown

# My New Lesson Title

> One-line hook that captures the essence of the lesson

**Type:** Build  
**Languages:** python  
**Prerequisites:** 01-intro-to-linear-algebra, 02-numpy-basics  
**Time:** ~30

## Learning Objectives

- Implement the algorithm from first principles
- Write unit tests covering edge cases
- Explain the mathematical intuition behind each step

```

### 2. Standardized Assessment Schema ([`quiz.json`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/quiz.json))

The contract mandates a strict JSON schema for assessments containing exactly **six questions**: one pre-assessment, three checkpoint questions, and two post-assessment items. The JSON object must include `lesson`, `title`, and a `questions` array where each entry contains `stage`, `question`, `options`, `correct` (zero-based index), and `explanation`. The site renderer strictly expects this shape, and any deviation will break the UI.

Example [`quiz.json`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/quiz.json) structure:

```json
{
  "lesson": "my-new-lesson",
  "title": "My New Lesson Title",
  "questions": [
    {"stage":"pre","question":"What is the purpose of X?","options":["A","B","C","D"],"correct":0,"explanation":""},
    {"stage":"check","question":"Which of these statements is true?","options":["A","B","C","D"],"correct":1,"explanation":""},
    {"stage":"check","question":"Select the correct output for Y.","options":["A","B","C","D"],"correct":2,"explanation":""},
    {"stage":"check","question":"What does function Z return?","options":["A","B","C","D"],"correct":1,"explanation":""},
    {"stage":"post","question":"How would you modify the algorithm to handle edge case E?","options":["A","B","C","D"],"correct":3,"explanation":""},
    {"stage":"post","question":"Which library provides the most efficient implementation?","options":["A","B","C","D"],"correct":0,"explanation":""}
  ]
}

```

### 3. Runnable Implementation and Testing (`code/`)

The `code/` directory must contain three specific components:

- **A runnable implementation** (`main.<lang>`) that terminates cleanly and exits with status 0
- **A 4-6 line header comment** citing the lesson's [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) path and any external specifications
- **A `code/tests/` folder** with at least five unit tests executable via the language's standard test runner (e.g., `python3 -m unittest discover`)

Example implementation header:

```python

# docs/en.md: https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/phases/XX-phase/YY-lesson/docs/en.md

# Implements the core algorithm described in the lesson.

def compute(...):
    # ... algorithm implementation ...

if __name__ == "__main__":
    print(compute(...))

```

Example test structure:

```python
import unittest
from main import compute

class TestCompute(unittest.TestCase):
    def test_basic(self):
        self.assertEqual(compute(...), ...)

    # add at least four more test cases covering edge cases …

if __name__ == "__main__":
    unittest.main()

```

## CI Validation and Automated Enforcement

The contract is not merely advisory; it is enforced by automated tooling. The [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) script validates every lesson against the contract requirements, checking for the presence of [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md), valid [`quiz.json`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/quiz.json) syntax, and proper test coverage in `code/tests/`. Meanwhile, [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js) generates the public site data from [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md), [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md), and [`glossary/terms.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/glossary/terms.md), expecting the strict directory structure defined in the contract. Violating any part of the contract will cause CI failures or broken links in the generated site.

Contributors can reference **LESSON_TEMPLATE.md** for boilerplate scaffolding that includes the correct folder structure and placeholder files, ensuring compliance from the initial commit.

## Summary

- The lesson contract is defined in [`AGENTS.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/AGENTS.md) and enforced by [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) and [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js) according to the rohitg00/ai-engineering-from-scratch source code.
- Every lesson requires three components: a [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) file with fixed front-matter, a [`quiz.json`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/quiz.json) with exactly six questions (1 pre, 3 check, 2 post), and a `code/` directory with a runnable `main.*` file and at least five unit tests.
- The **Languages** field in [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) must match the `main.*` file extensions present in `code/`.
- All implementations must include a 4-6 line header comment referencing the lesson documentation path.
- Use [`LESSON_TEMPLATE.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/LESSON_TEMPLATE.md) as a starting scaffold to ensure compliance with the curriculum standards.

## Frequently Asked Questions

### What happens if my quiz.json doesn't have exactly six questions?

The site renderer expects exactly six questions following the specific distribution (one pre, three check, two post). Any deviation from this schema will cause the UI to break and the CI pipeline to reject your contribution via [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py).

### Can I use languages other than Python for the code implementation?

Yes, the contract supports multiple languages as long as the **Languages** field in [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) exactly matches the extension of your `main.*` file in the `code/` directory. The test runner must be the standard one for your chosen language.

### Where can I find a template to start a new lesson?

The repository provides **LESSON_TEMPLATE.md**, which contains the boilerplate folder structure, placeholder files, and examples that satisfy the lesson contract requirements. This template ensures you include all necessary components before running the audit script.

### How does the CI system validate the lesson contract?

The [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) script automatically checks for the presence of required files, validates the [`quiz.json`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/quiz.json) schema, verifies that `code/tests/` contains at least five tests, and ensures the implementation exits cleanly with status 0. Failures in any of these checks will block merging.