How to Handle Merge Conflicts in the AI Engineering from Scratch Curriculum
Resolve merge conflicts in the AI Engineering from Scratch curriculum by preserving exact markdown table syntax in README.md and ROADMAP.md, regenerating site/data.js via node site/build.js, and validating changes with scripts/check_readme_counts.py and scripts/audit_lessons.py before committing.
The AI Engineering from Scratch curriculum maintains a tightly-coupled structure where lesson tables directly feed an automated site generator. Because the parser in site/build.js relies on precise markdown structures—including phase headers and lesson rows—to produce site/data.js, merge conflicts must be resolved carefully to prevent breaking the automatic site build and CI pipeline.
Core Principles for Conflict Resolution
The repository enforces strict structural contracts to ensure the generated website remains functional. Understanding these constraints prevents merge conflicts from corrupting the curriculum’s metadata.
-
One-commit-per-lesson – Each lesson lives in its own folder under
phases/. This isolation prevents large, tangled pull requests that generate simultaneous conflicts across multiple files. -
Exact markdown syntax – Phase headers must follow the format
### Phase N: …and lesson rows must use the pipe-delimited structure| # | Lesson | Type | Lang |. Thesite/build.jsparser expects these patterns to generate validsite/data.js. -
CI-driven regeneration – Files like
site/data.jsand lesson count badges inREADME.mdare automatically rebuilt on themainbranch. Manual edits to generated files are overwritten during the next CI run. -
Do not edit generated files – Both
catalog.jsonandsite/data.jsare git-ignored and machine-generated. Always modify source markdown and regenerate rather than editing output directly. -
Validate before merging – The repository provides
scripts/check_readme_counts.pyandscripts/audit_lessons.pyto catch structural issues before CI blocks your pull request.
Step-by-Step Conflict Resolution Process
When Git flags a conflict during a merge or rebase, follow this workflow to restore structural integrity while incorporating your changes.
1. Fetch the Latest Main Branch
Bring your feature branch up to date with the remote to materialize conflicts locally:
git fetch origin main
git merge --no-edit origin/main
This creates a merge commit and inserts conflict markers (<<<<<<< HEAD) into any contested files.
2. Identify Conflicted Files
Run git status to locate files with unresolved conflicts. In this curriculum, typical conflict locations include:
README.md– Lesson table rows and phase headersROADMAP.md– Status glyphs and lesson progress indicatorssite/data.js– Generated JavaScript data structures
3. Resolve Structural Content
Edit each conflicted file while preserving the exact syntax required by the build system:
README.md – Maintain the markdown table structure and lesson links. A valid row must follow this pattern:
| 01 | [Dev Environment](phases/00-setup-and-tooling/01-dev-environment/) | Build | Python |
Remove all conflict markers (<<<<<<<, =======, >>>>>>>) and ensure no duplicate rows remain.
ROADMAP.md – Preserve status glyphs exactly as Unicode characters (✅ for complete, 🚧 for in-progress, ⬚ for not started). Do not replace these with words like "Done" or "Pending".
site/data.js – Do not resolve this file manually. Instead, fix the source markdown files first, then regenerate:
node site/build.js
This script parses the corrected README.md and ROADMAP.md to produce a fresh site/data.js.
4. Run Local Validation
Before committing, execute the audit scripts to verify repository health:
python3 scripts/audit_lessons.py
python3 scripts/check_readme_counts.py --fix
The audit_lessons.py script checks for missing lesson files and malformed front-matter, while check_readme_counts.py --fix synchronizes the lesson-count badges in README.md with the actual directory structure.
5. Commit the Resolution
Stage only the resolved source files and the regenerated output:
git add README.md ROADMAP.md site/data.js
git commit --no-edit
The --no-edit flag preserves the default merge commit message.
6. Push and Verify
Push the branch without force (unless there are no pending review comments):
git push origin <your-branch>
Wait for the CI pipeline to complete. The audit, readme-counts-sync, and site-rebuild jobs must pass. If any job fails, return to step 4 and address the validation errors.
Common Pitfalls and Solutions
| Symptom | Cause | Fix |
|---|---|---|
grep -c 'tree/main/phases/NN-' site/data.js returns 0 |
Lesson rows in README.md lost their markdown link syntax ([Title](…)). |
Restore the proper link format and regenerate site/data.js. |
Status glyphs appear as plain text ("Done") in ROADMAP.md |
Manual editing replaced Unicode glyphs with ASCII words. | Replace with exact glyphs: ✅, 🚧, or ⬚. |
CI fails on readme-counts-sync |
Lesson count badge in README.md is out of sync with actual lessons. |
Run python3 scripts/check_readme_counts.py --fix before committing. |
site/data.js contains stale or missing lessons |
Manual edits were made directly to the generated file. | Delete the modified file (git checkout --theirs site/data.js) and run node site/build.js. |
Automating Conflict Resolution
For frequent contributors, wrap the resolution workflow in a Python script to ensure consistency. Save this as scripts/resolve_merge.py:
#!/usr/bin/env python3
import subprocess, sys
def run(cmd):
subprocess.check_call(cmd, shell=True)
def main():
# Pull latest main and attempt merge
run("git fetch origin main")
run("git merge --no-edit origin/main")
# Fix structural metadata
run("python3 scripts/check_readme_counts.py --fix")
run("node site/build.js")
# Validate repository health
run("python3 scripts/audit_lessons.py")
# Stage and commit
run("git add README.md ROADMAP.md site/data.js")
run("git commit --no-edit")
if __name__ == "__main__":
main()
Execute with python3 scripts/resolve_merge.py after Git notifies you of conflicts.
Essential Reference Files
For detailed specifications, consult these canonical sources in the repository:
AGENTS.md– Official conflict-resolution guide and agent instructionsCONTRIBUTING.md– Requirements for README and ROADMAP structuresite/build.js– The parser that generatessite/data.jsfrom markdownscripts/check_readme_counts.py– Badge synchronization logicscripts/audit_lessons.py– Lesson directory validation
Summary
- Preserve exact markdown table syntax in
README.mdand status glyphs inROADMAP.mdto keepsite/build.jsfunctional. - Never manually edit
site/data.js; always regenerate it usingnode site/build.jsafter resolving source conflicts. - Validate all changes locally with
scripts/check_readme_counts.py --fixandscripts/audit_lessons.pybefore pushing. - Follow the one-commit-per-lesson principle to minimize future conflict complexity.
- Reference
AGENTS.mdandCONTRIBUTING.mdfor authoritative structural requirements.
Frequently Asked Questions
What should I do if site/data.js appears in the conflict list?
Do not manually edit site/data.js. According to the repository’s CI-driven regeneration policy, this file is machine-generated from README.md and ROADMAP.md. Discard your local changes with git checkout --theirs site/data.js, resolve the markdown source files instead, then run node site/build.js to produce a fresh, correct version.
Why does the README.md use specific Unicode glyphs instead of text labels?
The site/build.js parser relies on exact Unicode characters (✅, 🚧, ⬚) in ROADMAP.md to determine lesson status for the generated website. Replacing these with words like "Done" or emojis breaks the parsing logic, causing lessons to display incorrectly or disappear from the generated site/data.js entirely.
How can I prevent merge conflicts when adding new lessons?
Follow the one-commit-per-lesson rule by placing each lesson in its own isolated directory under phases/. Make minimal, focused changes to README.md that add exactly one table row per lesson. Run python3 scripts/check_readme_counts.py and python3 scripts/audit_lessons.py before committing to catch structural violations early.
What happens if I commit resolved files but CI still fails?
The CI pipeline runs audit, readme-counts-sync, and site-rebuild jobs. If validation fails after your merge, return to your local environment and re-run python3 scripts/check_readme_counts.py --fix followed by python3 scripts/audit_lessons.py. These scripts identify the specific structural mismatch—such as malformed table rows or missing lesson directories—that caused the CI failure.
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 →