# How the ROADMAP Feature Tracks Completion Status in the AI Engineering Curriculum

> Discover how the ROADMAP feature tracks AI Engineering curriculum completion using emoji markers. Learn how lesson status is managed for a seamless learning experience.

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

---

**The ROADMAP feature tracks completion status by parsing emoji markers from [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) and injecting them into lesson data during the automated build process, generating a static [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) file that serves as the single source of truth for the web interface.**

The `rohitg00/ai-engineering-from-scratch` repository implements a deterministic build system that transforms human-readable markdown tables into structured curriculum data. This approach treats [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) as the authoritative source for progress tracking, ensuring that lesson completion statuses automatically synchronize with content availability every time the site rebuilds.

## Parsing the ROADMAP.md Source of Truth

The build process begins in [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js), where the `parseRoadmap()` function scans the curriculum's roadmap file line-by-line. This function identifies phase headers and lesson rows using regex patterns to extract status emojis and map them to standardized string values.

### Extracting Phase and Lesson Statuses

The script processes [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) using two distinct regex patterns. Phase headers follow the format `## Phase N: Title — <emoji>`, while lesson rows appear as table pipes `| Lesson Name | <emoji> |`. The function maps ✅ to `"complete"`, 🚧 to `"in-progress"`, and ⬚ to `"planned"`.

```javascript
// site/build.js – parseRoadmap()
function parseRoadmap(content) {
  const statuses = {};                // { "Phase 0": { phaseStatus, lessons: {} } }
  let currentPhase = null;
  let currentPhaseStatus = null;

  for (const line of content.split(/\r?\n/)) {
    // Phase header, e.g. "## Phase 0: Setup & Tooling — ✅"

    const phaseMatch = line.match(/^##\s+Phase\s+(\d+).*?—\s*(✅|🚧|⬚)/);
    if (phaseMatch) {
      const phaseId = parseInt(phaseMatch[1]);
      const statusEmoji = phaseMatch[2];
      currentPhaseStatus =
        statusEmoji === '✅' ? 'complete' :
        statusEmoji === '🚧' ? 'in-progress' : 'planned';
      currentPhase = `Phase ${phaseId}`;
      statuses[currentPhase] = { phaseStatus: currentPhaseStatus, lessons: {} };
      continue;
    }

    // Lesson row, e.g. "| 01 | Dev Environment | ✅ |"
    if (currentPhase) {
      const lessonMatch = line.match(/^\|\s*\d+\s*\|\s*(.+?)\s*\|\s*(✅|🚧|⬚)\s*\|/);
      if (lessonMatch) {
        const lessonName = lessonMatch[1].trim();
        const statusEmoji = lessonMatch[2];
        const status =
          statusEmoji === '✅' ? 'complete' :
          statusEmoji === '🚧' ? 'in-progress' : 'planned';
        statuses[currentPhase].lessons[lessonName] = status;
      }
    }
  }
  return statuses;
}

```

## Enriching README.md Data with Roadmap Statuses

After extracting the roadmap map, the script processes [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md) to locate lesson tables. The `parseReadme()` function performs fuzzy matching between lesson names in the README and those recorded in the roadmap, normalizing text by removing hyphens and extra whitespace.

### Cross-Referencing and Auto-Correction

The system implements a safety mechanism that automatically upgrades a lesson's status to **complete** if it detects a GitHub repository link, regardless of the roadmap entry. This ensures that published content never appears as unplanned.

```javascript
// site/build.js – inside parseReadme()
if (lessonMatch) {
  // Look up status from the roadmap map
  const roadmapKey = `Phase ${currentPhase.id}`;
  const roadmapPhase = roadmapStatuses[roadmapKey];
  let status = 'planned';
  if (roadmapPhase) {
    const lessonNameClean = lessonName.replace(/[-–—:]/g, ' ')
                                     .replace(/\s+/g, ' ')
                                     .trim()
                                     .toLowerCase();
    for (const [rName, rStatus] of Object.entries(roadmapPhase.lessons)) {
      const rNameClean = rName.replace(/[-–—:]/g, ' ')
                               .replace(/\s+/g, ' ')
                               .trim()
                               .toLowerCase();
      if (rNameClean.includes(lessonNameClean) ||
          lessonNameClean.includes(rNameClean)) {
        status = rStatus;
        break;
      }
    }
  }

  // If a GitHub link exists, force "complete" (the lesson is published)
  if (url && status === 'planned') {
    status = 'complete';
  }
}

```

## Generating the Static Data File

The enriched data structure is written to [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) during the build process (lines 68-78 of [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js)). This file exports a `PHASES` array containing nested lesson objects with resolved status fields, serving as the immutable data source for the frontend application.

### The data.js Output Structure

The generated file contains lesson records with standardized status values that the UI renders as visual progress indicators.

```javascript
const PHASES = [
  {
    id: 0,
    name: "Setup & Tooling",
    status: "complete",
    lessons: [
      {
        name: "Dev Environment",
        status: "complete",
        type: "Build",
        lang: "Python, Node, Rust",
        url: "https://github.com/rohitg00/ai-engineering-from-scratch/tree/main/phases/00-setup-and-tooling/01-dev-environment"
      }
    ]
  }
];

```

## Continuous Integration and Automated Synchronization

The build script executes automatically via the GitHub Action defined in [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml). This CI workflow triggers on every push to the repository, ensuring that any edits to [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) immediately propagate to the generated [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) and the live web interface.

## Summary

- **[`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md)** serves as the human-editable source of truth, using emoji markers (✅ 🚧 ⬚) to indicate completion states.
- **[`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js)** contains the `parseRoadmap()` and `parseReadme()` functions that transform markdown tables into structured JSON.
- **Auto-correction logic** guarantees that lessons with GitHub links always display as complete, preventing stale data.
- **[`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml)** automates the build process, ensuring the website always reflects the current curriculum state.

## Frequently Asked Questions

### How does the ROADMAP feature handle lessons that exist in README.md but lack entries in ROADMAP.md?

The system defaults to a `"planned"` status for any lesson not found in the roadmap map. However, if the lesson contains a valid GitHub repository link, the auto-correction logic immediately upgrades it to `"complete"`, ensuring published content is never mislabeled as unavailable.

### Can contributors update completion status without modifying code?

Yes. Contributors simply edit the emoji markers in [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) (✅ for complete, 🚧 for in-progress, ⬚ for planned). The next push triggers the GitHub Action, which regenerates [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) and updates the website automatically.

### What happens if the emoji markers in ROADMAP.md use different characters?

The regex patterns in `parseRoadmap()` specifically match only ✅, 🚧, and ⬚ characters. Any other characters would fail to match, causing the status to fall back to the default `"planned"` value or remain unrecognized until standardized.

### How does the system prevent the website from showing outdated completion statuses?

The continuous integration workflow in [`.github/workflows/curriculum.yml`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/.github/workflows/curriculum.yml) runs [`site/build.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/build.js) on every push. This deterministic rebuild ensures that the generated [`data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/data.js) file never diverges from the current state of [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) and [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md).