How Roadmap Status Tracking Works in AI Engineering from Scratch: The Emoji-Based System Explained
The curriculum uses three Unicode emojis (โ
for Complete, ๐ง for In Progress, โฌ for Planned) stored directly in ROADMAP.md, which site/build.js parses into structured JSON to automatically update the website, README badges, and lesson statistics.
The AI Engineering from Scratch repository maintains a public curriculum roadmap using a lightweight, file-based status tracking system. Instead of external databases or complex project management APIs, the project embeds simple visual markers directly in markdown tables to indicate completion states. This design allows contributors to update progress by editing a single file while automated scripts propagate those changes across the website and documentation.
Where the Status Emojis Live in ROADMAP.md
ROADMAP.md serves as the single source of truth for all curriculum progress. The emoji definitions appear in a legend at the top of the file (lines 9-10), establishing โ
for Complete, ๐ง for In Progress, and โฌ for Planned.
Phase headers include the status emoji after an em-dash:
## Phase 0: Setup & Tooling โ โ
(~14 hours)
Individual lessons use markdown table rows with the emoji in the third column:
| 01 | Dev Environment | โ
| ~75 min |
How build.js Parses the Emoji Statuses
The parseRoadmap() function in site/build.js (lines 36-57) converts these visual markers into machine-readable data using two specific regex patterns.
For phase headers, the pattern matches the phase number and trailing emoji:
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';
// ...
}
For lesson rows, the pattern extracts the lesson name and status from table formatting:
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';
// ...
}
The function returns a nested object structure mapping each phase to its status and a dictionary of lesson statuses:
{
"Phase 0": {
"phaseStatus": "complete",
"lessons": {
"Dev Environment": "complete",
"Git & Collaboration": "complete"
}
}
}
Status Propagation to the Website and README
Once parsed, the status data flows through several build steps:
-
HTML Generation: The
parseReadmefunction (lines 78-95 insite/build.js) reads the README lesson tables, matches each lesson to the roadmap entry, and copies the computedstatusonto the lesson object. -
site/data.js: The build script writes a generated JSON file consumed by the frontend, where each lesson object includes a
"status"field of"complete","in-progress", or"planned". -
README Synchronization: The
syncCountslogic updates the lesson count badge inREADME.mdto reflect current statistics, ensuring the public repository view matches the roadmap state.
Practical Examples
Adding a New Lesson
To add a lesson to the roadmap with planned status:
-
Open
ROADMAP.mdand insert a table row:| 27 | Advanced Embeddings | โฌ | ~60 min | -
Run
node site/build.js(or let CI automate this). The new lesson appears insite/data.jswith"status":"planned"and renders the empty square icon on the website.
Programmatic Status Lookup
You can use the parsing logic directly to check status programmatically:
const fs = require('fs');
// Load the parsing function from build.js
const { parseRoadmap } = require('./site/build.js');
const roadmap = parseRoadmap(fs.readFileSync('ROADMAP.md', 'utf8'));
const phase = roadmap['Phase 5'];
console.log('Phase 5 status:', phase.phaseStatus); // โ "complete"
console.log('Lesson status:', phase.lessons['Text Processing โ Tokenization, Stemming, Lemmatization']);
// โ "complete"
Rendering Status Badges
The frontend uses the status strings to render visual indicators:
<span class="status-badge complete">โ
</span>
<span class="status-badge in-progress">๐ง</span>
<span class="status-badge planned">โฌ</span>
Summary
- Single source of truth: Only
ROADMAP.mdrequires manual editing; the website and README regenerate automatically viasite/build.js. - Three-state system: โ
maps to
"complete", ๐ง to"in-progress", and โฌ to"planned". - Regex parsing: Lines 36-57 of
site/build.jsuse pattern matching to extract statuses from phase headers and lesson table rows. - Deterministic output: Unicode emojis ensure identical parsing across all platforms and operating systems.
Frequently Asked Questions
What happens if I use the wrong emoji in ROADMAP.md?
If you use an emoji not in the set [โ
๐งโฌ], the regex patterns in site/build.js will fail to match that line, causing the entry to be omitted from the generated site/data.js. The build process will effectively treat that lesson or phase as having no status, and it won't appear in the website's progress tracking until corrected.
Can I modify the status emojis to use different characters?
You would need to update three locations: the legend in ROADMAP.md (lines 9-10), the regex patterns in site/build.js (lines 36-57), and the mapping logic that converts emoji matches to string values ('complete', 'in-progress', 'planned'). The system is designed to be strict about the current Unicode characters to ensure consistency across the repository.
How does the README badge stay synchronized with the roadmap?
The syncCounts functionality within site/build.js automatically calculates the total number of lessons and their completion status after parsing ROADMAP.md. It then updates the badge URL in README.md to reflect current statistics, ensuring that the repository's front page always displays accurate progress without manual editing.
Is this emoji-based system scalable for larger curricula?
According to the source code design, the system scales linearly with the number of lessons because parseRoadmap() iterates through ROADMAP.md once in O(n) time. Since it uses simple string matching rather than complex parsing libraries, performance remains consistent even with hundreds of lessons. The only limitation is markdown file size, which GitHub handles efficiently up to several megabytes.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too โ