mirror of
https://github.com/rohitg00/ai-engineering-from-scratch.git
synced 2026-10-02 10:04:49 +08:00
* fix(i18n): force-add translated lessons past main's inherited .gitignore The dispatched backfill (run 30768876598, 100 shards, all green) published nothing: the translations branch was never created (404). Every shard's publish step logged "no changes". Root cause: when origin/translations doesn't exist yet, the publish step creates it from the current checkout, which is main's tree, .gitignore included. main's .gitignore intentionally excludes i18n/*/phases/ and i18n/*/.cache/ to keep lesson translations off main, but that same rule silently drops the plain `git add "i18n/$LANG_CODE"` inside the new translations-branch worktree, so nothing was ever staged, committed, or pushed across all 100 jobs. Reproduced locally (a repo with the same .gitignore + the same add call reports "no changes"; git add -f stages correctly) before applying the fix. Force-add: the translations branch exists specifically to hold this content. * feat(cert/00): add certification strategy Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/01): add product and model selection Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/02): add model routing and token economics Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/03): add prompting and task decomposition Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/04): add context, memory, and caching Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/05): add output evaluation and validation Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/06): add governance and responsible use Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/07): add workflow design and handoffs Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/08): add Messages API lifecycle Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/09): add defensive structured outputs Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/10): add tool use and agent loops Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/11): add MCP server integration Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/12): add Agent SDK harnesses and hooks Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/13): add application security controls Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/14): add evals and observability Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/15): add Claude Code team workflows Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/16): add multi-agent orchestration Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/17): add sessions, subagents, and context Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/18): add resilient tool contracts Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/19): add Claude Code skills and CI Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/20): add extraction, batch, and review Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/21): add long-context reliability Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/22): add discovery and SLA design Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/23): add architecture tradeoffs Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/24): add RAG evidence pipelines Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/25): add least-privilege integrations Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/26): add production operations Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/27): add enterprise governance Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/28): add lifecycle communication Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/29): add associate capstone Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/30): add developer capstone Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/31): add architect foundations capstone Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * feat(cert/32): add architect professional capstone Adds the lesson, runnable lab, deterministic tests, practice, and inspectable artifacts for this certification topic. * chore(cert): define curriculum contract Documents certification lesson invariants and keeps the AI tutor wrapper while excluding generated site data. * docs(cert): define program and verified sources Adds the independent curriculum policy, onboarding, prerequisites, research notes, and dated source register. * feat(cert/ccao-f): add associate route and practice Maps the associate blueprint to an ordered route, diagnostic, and original full-length practice assessment. * feat(cert/ccdv-f): add developer route and practice Maps the developer blueprint to an ordered route, diagnostic, and original full-length practice assessment. * feat(cert/ccar-f): add architect foundations route Maps the architect foundations blueprint to an ordered route, diagnostic, and original full-length practice assessment. * feat(cert/ccar-p): add architect professional route Maps the architect professional blueprint to an ordered route, diagnostic, and original full-length practice assessment. * feat(skill): add AI-native certification tutor Teaches certification routes step by step in compatible agent harnesses and keeps learner state outside the book workflow. * test(cert): enforce certification contracts Audits lesson, assessment, reference, and answer-position invariants and runs all certification labs in CI. * docs(readme): publish certification entry points Adds the GitHub tutor and website entry points across the canonical README and synchronized translations. * feat(glossary): expand the learning reference Adds deeper original definitions, learning areas, source links, filters, and navigable term detail. * feat(site): redesign the interactive roadmap Keeps the canonical top-to-bottom dependency graph while adding branded focus, path guidance, and reliable navigation. * feat(site): integrate interactive learning surfaces Adds certification routes, lessons, assessments, progress, navigation, artifact rendering, narration fixes, and deploy routing.
137 lines
4.5 KiB
Python
137 lines
4.5 KiB
Python
#!/usr/bin/env python3
|
|
"""Ensure every certification assessment item links to lesson remediation.
|
|
|
|
The script preserves existing references, adds an internal lesson path when an
|
|
item has only external sources, then distributes uncovered route lessons across
|
|
questions in matching blueprint domains. It is deterministic and idempotent.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
import json
|
|
from pathlib import Path
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
TRACKS = ROOT / "certifications" / "claude" / "tracks"
|
|
LESSON_PREFIX = "certifications/claude/lessons/"
|
|
|
|
|
|
def load(path: Path) -> dict:
|
|
return json.loads(path.read_text(encoding="utf-8"))
|
|
|
|
|
|
def save(path: Path, data: dict) -> None:
|
|
path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
|
|
|
|
def lesson_candidates(track: dict) -> dict[str, list[str]]:
|
|
by_domain: dict[str, list[str]] = {}
|
|
for lesson in track.get("lessons", []):
|
|
path = lesson.get("path")
|
|
if not isinstance(path, str):
|
|
continue
|
|
for domain in lesson.get("domains", []):
|
|
by_domain.setdefault(domain, []).append(path)
|
|
for domain, paths in by_domain.items():
|
|
paths.sort(key=lambda path: (
|
|
path.endswith("certification-strategy"),
|
|
"capstone" in path,
|
|
path,
|
|
))
|
|
return by_domain
|
|
|
|
|
|
def assessment_paths(track: dict) -> list[Path]:
|
|
paths = []
|
|
for declaration in track.get("assessments", []):
|
|
relative = declaration.get("path")
|
|
if isinstance(relative, str):
|
|
paths.append(ROOT / relative)
|
|
return paths
|
|
|
|
|
|
def internal_references(question: dict) -> list[str]:
|
|
return [
|
|
reference for reference in question.get("references", [])
|
|
if isinstance(reference, str) and reference.startswith(LESSON_PREFIX)
|
|
]
|
|
|
|
|
|
def update_track(track_path: Path, *, write: bool) -> tuple[int, int]:
|
|
track = load(track_path)
|
|
candidates = lesson_candidates(track)
|
|
documents = [(path, load(path)) for path in assessment_paths(track)]
|
|
added = 0
|
|
|
|
for _, assessment in documents:
|
|
for question in assessment.get("questions", []):
|
|
if internal_references(question):
|
|
continue
|
|
domain_paths = candidates.get(question.get("domain"), [])
|
|
if not domain_paths:
|
|
continue
|
|
question.setdefault("references", []).append(domain_paths[0])
|
|
added += 1
|
|
|
|
covered = {
|
|
reference
|
|
for _, assessment in documents
|
|
for question in assessment.get("questions", [])
|
|
for reference in internal_references(question)
|
|
}
|
|
route_lessons = [
|
|
lesson.get("path") for lesson in track.get("lessons", [])
|
|
if isinstance(lesson.get("path"), str)
|
|
]
|
|
for lesson_path in route_lessons:
|
|
if lesson_path in covered:
|
|
continue
|
|
lesson = next(item for item in track["lessons"] if item.get("path") == lesson_path)
|
|
target = None
|
|
for domain in lesson.get("domains", []):
|
|
for _, assessment in documents:
|
|
target = next(
|
|
(question for question in assessment.get("questions", []) if question.get("domain") == domain),
|
|
None,
|
|
)
|
|
if target:
|
|
break
|
|
if target:
|
|
break
|
|
if target is None:
|
|
continue
|
|
target.setdefault("references", []).append(lesson_path)
|
|
covered.add(lesson_path)
|
|
added += 1
|
|
|
|
changed_files = 0
|
|
for path, assessment in documents:
|
|
before = path.read_text(encoding="utf-8")
|
|
after = json.dumps(assessment, indent=2, ensure_ascii=False) + "\n"
|
|
if before != after:
|
|
if write:
|
|
path.write_text(after, encoding="utf-8")
|
|
changed_files += 1
|
|
return added, changed_files
|
|
|
|
|
|
def main() -> int:
|
|
parser = argparse.ArgumentParser(description=__doc__)
|
|
parser.add_argument("--check", action="store_true", help="fail if remediation references need regeneration")
|
|
args = parser.parse_args()
|
|
total_added = 0
|
|
total_files = 0
|
|
for track_path in sorted(TRACKS.glob("*.json")):
|
|
added, changed = update_track(track_path, write=not args.check)
|
|
total_added += added
|
|
total_files += changed
|
|
verb = "need" if args.check else "added"
|
|
print(f"{verb} {total_added} remediation reference(s) across {total_files} assessment file(s)")
|
|
return 1 if args.check and total_files else 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|