# How Phases Are Ordered and Prerequisite Lesson Dependencies Work in AI Engineering from Scratch

> Discover how phases are ordered numerically and lesson prerequisite dependencies work in ai-engineering-from-scratch. Explore the curriculum structure and validation process.

- Repository: [Rohit Ghumare/ai-engineering-from-scratch](https://github.com/rohitg00/ai-engineering-from-scratch)
- Tags: internals
- Published: 2026-06-14

---

**In the rohitg00/ai-engineering-from-scratch curriculum, phases are ordered numerically from `00` to `19` in the `phases/` directory, while lesson prerequisites are declared in each lesson's [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) frontmatter using a structured format like "Phase 2 · 14 (Naive Bayes)" that the CI validates as a directed acyclic graph.**

The repository structures a self-contained AI engineering learning path through rigid file naming conventions and explicit dependency declarations. Understanding how phases are ordered and how prerequisite lesson dependencies are encoded is essential for navigating the curriculum or contributing new content. The system enforces these relationships automatically through validation scripts that prevent logical gaps or circular dependencies.

## Phase Ordering via Directory Structure

The curriculum lives under the top-level **`phases/`** directory. Each subfolder uses a two-digit numeric prefix that defines the chronological learning path, starting at **`00-setup-and-tooling`** and ending at **`19-capstone-projects`**.

Because the directory names begin with zero-padded numbers, a simple lexical sort yields the correct sequence. The intermediate phases follow this pattern:

- **`00-setup-and-tooling`** – Environment preparation
- **`01-math-foundations`** – Linear algebra and calculus
- **`02-ml-fundamentals`** – Linear regression and decision trees
- **...**
- **`19-capstone-projects`** – End-to-end integration projects

The canonical ordering is documented in **[`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md)**, which serves as the master reference table. As implemented in the `phase_order()` function within the repository's tooling, the sequence is generated by matching directory names against the pattern `\d\d-` and sorting them alphabetically.

## Declaring Lesson Prerequisites in Frontmatter

Every lesson resides in a leaf directory containing a **[`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md)** file. This markdown file begins with frontmatter that includes a **Prerequisites** field using the syntax:

```text
**Prerequisites:** Phase X · Y (Lesson Title)

```

For example, the text processing lesson in [`phases/05-nlp-foundations-to-advanced/01-text-processing/docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/phases/05-nlp-foundations-to-advanced/01-text-processing/docs/en.md) declares:

```text
**Prerequisites:** Phase 2 · 14 (Naive Bayes)

```

The format supports several dependency types:

- **Cross-phase requirements** – `Phase 3 · 02 (Backpropagation)` references phase 3, lesson 2
- **Multiple prerequisites** – Comma-separated lists like `Phase 1 · 08, Phase 2 · 05`
- **Intra-phase dependencies** – Lessons within the same phase referencing each other

The middle dot (·) serves as a standard delimiter between the phase number and lesson number, making the string parseable by the validation tooling.

## Automated Dependency Graph Validation

The repository treats curriculum dependencies as a **directed acyclic graph (DAG)** that must be validated continuously. The **[`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py)** script runs in CI to parse prerequisite declarations from every [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) file.

The validation process extracts phase and lesson numbers using regex patterns, then verifies that:
1. Referenced prerequisites exist as actual files
2. No circular dependencies exist (e.g., lesson A depending on lesson B which depends on lesson A)
3. Prerequisites do not reference future phases or lessons that occur later in the sequence

This automated enforcement prevents contributors from introducing lessons that depend on future content or creating logical gaps in the learning path. If the DAG validation fails, the CI build prevents the pull request from merging.

## Parsing Prerequisites Programmatically

You can extract the dependency graph using Python to analyze the curriculum structure. The following script demonstrates how the repository tooling reads the roadmap and extracts prerequisite relationships:

```python
import pathlib
import re

ROOT = pathlib.Path(__file__).parent.parent

def phase_order():
    """Return a list of phase folder names in canonical order."""
    # The folder names already encode the order.

    return sorted(p.name for p in (ROOT / "phases").iterdir()
                  if p.is_dir() and re.match(r'\d\d-', p.name))

def parse_prereq(frontmatter: str) -> list[tuple[str, int]]:
    """Parse the '**Prerequisites:**' line into (phase, lesson) tuples."""
    m = re.search(r'\*\*Prerequisites:\*\*\s*(.*)', frontmatter)
    if not m:
        return []
    raw = m.group(1)
    deps = []
    for part in raw.split(','):
        match = re.search(r'Phase\s*(\d+)\s*·\s*(\d+)', part)
        if match:
            deps.append((f'{int(match.group(1)):02d}', int(match.group(2))))
    return deps

def collect_lessons():
    """Yield (phase, lesson, prereqs) for every lesson."""
    for phase_dir in (ROOT / "phases").iterdir():
        if not re.match(r'\d\d-', phase_dir.name):
            continue
        phase_id = phase_dir.name.split('-')[0]
        for lesson_dir in phase_dir.rglob('docs/en.md'):
            with open(lesson_dir) as f:
                text = f.read()
            prereqs = parse_prereq(text)
            lesson_id = int(lesson_dir.parent.name.split('-')[0])
            yield (phase_id, lesson_id, prereqs)

if __name__ == "__main__":
    print("Phase order:", phase_order())
    for phase, lesson, deps in collect_lessons():
        print(f"Phase {phase} – Lesson {lesson:02d} → {deps}")

```

The `parse_prereq` function uses regex to capture the **Phase** and **Lesson** numbers, handling the middle dot delimiter and multiple prerequisite declarations. Running this script outputs the complete DAG of dependencies, which mirrors the validation performed by [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py).

## Summary

- **Phases are ordered numerically** from `00` to `19` in the `phases/` directory using zero-padded prefixes
- **Prerequisites are declared** in [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) frontmatter using the format "Phase X · Y (Title)"
- **The [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) CI tool** validates the dependency DAG and prevents circular references
- **Lexical sorting** of directory names produces the correct learning sequence without additional configuration files

## Frequently Asked Questions

### What is the correct order of phases in ai-engineering-from-scratch?

The phases follow a zero-padded numeric sequence from `00` (setup-and-tooling) through `19` (capstone-projects), with intermediate phases covering math foundations, ML fundamentals, deep learning, NLP, and other topics. This order is enforced by the two-digit prefix in each phase directory name, and a simple `ls phases/` command lists them in the correct learning sequence.

### How do I specify that my lesson requires knowledge from a previous phase?

Add a **Prerequisites** line to your lesson's [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) frontmatter using the format `Phase X · Y (Lesson Name)`. For multiple prerequisites, separate them with commas. The CI will validate that these lessons exist and that you are not creating circular dependencies or referencing future content.

### What happens if I create a prerequisite that points to a non-existent lesson?

The CI will fail because [`scripts/audit_lessons.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/audit_lessons.py) validates that every prerequisite string references an actual file in the repository. If the validation script cannot find the corresponding [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md) file for the phase and lesson number you specified, the build will fail and prevent the merge of your pull request.

### Can a lesson in phase 10 depend on a lesson from phase 5?

Yes, cross-phase dependencies are fully supported and expected. The prerequisite syntax `Phase 5 · 12 (Lesson Name)` explicitly allows lessons to reference content from any previous phase, enabling the curriculum to build upon foundational concepts introduced earlier in the learning path while maintaining strict forward-only dependencies.