# Tracking Phase Prerequisites and Dependencies in the AI Engineering from Scratch Curriculum

> Learn how the AI Engineering from Scratch curriculum tracks phase prerequisites and dependencies using a DAG and interactive SVG roadmap. Master your AI learning path.

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

---

**The AI Engineering from Scratch curriculum tracks phase prerequisites and dependencies through a directed acyclic graph (DAG) implemented via a static `PREREQS` JavaScript object in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html), merged with dynamically generated `PHASES` data from [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) to render an interactive SVG roadmap.**

The rohitg00/ai-engineering-from-scratch repository structures its learning path as a directed acyclic graph where each phase may depend on one or more earlier phases. Understanding how the system tracks these dependencies is essential for contributors adding new content or learners navigating the curriculum. The implementation combines static dependency maps with auto-generated catalog data to create a robust prerequisite tracking system that maintains synchronization between documentation, code, and the visual roadmap.

## How Prerequisites Are Stored

The system stores prerequisite information in three interconnected locations, balancing manual curation with automated generation.

### Static Dependency Map in site/prereqs.html

The canonical source of dependency edges lives in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html) as a JavaScript object called `PREREQS`. This static mapping lists, for every phase ID, the IDs of its direct prerequisite phases.

```javascript
// In site/prereqs.html (around line 523)
var PREREQS = {
  0:  [],
  1:  [0],
  2:  [1],
  // ...
  19: [14, 15, 16, 17]
};

```

### Generated Phase Catalogue in site/data.js

The build pipeline generates [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) via [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js), which processes the output of [`scripts/build_catalog.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_catalog.py). This file contains a `PHASES` array where each element includes the phase `id`, `name`, and `status` (complete, in-progress, or planned).

### Runtime Graph Construction

When the roadmap page loads, the system merges `PREREQS` with `PHASES` and builds two auxiliary structures for traversal: `CHILDREN` (the reverse of `PREREQS` mapping parents to children) and `POS` (absolute SVG coordinates derived from `TIER_ORDER`). A sanity-check loop (lines 887-891 in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html)) ensures every phase in `PHASES` has an entry in `PREREQS`, automatically assigning an empty array to phases without explicit prerequisites.

## The Build Pipeline

The end-to-end flow transforms markdown lesson files into a navigable dependency graph.

### Phase Definition Structure

Each phase resides under `phases/<phase-number>-<slug>/` with its human-readable title extracted from the H1 in [`docs/en.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/docs/en.md). The front-matter includes a `Prerequisites:` field listing upstream lessons.

### Catalog Generation with build_catalog.py

The [`scripts/build_catalog.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_catalog.py) script walks the `phases/*` directory tree, parses front-matter, collects code files and quiz metadata, and outputs a JSON representation. This catalog captures the phase identifiers that keep documentation and code synchronized.

### Site Generation with build.js

The [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js) script consumes the catalog to produce [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js), injecting the `PHASES` array into the static site. This separation allows the visual map to reference the same phase identifiers used in lesson front-matter.

## Visualizing the Dependency Graph

The visualization logic in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html) (lines 523-800) renders the DAG as an interactive SVG diagram.

### Layout Algorithm and TIER_ORDER

The layout matrix `TIER_ORDER` defines visual groupings of phases. The script computes node positions automatically, adding a catch-all tier for any phase not explicitly placed in the matrix. Directed edges render as cubic-bezier curves (`edgePath`) with arrowheads (`arrowPoints`) to show prerequisite flow.

### Interactive Traversal Functions

The UI exposes `getAncestors(pid)` and `getDescendants(pid)` functions for highlighting prerequisite chains and unlocked content. Clicking a phase highlights its ancestors (required prerequisites) and descendants (what it unlocks) while displaying completion status from the `PHASES` array.

## Adding New Phases with Prerequisites

To extend the curriculum with a new phase, update both the static map and the directory structure.

First, edit the `PREREQS` object in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html):

```javascript
// Add to PREREQS object
var PREREQS = {
  // ... existing entries ...
  20: [19],  // New phase 20 depends on phase 19
};

```

Then create the phase directory:

```bash
mkdir -p phases/20-new-research/01-intro
echo "# Intro to New Research\n\n**Prerequisites:** Phase 19" > phases/20-new-research/01-intro/docs/en.md

```

After the next CI build, [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) includes the new phase automatically.

## Querying Dependencies Programmatically

You can inspect prerequisite relationships via browser console using the helper functions:

```javascript
// Get all prerequisite phase IDs for phase 12
const ancestors = getAncestors(12);
console.log(Object.keys(ancestors)); // → ['4', '6', '11', ...]

```

To customize the visual layout, modify `TIER_ORDER` before the graph renders:

```javascript
var TIER_ORDER = [
  [0],
  [1],
  [2],
  [3, 5, 7, 4, 6],
  [8, 10],
  [11, 12, 13],
  [14, 15, 16],
  [19, 20]  // Place new phase 20 next to 19
];

```

## Summary

- The **prerequisite system** uses a static `PREREQS` object in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html) merged with auto-generated `PHASES` data from [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js).
- **Build pipeline**: [`scripts/build_catalog.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_catalog.py) parses lesson front-matter, [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js) generates the site data, and [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html) renders the interactive DAG.
- **Visualization** relies on `TIER_ORDER` for layout, `getAncestors()` for prerequisite chains, and `getDescendants()` for unlocked content.
- **Safety checks** ensure every phase has a dependency entry, preventing graph breakage when adding new curriculum content.

## Frequently Asked Questions

### How does the curriculum prevent circular dependencies between phases?

The system implements a directed acyclic graph (DAG) structure where `PREREQS` defines edges from child to parent phases. While the JavaScript rendering logic assumes acyclic data, the static nature of the `PREREQS` object in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html) allows maintainers to review dependency chains manually during curriculum updates. The `getAncestors()` function performs recursive traversal up the parent chain, which would theoretically run indefinitely if cycles existed, but the build process and manual review ensure phase 19 cannot list phase 20 as a prerequisite while phase 20 lists phase 19.

### Can I modify prerequisites without rebuilding the entire site?

Yes. The `PREREQS` object in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html) is static JavaScript that loads at runtime, so you can edit dependency edges directly in that file without running [`scripts/build_catalog.py`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/scripts/build_catalog.py) or [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js). However, changes to phase titles, descriptions, or completion status require regenerating [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) through the build pipeline, as that data derives from lesson front-matter in the `phases/` directory.

### What happens if a phase is missing from the PREREQS map?

The runtime initialization code includes a safety check (lines 887-891 in [`site/prereqs.html`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/prereqs.html)) that iterates through all phase IDs in `PHASES` and verifies their presence in `PREREQS`. If a phase lacks an entry, the script automatically assigns it an empty array (`PREREQS[pid] = []`), effectively marking it as having no prerequisites. This prevents the visualization from breaking while allowing the curriculum to scale without immediate manual updates to the dependency map.

### How does the system handle multiple prerequisites for a single phase?

The `PREREQS` object supports arrays of parent IDs for each phase. For example, phase 19 declares `[14, 15, 16, 17]` as its prerequisites, meaning learners must complete all four preceding phases before accessing phase 19. The visualization draws separate cubic-bezier curves from each parent to the child node, and the `getAncestors()` function recursively collects the entire upstream chain, ensuring complete dependency tracking for complex curriculum paths.