100 Commits
Author SHA1 Message Date
Rohit Ghumare 29c480a6f9 fix(site): refresh cached assets and align project commands (#513)
* fix(site): revalidate pages and version deployed assets

* fix(projects): align setup cards and add copy feedback

* fix(site): keep desktop navigation compact and controls usable
2026-09-30 00:07:51 +05:30
Rohit Ghumare 3ecf630b0f feat(projects): add 48 builds and a 52-project roadmap (#497)
* feat(projects): workflow-hooks stage 1

* feat(projects): workflow-hooks stage 2

* feat(projects): workflow-hooks stage 3

* feat(projects): workflow-hooks stage 4

* fix(projects): preserve sponsor navigation in project footer

* feat(projects): agent-budget-planner stage 1

* feat(projects): agent-budget-planner stage 2

* feat(projects): agent-budget-planner stage 3

* feat(projects): agent-budget-planner stage 4

* feat(projects): agent-trace-debugger stage 1

* feat(projects): agent-trace-debugger stage 2

* feat(projects): agent-trace-debugger stage 3

* feat(projects): agent-trace-debugger stage 4

* feat(projects): browser-agent stage 1

* feat(projects): browser-agent stage 2

* feat(projects): browser-agent stage 3

* feat(projects): browser-agent stage 4

* feat(projects): calendar-focus-planner stage 1

* feat(projects): calendar-focus-planner stage 2

* feat(projects): calendar-focus-planner stage 3

* feat(projects): calendar-focus-planner stage 4

* feat(projects): changelog-writer-from-git stage 1

* feat(projects): changelog-writer-from-git stage 2

* feat(projects): changelog-writer-from-git stage 3

* feat(projects): changelog-writer-from-git stage 4

* feat(projects): cloud-agent-with-aws-strands stage 1

* feat(projects): cloud-agent-with-aws-strands stage 2

* feat(projects): cloud-agent-with-aws-strands stage 3

* feat(projects): cloud-agent-with-aws-strands stage 4

* feat(projects): csv-sql-question-workbench stage 1

* feat(projects): csv-sql-question-workbench stage 2

* feat(projects): csv-sql-question-workbench stage 3

* feat(projects): csv-sql-question-workbench stage 4

* feat(projects): dataset-split-auditor stage 1

* feat(projects): dataset-split-auditor stage 2

* feat(projects): dataset-split-auditor stage 3

* feat(projects): dataset-split-auditor stage 4

* feat(projects): desktop-control stage 1

* feat(projects): desktop-control stage 2

* feat(projects): desktop-control stage 3

* feat(projects): desktop-control stage 4

* feat(projects): distributed-eval-farm stage 1

* feat(projects): distributed-eval-farm stage 2

* feat(projects): distributed-eval-farm stage 3

* feat(projects): distributed-eval-farm stage 4

* feat(projects): doc-qa-with-citations stage 1

* feat(projects): doc-qa-with-citations stage 2

* feat(projects): doc-qa-with-citations stage 3

* feat(projects): doc-qa-with-citations stage 4

* feat(projects): document-extraction-desk stage 1

* feat(projects): document-extraction-desk stage 2

* feat(projects): document-extraction-desk stage 3

* feat(projects): document-extraction-desk stage 4

* feat(projects): durable-agent-jobs stage 1

* feat(projects): durable-agent-jobs stage 2

* feat(projects): durable-agent-jobs stage 3

* feat(projects): durable-agent-jobs stage 4

* feat(projects): feedback-theme-board stage 1

* feat(projects): feedback-theme-board stage 2

* feat(projects): feedback-theme-board stage 3

* feat(projects): feedback-theme-board stage 4

* feat(projects): harness-bench stage 1

* feat(projects): harness-bench stage 2

* feat(projects): harness-bench stage 3

* feat(projects): harness-bench stage 4

* feat(projects): inbox-triage-desk stage 1

* feat(projects): inbox-triage-desk stage 2

* feat(projects): inbox-triage-desk stage 3

* feat(projects): inbox-triage-desk stage 4

* feat(projects): json-schema-output-guard stage 1

* feat(projects): json-schema-output-guard stage 2

* feat(projects): json-schema-output-guard stage 3

* feat(projects): json-schema-output-guard stage 4

* feat(projects): llm-gateway-with-fallbacks stage 1

* feat(projects): llm-gateway-with-fallbacks stage 2

* feat(projects): llm-gateway-with-fallbacks stage 3

* feat(projects): llm-gateway-with-fallbacks stage 4

* feat(projects): local-model-eval-harness stage 1

* feat(projects): local-model-eval-harness stage 2

* feat(projects): local-model-eval-harness stage 3

* feat(projects): local-model-eval-harness stage 4

* feat(projects): mcp-at-scale stage 1

* feat(projects): mcp-at-scale stage 2

* feat(projects): mcp-at-scale stage 3

* feat(projects): mcp-at-scale stage 4

* feat(projects): mcp-at-scale stage 5

* feat(projects): meeting-notes-to-actions stage 1

* feat(projects): meeting-notes-to-actions stage 2

* feat(projects): meeting-notes-to-actions stage 3

* feat(projects): meeting-notes-to-actions stage 4

* feat(projects): memory-server stage 1

* feat(projects): memory-server stage 2

* feat(projects): memory-server stage 3

* feat(projects): memory-server stage 4

* feat(projects): multi-agent-code-review-panel stage 1

* feat(projects): multi-agent-code-review-panel stage 2

* feat(projects): multi-agent-code-review-panel stage 3

* feat(projects): multi-agent-code-review-panel stage 4

* feat(projects): postmortem-writer stage 1

* feat(projects): postmortem-writer stage 2

* feat(projects): postmortem-writer stage 3

* feat(projects): postmortem-writer stage 4

* feat(projects): pr-review-reporter stage 1

* feat(projects): pr-review-reporter stage 2

* feat(projects): pr-review-reporter stage 3

* feat(projects): pr-review-reporter stage 4

* feat(projects): prompt-regression-tester stage 1

* feat(projects): prompt-regression-tester stage 2

* feat(projects): prompt-regression-tester stage 3

* feat(projects): prompt-regression-tester stage 4

* feat(projects): rag-freshness-pipeline stage 1

* feat(projects): rag-freshness-pipeline stage 2

* feat(projects): rag-freshness-pipeline stage 3

* feat(projects): rag-freshness-pipeline stage 4

* feat(projects): report-judge stage 1

* feat(projects): report-judge stage 2

* feat(projects): report-judge stage 3

* feat(projects): report-judge stage 4

* feat(projects): research-report-agent stage 1

* feat(projects): research-report-agent stage 2

* feat(projects): research-report-agent stage 3

* feat(projects): research-report-agent stage 4

* feat(projects): research-report-agent stage 5

* feat(projects): research-report-agent stage 6

* feat(projects): research-report-agent stage 7

* feat(projects): retrieval-evaluation-lab stage 1

* feat(projects): retrieval-evaluation-lab stage 2

* feat(projects): retrieval-evaluation-lab stage 3

* feat(projects): retrieval-evaluation-lab stage 4

* feat(projects): rust-agent-shell stage 1

* feat(projects): rust-agent-shell stage 2

* feat(projects): rust-agent-shell stage 3

* feat(projects): rust-agent-shell stage 4

* feat(projects): sandbox-ladder stage 1

* feat(projects): sandbox-ladder stage 2

* feat(projects): sandbox-ladder stage 3

* feat(projects): sandbox-ladder stage 4

* feat(projects): self-improving-skill-loop stage 1

* feat(projects): self-improving-skill-loop stage 2

* feat(projects): self-improving-skill-loop stage 3

* feat(projects): self-improving-skill-loop stage 4

* feat(projects): semantic-notes-search stage 1

* feat(projects): semantic-notes-search stage 2

* feat(projects): semantic-notes-search stage 3

* feat(projects): semantic-notes-search stage 4

* feat(projects): skill-installer stage 1

* feat(projects): skill-installer stage 2

* feat(projects): skill-installer stage 3

* feat(projects): skill-installer stage 4

* feat(projects): skill-router stage 1

* feat(projects): skill-router stage 2

* feat(projects): skill-router stage 3

* feat(projects): skill-router stage 4

* feat(projects): skill-scanner stage 1

* feat(projects): skill-scanner stage 2

* feat(projects): skill-scanner stage 3

* feat(projects): skill-scanner stage 4

* feat(projects): skill-validator stage 1

* feat(projects): skill-validator stage 2

* feat(projects): skill-validator stage 3

* feat(projects): skill-validator stage 4

* feat(projects): source-grounded-study-coach stage 1

* feat(projects): source-grounded-study-coach stage 2

* feat(projects): source-grounded-study-coach stage 3

* feat(projects): source-grounded-study-coach stage 4

* feat(projects): support-agent-with-google-adk stage 1

* feat(projects): support-agent-with-google-adk stage 2

* feat(projects): support-agent-with-google-adk stage 3

* feat(projects): support-agent-with-google-adk stage 4

* feat(projects): tiny-coding-agent stage 1

* feat(projects): tiny-coding-agent stage 2

* feat(projects): tiny-coding-agent stage 3

* feat(projects): tiny-coding-agent stage 4

* feat(projects): token-counter-and-cost-meter stage 1

* feat(projects): token-counter-and-cost-meter stage 2

* feat(projects): token-counter-and-cost-meter stage 3

* feat(projects): token-counter-and-cost-meter stage 4

* feat(projects): tool-call-firewall stage 1

* feat(projects): tool-call-firewall stage 2

* feat(projects): tool-call-firewall stage 3

* feat(projects): tool-call-firewall stage 4

* feat(projects): typed-workflow-agent-with-mastra stage 1

* feat(projects): typed-workflow-agent-with-mastra stage 2

* feat(projects): typed-workflow-agent-with-mastra stage 3

* feat(projects): typed-workflow-agent-with-mastra stage 4

* feat(projects): visual-evidence-library stage 1

* feat(projects): visual-evidence-library stage 2

* feat(projects): visual-evidence-library stage 3

* feat(projects): visual-evidence-library stage 4

* feat(projects): voice-note-transcriber-pipeline stage 1

* feat(projects): voice-note-transcriber-pipeline stage 2

* feat(projects): voice-note-transcriber-pipeline stage 3

* feat(projects): voice-note-transcriber-pipeline stage 4

* feat(projects): web-change-brief stage 1

* feat(projects): web-change-brief stage 2

* feat(projects): web-change-brief stage 3

* feat(projects): web-change-brief stage 4

* feat(projects): workflow-hooks stage 1

* feat(projects): workflow-hooks stage 2

* feat(projects): workflow-hooks stage 3

* feat(projects): workflow-hooks stage 4

* feat(projects): publish the practical application catalog

* feat(projects): add 52 planned builds to the roadmap

* fix(projects): make lesson animations explain computed changes

Stage mechanisms should expose the decisions learners are implementing. Preserve record identity as state changes and keep project context below the selected lesson.

* fix(projects): agent-budget-planner stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): agent-budget-planner stage 02 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): agent-budget-planner stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): agent-budget-planner stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): agent-trace-debugger stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): browser-agent stage 02 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): browser-agent stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): browser-agent stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): calendar-focus-planner stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): cloud-agent-with-aws-strands stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): cloud-agent-with-aws-strands stage 02 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): cloud-agent-with-aws-strands stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): desktop-control stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): distributed-eval-farm stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): distributed-eval-farm stage 02 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): distributed-eval-farm stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): document-extraction-desk stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): durable-agent-jobs stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): durable-agent-jobs stage 02 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): durable-agent-jobs stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): durable-agent-jobs stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): feedback-theme-board stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): inbox-triage-desk stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): llm-gateway-with-fallbacks stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): llm-gateway-with-fallbacks stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): mcp-at-scale review corrections

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): meeting-notes-to-actions stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): meeting-notes-to-actions stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): memory-server stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): pr-review-reporter stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): pr-review-reporter stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): pr-review-reporter stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): research-report-agent stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): retrieval-evaluation-lab review corrections

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): rust-agent-shell stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): rust-agent-shell stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): semantic-notes-search stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): skill-installer review corrections

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): skill-router stage 02 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): skill-router stage 04 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): tiny-coding-agent stage 02 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): voice-note-transcriber-pipeline stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): web-change-brief stage 03 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): workflow-hooks stage 01 contracts

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* fix(projects): site review corrections

Keep the stage contract, learner scaffold and verification evidence
consistent at the reviewed failure boundary.

* docs(projects): record verified review corrections
2026-09-29 21:38:54 +05:30
Rohit Ghumare a05d392590 fix: repair broken lesson references and guard homepage storage (#495)
* fix(site): guard theme storage access on the homepage and about page

Reading or writing localStorage throws a SecurityError when storage is
blocked (strict privacy settings, some embedded webviews). site/app.js
read the saved theme outside any try/catch, before it registered its
DOMContentLoaded handler, so the throw stopped the whole homepage from
initializing. The about page's inline theme script had the same
unguarded read and write.

Wrap all four accesses the way the other pages already do and fall
back to the system theme. Bump the app.js cache key so browsers pick
up the fix, and give app.js its own release constant in the cache-key
test.

Fixes #490

* fix(lessons): repair dataset, model, and tool references that no longer resolve

Lesson snippets pointed at resources that are gone or never existed, so
they fail when a student runs them:

- wikimedia/wikipedia only ships 20231101.* configs; 20220301.en is gone
- MMAU-Pro lives at gamma-lab-umd/MMAU-Pro, with audio_path and answer
  fields; open-ended rows are filtered out of the exact-match score
- meta-llama/Llama-3-70B-Instruct is meta-llama/Meta-Llama-3-70B-Instruct
- Depth Anything V2 for transformers is
  depth-anything/Depth-Anything-V2-Large-hf
- microsoft/deberta-v3-large-mnli and microsoft/BEATs-base are not on
  the Hub; BEATs checkpoints ship with microsoft/unilm
- sayakpaul/sd-lora-ghibli does not exist; use a published SD 1.5
  Ghibli LoRA with its trigger phrase
- Qwen/Qwen3-0.6B-spec and meta-llama/Llama-3.2-1B-Instruct-spec are
  not real draft models
- gemini-3-pro is not a Gemini model code, gemini-1.5-pro is shut down,
  and the google.generativeai SDK reached end of life on 2025-11-30
- vLLM replaced --speculative-model and --num-speculative-tokens with
  --speculative-config, and --dtype has no float8_e4m3fn choice
- convert_hf_to_gguf.py cannot write q4_k_m; llama-quantize does
- AutoGPTQ and AutoAWQ are archived; GPTQModel and LLM Compressor are
  the maintained successors, and vLLM reads their quantization method
  from the checkpoint config

Fixes #493

* fix(lessons): replace dead reference links

A link check over every lesson found 46 references that return 404 or
410 or no longer resolve. Each replacement was fetched and matched
against the cited title or content:

- pages that moved on the same site: vLLM, librosa, Letta, Apollo
  Research, Stability AI, NVIDIA, NeurIPS, the MCP spec, the Claude
  docs, the A2A spec, the Julia docs, W&B, Baseten, and Arena (formerly
  LMSYS Chatbot Arena, whose old domain no longer resolves)
- papers and books pointed at DOIs or publisher pages: Friedman on
  gradient boosting, Golub and Van Loan, Kuttruff, Littman's thesis,
  Milne and Witten, and Zave and Jackson (whose DOI was wrong)
- Wayback snapshots where the source only survives in the archive:
  Poynton's color space tour and a model-routing article
- citations of pages that never existed replaced with the real source:
  the DINOv2 paper, the MMAU-Pro project page, Anthropic's Contextual
  Retrieval post, the February 2026 risk report, and the correct
  Anthropic alignment post
- removed where no source exists: a Spinning Up DQN page, the
  andrewgarst/agentic_harness repo, and an Akira blog post

URLs in code-file reference headers get the same treatment.

* chore(site): rebuild data.js

* Revert "chore(site): rebuild data.js"

The main-only CI job rebuilds site/data.js after merge, so the PR
should not carry it; a stale "Last built" line would conflict.

This reverts commit e78e5def.

* fix(lessons): correct claims flagged in review

Each finding was checked against its primary source before changing
anything:

- vLLM: the v0.18.0 feature matrix marks speculative decoding as
  compatible with chunked prefill (and incompatible with LoRA), so the
  "draft model plus chunked prefill does not compile" gotcha was false.
  It is replaced in both lessons, their skills, the scheduler and
  EAGLE-3 diagrams, and the quiz question that asserted it
- alignment faking: the cited Anthropic post tests interrogation
  training, scratchpad length penalties, and process supervision, not
  a compliance-gap loss or faithful-CoT training. The section, learning
  objective, exercise, reference, skill, diagram, and quiz now match it
- Gemini: Google limits the 2.5 models to existing users and points new
  projects to 3.5 Flash-Lite or 3.8 Flash, so both examples use
  gemini-3.8-flash (GA, caching supported, 1M context), and the
  context comparison names GPT-4o's 128K window instead of Claude
- vLLM FP8: --quantization fp8_per_tensor, which the 0.30.0 release
  accepts and main recommends over the deprecated fp8
- GGUF: the converter has no K-quant output; it does write f32 and
  ternary files, which the old wording ruled out
- MMAU-Pro: the exact-match loop is labeled a sanity check, with the
  official evaluator (embedding match, LLM judge, regex rules) named
- Depth Anything: the pipeline example is labeled V2, with the separate
  depth_anything_3 package described for V3, and the missing numpy
  import added
- audio classification: Step 5 is titled for the AST example it runs,
  with BEATs loading described beneath it

The repo's quiz de-biaser moved one rewritten question's correct answer
to its assigned position.

* fix(lessons): drop the speculative decoding and LoRA incompatibility

The v0.18.0 docs matrix marks speculative decoding with LoRA as
unsupported, but vLLM has supported LoRA with speculative decoding on
the V1 GPU engine since vllm-project/vllm#21068 (merged 2025-11-08), so
calling the pair incompatible steers learners away from valid setups.
Remove the claim from both serving lessons, their skills, and both
diagrams. The rollout skill's hard reject now names an incompatibility
the speculative-decoding docs do list: pipeline parallelism on vLLM
0.15.0 or earlier.
2026-09-27 15:38:59 +05:30
Rohit Ghumare 744520ac08 fix(site): refresh cached header for newsletter signup (#494) 2026-09-27 11:27:55 +05:30
Rohit Ghumare 6c0c06dce2 feat(site): add Substack newsletter signup (#492)
* feat(site): add Substack newsletter signup

* fix(site): restore compact newsletter signup design
2026-09-27 11:20:26 +05:30
Rohit Ghumare 4b9c61beb2 feat(site): animate the MCPA and Claude certification figures (#489)
* feat(site): animate the Claude certification labs

Each Claude certification lab now opens its output with an animated
strip. The inputs flow into the formula and then into the result: a
gauge for threshold, equation, and readiness labs, one bar per option
for decision labs, and a stage rail for pipeline labs. The strip
replaces the HTML meter bars and stage cards that showed the same
values.

The labs now share one builder and use the course lf card markup, so
the runtime names each SVG from the card title and caption. Bars grow
through stroke-dash rather than transforms, because the runtime marks
nodes it reconciles after a slider drag with transform-origin center.
The redundant control labelling is gone, since LF.slider and LF.select
already bind their labels.

* feat(site): animate the MCPA certification figures

The 34 MCPA lesson figures were static SVG strings. Each one now builds
its diagram with a small shared SMIL kit and plays the mechanism in
causal order: messages draw along their arrows with a packet at the
tip, gates light up when a request reaches them, and outcomes grow in
when the packet arrives. Each loop holds the finished diagram, fades,
and restarts. Only opacity, transform, stroke-dashoffset, and motion
are animated, so every animation loops and no replay button appears,
and each figure sets its reduced-motion and print frame to the
complete diagram.

Text, facts, and layout carry over, apart from fixes where the
original overflowed a box or the viewBox, put a label on top of a
line, or left an empty table column. Cards now use the course lf
markup, so the runtime names each SVG from the card title and caption,
and the original aria-label text becomes the SVG description instead
of being overridden by aria-labelledby.

Below 640px wide, the diagram scrolls sideways inside its card at a
readable size, where it used to shrink labels to about 5px.
2026-09-25 21:16:11 +05:30
Rohit Ghumare 38ed3c95b0 fix(site): show published exam facts on certification cards (#487)
Catalog cards show a track's first three exam facts: questions, time
limit, and passing score. The official MCPA page publishes only the
90-minute duration, so the MCPA card read "Not published" twice out of
three and looked broken. Cards now skip facts a track marks
unpublished and fill the row with the next published ones, so the
MCPA card shows its time limit, exam fee, and format. Claude cards are
unchanged, and the track page still lists every fact, including the
ones the provider does not publish.
2026-09-25 10:45:50 +05:30
Rohit Ghumare 352b2eac89 fix(readme): rebuild the banner curriculum stack so every phase appears once (#486)
The banner's curriculum stack skipped Phase 11 (LLM Engineering), grouped
Generative AI and Multimodal under "LLMs · Transformers", drew
translucent layers whose edges showed through each other, and ran its
last label into the right edge past the 56px margin the header keeps.

The stack is now eight solid slabs with thickness, foundations at the
bottom and capstones on top, covering phases 00 to 19 exactly once and
in order: setup and math, ML and deep learning, vision, NLP, and
speech, transformers and generative AI, RL and LLMs, multimodal and
tools, agents and swarms, then production, safety, and capstones. Each
label sits on its slab's corner, and every label stays inside the
margin. The left column gains a certification line for the Claude and
MCPA preparation tracks, and the separators drop em and en dashes. The
count line is unchanged and still pinned by the build test.
2026-09-25 10:41:33 +05:30
Rohit Ghumare 2341733d60 fix(readme): redraw the FIG_001 artifact icons so no label collides with geometry (#485)
The four "every lesson ships something" icons had collisions at README
size: the agent loop's arc ran through the TOOL box and its label, OBS
sat on its box edge with a detached arrowhead, the MCP labels hung
outside the rack at about 4px, and the skill icon ended in a stray plug
shape. The README also drew the 120-unit artwork at 96px, shrinking
every label by a fifth.

Each icon is redrawn on the same grid in the blueprint style: a
prompt page with a >_ line sent to the model, a SKILL.md file dropping
into an agent's skills tray, the agent loop as LLM to TOOL to OBS and
back, and an MCP server whose tools, resources, and prompts are labeled
inside its units with a two-way client link. Every label sits inside
its container with clearance, checked by bounding-box tests at 96, 120,
and 360px, and the README renders the icons at their native 120px.
The translated READMEs are regenerated.
2026-09-25 10:31:33 +05:30
Rohit Ghumare 9f06b4b740 feat(certifications): MCPA exam prep on the MCP 2026-07-28 protocol (#484)
* feat(mcpa): add MCPA program, track blueprint, and source ledger

Start the Model Context Protocol Associate certification prep, mirroring the
Claude certification system. Adds the program manifest, the mcpa-f track with
the five published domains and weights (Fundamentals 16, Architecture 14,
Interactions 26, Security 24, Use Cases 20) and exam mechanics, and a source
verification ledger that maps every exam fact to the official certification
page, the launch announcement, and the MCP 2026-07-28 specification with the
retrieval date. Objectives are original, derived from the published
sub-competency names and the specification.

* feat(mcpa): add the MCP fundamentals lesson and figure runtime

First MCPA cert lesson, mirroring the Claude certification lesson contract: a
concept-first explainer of the integration problem MCP solves, the four roles,
and the handshake, discovery, and invocation flow, with a stdlib JSON-RPC mock
(no SDK, no network), five-plus tests, a six-question quiz, a field-brief
artifact, and a registered host-client-server figure. Aligned to MCP 2026-07-28.

* feat(certifications): make cert audit + debias provider-aware

Discover providers via certifications/*/program.json and run the same
contract per provider instead of hardcoding certifications/claude.

- audit_certifications.py: PROVIDERS registry + use_provider(slug);
  check_public_pages runs once, run_provider_audit(audit, slug) per
  provider; LESSON_REF_PREFIX / PROVIDER_ENTITY / PROVIDER_AI_NATIVE_SURFACE
  replace the former claude-only literals; AI-native-surface check gated
  per provider.
- debias_certification_questions.py: glob certifications/*/lessons and
  certifications/*/assessments.
- claude verdict unchanged: 33 lessons, 8 assessments, 295 questions, 0 issues.
- balance mcpa lesson 01 quiz answer positions and option lengths.

* feat(certifications): add MCPA cert README and generalize route-count regex

- certifications/mcpa/README.md: route table (MCPA, 10 lessons), blueprint
  weights, AI-tutor onboarding, GitHub lesson index, non-affiliation notice;
  states the official item count and passing score are not published and the
  90-vs-120 minute source discrepancy.
- audit_certifications.py: widen the README route-count regex from CC-only to
  any uppercase exam code so MCPA is parsed; claude codes still match and the
  claude verdict stays 0 issues.

* feat(certifications): build MCPA track lessons, figures, and wiring

- Nine new lessons (00, 02-09) covering all five MCPA domains. Each ships a
  concept-first doc, a standard-library MCP mock in code/main.py, a Python
  test suite (88 lesson tests total, all passing), a six-question quiz, a
  reusable output artifact, and a mechanism figure.
- site/figures-mcpa-certifications.js: register all ten lesson figures
  (mcpa-00 through mcpa-09), each a themed inline-SVG diagram; render-checked.
- tracks/mcpa-f.json: wire the ten lessons to their domains and roles.
- prerequisites.json: linear lesson dependency chain over all ten lessons.
- audit_certifications.py: enforce the mcpa expectedFigures map.

* feat(certifications): add MCPA assessments and AI-native tutor surface

Completes the MCPA certification track. Full audit is green: 43 lessons,
10 assessments, 380 questions, 0 issues; the Claude verdict is unchanged
(33 lessons, 8 assessments, 295 questions).

- assessments/mcpa-f/diagnostic.json (25 questions) and mock-01.json (60
  questions) with the blueprint domain mix (10/8/16/14/12); every question
  maps to a declared domain objective and cites an existing lesson for
  remediation. Declared in tracks/mcpa-f.json.
- debias pass balances answer positions across the ten lesson quizzes and
  the two assessments.
- skills/mcpa-certification (SKILL.md + agents/openai.yaml) and its
  .claude/skills mirror: an AI-native tutor for the MCPA route, mirroring
  the Claude certification tutor.
- certifications/mcpa/GETTING_STARTED.md: the GitHub learner guide.
- curriculum.yml: run certification lab tests and demos for every provider,
  not just Claude.
- README.md: MCPA onboarding section and quick-start row.

* feat(certifications): add MCP 2026-07-28 protocol brief and wire-shape checker

The MCPA exam is aligned to the 2026-07-28 revision, which made MCP
stateless (SEP-2575, SEP-2567): no initialize handshake, no sessions,
per-request _meta version and capabilities, mandatory server/discover,
Multi Round-Trip Requests instead of server-initiated requests (SEP-2322),
a required resultType, subscriptions/listen, cacheable list results
(SEP-2549), and a new error-code allocation policy.

- certifications/mcpa/research/mcp-2026-07-28-brief.md: the protocol
  source of truth for every MCPA lesson and question, read from the
  primary specification pages, schema.ts, the extension pages, and the
  SEPs, with a table of exam traps where legacy-era beliefs are now wrong.
- scripts/check_mcpa_wire.py: imports each MCPA lesson's transcript() and
  enforces the 2026-07-28 wire invariants (required _meta fields,
  resultType, cache hints on the six cacheable operations, MRTR retry
  rules, subscription ids on listen streams, header and body agreement,
  the error-code allocation policy) and rejects legacy methods such as
  initialize unless a lesson marks them as compatibility examples.
- scripts/test_check_mcpa_wire.py: 16 tests for the checker's rules.

* refactor(certifications): restructure the MCPA track for the stateless 2026-07-28 protocol

The first MCPA build taught the legacy initialize handshake as current,
answered unknown tools with -32601 and schema-invalid arguments with
-32602, and allocated custom errors in the legacy -32000..-32019 range.
MCP 2026-07-28 removed the handshake and sessions (SEP-2575, SEP-2567),
made input validation a tool execution error (SEP-1303), and partitioned
the server-error range into a legacy block and an MCP-reserved block.

- remove the nine lessons and two assessments built on the legacy model
- rewrite the 18 domain objectives against 2026-07-28: the stateless
  core, discovery and capability negotiation, Multi Round-Trip Requests,
  subscriptions, caching, extensions, and the deprecation lifecycle
- lay out a 34-lesson route across the five domains with a prerequisite
  chain and the expected figure for each lesson
- link all 17 phase 13 MCP lessons as deep dives

* feat(mcpa): integration-problem lesson on the stateless core

- one client discovers and calls two unrelated servers using per-request
  _meta (protocolVersion, clientCapabilities, clientInfo) and
  server/discover with cache hints, with no handshake or session
- N times M versus N plus M integration arithmetic
- the two error channels: an unknown tool is a -32602 protocol error, a
  missing argument is an isError tool execution error the model can fix
  (SEP-1303)
- UnsupportedProtocolVersion -32022 carrying data.supported and
  data.requested
- transcript() passes scripts/check_mcpa_wire.py; this lesson is the
  structural exemplar for the rest of the track

* feat(mcpa): discovery and capability negotiation lesson

- server/discover as the only discovery call a server must implement:
  DiscoverResult with supportedVersions, capabilities, instructions,
  serverInfo, and CacheableResult hints (ttlMs, cacheScope)
- server capabilities are cached per server; client capabilities are
  declared fresh on every request in _meta
- MissingRequiredClientCapability (-32021) with data.requiredCapabilities
  when a tool needs elicitation the request did not declare
- UnsupportedProtocolVersion (-32022) then a retry with a supported
  version and a new request id; era is message shape, not version string
- unknown tool (-32602) versus unknown method (-32601)

* feat(mcpa): stateless core lesson

- statelessness as a protocol invariant (SEP-2575): every request carries
  its own version and capabilities, no initialize, no session
- two replicas behind a round-robin router serve interleaved requests
  from one shared store, so any replica answers any request
- cross-request state through opaque server-minted handles (SEP-2567):
  authorized per call, bounded lifetime, expiry and foreign-principal
  use returned as isError tool execution errors
- list results identical across connections; a request without the
  required _meta fields rejected with -32602

* feat(mcpa): hosts, clients, and servers topology lesson

- one client per server inside the host, with local stdio and remote
  Streamable HTTP servers and trust following process and network
  boundaries
- server features (tools, resources, prompts, completion) versus client
  features (elicitation; sampling and roots deprecated) and the control
  model: model-controlled tools, application-driven resources,
  user-controlled prompts
- host aggregation across servers: tool-name collisions resolved by
  server-id prefixing, serverInfo.name never used as a routing key
  because it is self-reported and not unique
- capability-gated discovery: no tools/list against a server that did
  not declare the tools capability

* feat(mcpa): exam strategy lesson for the 34-lesson route

- blueprint-weighted study allocation and weighted readiness (a heavy
  domain moves the estimate more than a plain average)
- exam mechanics from the source ledger, including the 90-minute page
  value versus the 120-minute launch announcement
- a reading strategy for legacy-era distractors: the initialize
  handshake, sessions, and -32601 for an unknown tool
- the full 34-lesson route with its domain tags, validated so every
  lesson and every domain is covered; the capstone spans all five

* feat(mcpa): tool schema and structured content lesson

- tool definition fields and naming rules (1 to 128 characters of
  A-Za-z0-9_-., unique per server, aggregator prefixing)
- JSON Schema 2020-12 as the default dialect (SEP-1613), any 2020-12
  keyword allowed (SEP-2106), and the recommended no-parameter schema
- network $ref never auto-dereferenced; the registration path refuses it
- outputSchema with structuredContent plus a serialized text mirror
- schema-invalid arguments returned as isError tool execution errors
  (SEP-1303); -32602 kept for unknown tools and missing _meta, with the
  legacy behavior shown only as a labeled counterexample

* feat(mcpa): JSON-RPC envelope and _meta lesson

- the four message shapes under MCP: requests with a non-null unique id,
  results that must carry resultType, errors, and id-less notifications
  that are never answered; no batching
- resultType semantics: complete, input_required, unknown values
  invalid, absent treated as complete for earlier servers
- _meta key grammar (optional reverse-DNS prefix plus name) and the
  reserved-prefix rule on the second label: io.modelcontextprotocol and
  dev.mcp reserved, com.example.mcp not
- the reserved keys, including the OpenTelemetry traceparent, tracestate,
  and baggage exception (SEP-414)
- a request missing protocolVersion or clientCapabilities rejected with
  -32602, shown next to three labeled malformed messages

* feat(mcpa): reading server manifests lesson

- review a server/discover result, a tools/list page, and a registry
  server.json before any tool is called
- tool annotation defaults applied when omitted (readOnlyHint false,
  destructiveHint true and only meaningful when not read-only,
  idempotentHint false, openWorldHint true), treated as untrusted hints
- x-mcp-header rules: HTTP token syntax, case-insensitive uniqueness, no
  number types, never on secrets
- cacheScope as a sharing hint, not access control; instructions as
  self-reported text that can try to steer the model
- reverse-DNS registry namespaces tied to verified owners
- a manifest linter that flags six defects in a careless server and none
  in a clean one

* feat(mcpa): reading the specification lesson

- how the 2026-07-28 specification is organized and the floor every
  implementation must support (base protocol, versioning, message
  patterns) versus optional components
- RFC 2119 and RFC 8174 keyword strength, including the capitals rule
- schema.ts as the source of truth and schema.json as generated output
- revision states (Draft, Current, Final) versus feature states (Active,
  Deprecated, Removed) under the lifecycle policy (SEP-2596): a 12-month
  minimum window measured from the deprecating revision's release, and
  the earliest removal on or after it
- JSON-RPC batching (added 2025-03-26, removed 2025-06-18) as the
  reversal the lifecycle policy was written to prevent
- tracing changelog entries back to their SEPs

* feat(mcpa): resources primitive lesson

- resources/list, resources/read, and resources/templates/list with an
  RFC 6570 template, text and base64 blob contents, and a directory read
  returning several contents
- resource not found as -32602 with data.uri (SEP-2164), never -32002 and
  never an empty contents array
- URI scheme choice: https only when the client can fetch directly;
  file, git, or a custom scheme otherwise
- traversal-safe resolution of file URIs so a path containing ".." can
  never escape the served root
- cache hints on every cacheable result, with a private cacheScope for
  user-specific content

* feat(mcpa): prompts and argument completion lesson

- prompts as user-controlled templates: prompts/list with pagination and
  cache hints, prompts/get substituting arguments into messages that can
  carry resource links
- unknown prompt, missing required argument, and invalid cursor all
  reported as -32602
- completion/complete for ref/prompt and ref/resource references, with
  context.arguments narrowing later suggestions
- the 100-value cap with total and hasMore, exercised against a real
  catalog larger than the cap

* feat(mcpa): error handling lesson

- protocol errors versus tool execution errors (SEP-1303): an unknown
  tool stays -32602, invalid or missing arguments return isError results
  the model can correct
- MCP-reserved codes with their data shapes: HeaderMismatch -32020,
  MissingRequiredClientCapability -32021 (data.requiredCapabilities),
  UnsupportedProtocolVersion -32022 (data.supported, data.requested)
- the 2026-07-28 allocation policy enforced in code: a guard refuses the
  legacy -32000..-32019 block, retired -32002 and -32042, and undefined
  reserved codes before any response is built
- HTTP status mapping only where the specification states one (400,
  404, 202, 401, 403, 405); statuses the spec leaves open are marked so

* feat(mcpa): client registration and identity lesson

- registration priority: pre-registered credentials, Client ID Metadata
  Documents when the authorization server advertises support,
  deprecated Dynamic Client Registration, then asking the user
- CIMD validation: an HTTPS client_id with a path, exact client_id match,
  required fields, and redirect URI checks (SEP-991)
- application_type native versus web for DCR clients
- credentials keyed by issuer and never reused across authorization
  servers; re-registration when the authorization server changes
- per-client consent at a proxy to prevent the confused-deputy attack
- the OAuth Client Credentials and Enterprise-Managed Authorization
  extensions for machine-to-machine and IdP-governed access

* feat(mcpa): deprecated client features lesson

- roots, sampling, and logging deprecated by SEP-2577 but still valid in
  2026-07-28: roots/list and sampling/createMessage travel as MRTR
  inputRequests, gated by declared client capabilities (-32021 when
  missing)
- per-request io.modelcontextprotocol/logLevel with notifications/message
  only on that request's own stream, and -32602 for an unknown level
- removed versus deprecated: logging/setLevel and
  notifications/roots/list_changed are gone (SEP-2575), shown only as a
  labeled legacy contrast
- earliest removal computed from the 12-month window, with migration
  paths for each feature, DCR, includeContext, and HTTP+SSE

* feat(mcpa): multi round-trip requests and elicitation lesson

- MRTR replacing server-initiated requests (SEP-2322): an input_required
  result with inputRequests and requestState, then a retry with a new id,
  inputResponses, and the state echoed exactly
- requestState protected with an HMAC that binds the principal, a short
  expiry, a digest of the originating request, and a single-use nonce
- tampering, expiry, cross-principal replay, and a retargeted retry all
  rejected before any side effect
- form-mode elicitation with accept, decline, and cancel; URL mode for
  out-of-band sensitive steps (SEP-1036); a client without the
  elicitation capability refused with -32021

* feat(mcpa): risk and safety controls lesson

- a threat model mapped to the clause that mitigates each threat: tool
  poisoning, prompt injection through results, rug pulls, tool
  shadowing, confused deputy, token passthrough, requestState tampering,
  SSRF through CIMD fetches and network $ref, DNS rebinding, malicious
  icons, and supply-chain drift
- a gateway that pins tool definitions by hash and holds a changed
  definition for review, quarantines descriptions carrying injected
  instructions, refuses network $ref, blocks token passthrough, and
  enforces a per-tool rate limit
- policy refusals returned as isError tool results, never as invented
  codes in the reserved -32000..-32099 range

* feat(mcpa): tools primitive lesson

- tools/list with opaque cursors (an empty-string cursor still means more
  pages), cache hints, and results identical across connections
- CallToolResult: content, structuredContent, and isError defaulting to
  false
- every content block type (text, image, audio, resource_link, embedded
  resource) with audience, priority, and lastModified annotations; an
  embedded resource's annotations sit beside resource, per schema.ts
- tool annotation defaults (readOnlyHint false, destructiveHint true,
  idempotentHint false, openWorldHint true) treated as untrusted hints
- listChanged through subscriptions/listen, from acknowledgment to
  notifications/tools/list_changed to a fresh tools/list

* feat(mcpa): notifications, subscriptions, and cancellation lesson

- subscriptions/listen replacing resources/subscribe and the HTTP GET
  stream: the notification filter, the acknowledgment as the first
  message, and subscriptionId equal to the listen request id so several
  subscriptions can be demultiplexed
- stream notifications (list_changed, resources/updated) versus
  request-scoped progress and message notifications that never travel on
  a listen stream
- progress tokens with strictly increasing progress
- cancellation per transport: closing the SSE stream on HTTP,
  notifications/cancelled on stdio; the server sends that notification
  only to tear down a listen stream; graceful closure and late-message
  races
- a fresh subscriptions/listen after a stdio reconnect

* feat(mcpa): transports and HTTP header contract lesson

- stdio: newline-delimited framing with embedded newlines rejected,
  stdout reserved for MCP messages, stderr for logs, cancellation by
  notification, shutdown by closing stdin
- Streamable HTTP without sessions: one POST endpoint, JSON or
  per-request SSE responses, 202 for notifications, 405 for GET and
  DELETE, no resumability
- Origin validation with 403 and localhost binding against DNS rebinding
- the header contract (SEP-2243): MCP-Protocol-Version, Mcp-Method, and
  Mcp-Name mirrored from the body, x-mcp-header parameters as
  Mcp-Param-{Name}, and base64 sentinel encoding checked against the
  specification's own worked examples
- a header-body mismatch rejected with 400 and HeaderMismatch -32020

* feat(mcpa): trust zones lesson

- five trust zones in one exchange: user and host, client, server,
  upstream systems, and the model
- every untrusted input that reaches model context labeled and
  quarantined: tool descriptions, annotations, icons, results, and
  resource contents
- clientInfo and serverInfo treated as self-reported display data
- multi-server isolation: an instruction embedded in one server's result
  cannot trigger a call on another server
- annotations from an untrusted server fall back to safe defaults;
  icon URIs other than https or data rejected
- local server launch commands accepted only from the host's own
  configuration (SEP-1024)

* docs(mcpa): record primary-source conflicts resolved during the lesson build

Seven places where specification pages, schema.ts, and SEP texts
disagree, each with the normative resolution: removed versus deprecated
roots and logging methods (SEP-2575 over SEP-2577's feature grouping),
embedded-resource annotation placement (schema.ts over the rendered
example), notification-POST headers, requestState rejection channel,
HTTP statuses for three JSON-RPC codes, server-side subscription
teardown, and tool-name format (published page over SEP-986's draft).
Points the specification leaves open are marked so assessments never
test them as a single rule.

* feat(mcpa): model interaction flow lesson

- the host loop from user request through model selection, tools/call,
  and back into model context, driven by a deterministic scripted model
- tool execution errors (isError true) fed back to the model and
  corrected on a new request id; protocol errors such as an unknown tool
  (-32602) never retried blindly
- an input_required result gathered from a human through
  elicitation/create and retried with a new id, inputResponses, and the
  requestState echoed exactly
- a tool with no annotations treated as destructive under the
  specification defaults: one call confirmed and sent, one denied and
  never put on the wire
- deterministic tools/list ordering across identical calls

* feat(mcpa): cache freshness and cursor pagination lesson

- ttlMs and cacheScope on every cacheable result (SEP-2549): absent or
  negative ttlMs clamps to 0, cacheScope has no default
- public entries shared across tokens behind a shared cache, private
  entries never crossing identities, proven by server call counts
- input_required results and MRTR completions never cached
- opaque cursors, including an empty-string cursor that still means
  another page, and invalid cursors rejected with -32602
- notifications/resources/list_changed on a subscriptions/listen stream
  invalidating a cached list before its ttlMs runs out
- stable list ordering so client caches and model prompt caches see a
  byte-identical catalog

* feat(mcpa): audit trail and trace propagation lesson

- W3C traceparent in _meta (SEP-414): version, trace id, parent id, and
  flags validated as lowercase hex of exact length, all-zero ids
  rejected, tracestate and baggage passed through untouched
- a three-hop call (client, server, upstream server) where each hop
  mints a child span under the same trace id
- a hash-chained audit log recording the authenticated principal (never
  self-reported clientInfo), method, tool, redacted arguments, result
  channel, request id, and trace id
- tamper detection for both a naive edit and an edit that rewrites its
  own hash, caught one entry later through prev_hash
- denied attempts (unknown tool, bad bearer token) logged as protocol
  errors, not dropped
- deprecated logging replaced by stderr and OpenTelemetry, with the
  per-request logLevel still producing notifications/message

* feat(mcpa): long-running work and the tasks extension lesson

- the tasks extension (SEP-2663) negotiated per request: the client
  declares io.modelcontextprotocol/tasks in clientCapabilities and the
  server advertises it in server/discover
- a tool that runs synchronously without the extension and returns
  resultType task (CreateTaskResult) with it
- tasks/get polling through working, input_required, and completed,
  with tasks/get itself always a complete result
- mid-flight input supplied with tasks/update and inputResponses;
  cooperative cancellation with tasks/cancel
- -32602 for an unknown or expired taskId and -32021 naming the
  extension for a client that never declared it
- what changed from the 2025-11-25 experimental tasks: no tasks/result,
  no tasks/list, and no task parameter on tools/call
- choosing among a plain call, an MRTR round trip, and a task

* feat(mcpa): OAuth authorization lesson

- the three roles: the MCP server as resource server, the MCP client,
  and the authorization server
- Protected Resource Metadata discovery (RFC 9728): the
  WWW-Authenticate resource_metadata URL first, then the path-specific
  and root well-known fallbacks
- authorization server metadata discovery order for path and root
  issuers, with the issuer required to match
- PKCE S256 generated with the standard library, and the client
  refusing to proceed when code_challenge_methods_supported is absent
- the RFC 8707 resource parameter carrying the canonical server URI on
  both the authorization and token requests
- the RFC 9207 iss decision table, compared without normalization and
  applied to error responses too
- bearer tokens in the Authorization header on every request, audience
  validation, no token passthrough, and 401 versus 403 versus 400

* feat(mcpa): operational use-case selection lesson

- the control model as the first design question: model-controlled
  tools, application-driven resources, user-controlled prompts, and the
  skills extension for cataloged multi-step procedures
- local systems on stdio with credentials from the environment; remote
  systems on Streamable HTTP with the interactive OAuth flow, the client
  credentials extension for unattended callers, or enterprise-managed
  authorization for a central identity provider
- the tasks extension for long jobs and MCP Apps for interactive views,
  with a text fallback for hosts that do not declare the ui extension
- cacheScope chosen from data sensitivity, and a no-external-system case
  where MCP is not the right fit
- a decision engine that turns a use-case profile into a primitive,
  transport, auth path, and extension recommendation

* feat(mcpa): deployment roles and adoption lesson

- six deployment roles on top of the host, client, and server
  architecture: server author, host and client developer, platform or
  gateway operator, security and governance owner, registry publisher,
  and end user
- a responsibility matrix built from a catalog of exact MUST and SHOULD
  requirements with page citations, where the same requirement (Origin
  validation) moves from the server author to the gateway operator as
  the deployment shape changes
- gap reporting for a requirement no role owns
- stdio credentials supplied by the operator's environment and never
  carried on the wire
- governance: Agentic AI Foundation stewardship, the maintainer
  hierarchy and contributor ladder minimums, Working Groups versus
  Interest Groups, the SEP status workflow, and the feature lifecycle
- SDK tiers (SEP-1730) as an adoption risk decision: conformance,
  feature, triage, and critical-bug commitments per tier

* feat(mcpa): tool invocation lifecycle lesson

- eight checkpoints from discover and list through select, confirm,
  call, validate, execute, and result, with select and confirm as
  host-only steps that never touch the wire
- validate ends only in a protocol error (-32602 for an unknown tool);
  schema violations, upstream failures, and business-rule failures in
  execute become tool execution errors with isError true
- a genuine internal fault during execute surfaced as -32603
- notifications/progress bound to the request's progressToken with a
  strictly increasing progress value, and a hard timeout that progress
  does not extend
- transport-specific cancellation: closing the stream on Streamable HTTP,
  notifications/cancelled on stdio, and no cancelled or timed-out
  resultType
- reissuing after a broken stream with a new request id, guided by
  idempotentHint as an untrusted hint and a server-minted handle

* feat(mcpa): protocol eras and compatibility lesson

- the revision timeline from 2024-11-05 to 2026-07-28 and the legacy,
  modern, and dual-era terms
- the stdio probe for a dual-era client: server/discover first, a
  DiscoverResult or a recognized modern error such as -32022 means
  modern (retry with a supported version, never fall back), any other
  error or a timeout means legacy
- the fallback never keyed on one specific error code
- the Streamable HTTP probe: reading a 400 body for a recognized modern
  JSON-RPC error before assuming legacy
- era cached per server process on stdio or per origin on HTTP, with a
  re-probe when the cached assumption fails
- a modern-only server naming its supported versions when it rejects a
  legacy initialize, and the legacy opening sequence shown only inside
  wrapped legacy examples

* feat(mcpa): consent and least privilege lesson

- consent gathered through a multi round-trip request: a tools/call
  returns input_required with an elicitation/create request, and the
  retry carries a new id, inputResponses, and the signed requestState
- decline, cancel, and a rejected retry returned as tool execution
  errors with isError true, never an invented consent error code
- consent scoped per tool and bound to the approved arguments, with
  requestState signed, single-use, and rejected when a retry changes
  the arguments
- annotation defaults (destructiveHint and openWorldHint true,
  readOnlyHint false) deciding when to prompt, treated as untrusted
  hints rather than enforcement
- step-up authorization: a 403 insufficient_scope challenge, a new token
  requested for the union of granted and challenged scopes, and a retry
  cap when the scope is never granted
- tools/list filtered by granted scopes and cached with cacheScope
  private because it varies by authorization

* feat(mcpa): extensions framework lesson

- extension identifiers as {vendor-prefix}/{name}: the
  io.modelcontextprotocol/ prefix for official extensions and a reversed
  owned domain for third parties
- negotiation on every request: the client declares extensions in
  clientCapabilities and the server advertises its own in server/discover,
  with the settings object as the value
- an optional extension falling back to core behavior and a mandatory
  one rejected with -32021 naming it in data.requiredCapabilities
- extensions disabled by default and opt-in; a breaking change needs a
  new identifier
- the SEP-2133 process, experimental-ext- repositories owned by a
  Working Group or Interest Group, and the official roster: tasks, MCP
  Apps, skills, and the two authorization extensions
- what changed from initialize-time declaration to per-request
  negotiation

* feat(mcpa): registry, gateways, and SDK tiers lesson

- the MCP Registry as a preview metadata index for public servers:
  server.json with packages (npm, pypi, nuget, cargo, oci, mcpb),
  remotes (streamable-http, deprecated sse), or both
- reverse-DNS namespaces admitted only after GitHub, DNS, or HTTP
  verification; spoofed namespaces and private servers rejected
- exact version strings (ranges prohibited), and the server.json schema
  version kept separate from the protocol version
- aggregators and subregistries built on top of the registry
- gateways that route on the Mcp-Method and Mcp-Name headers, reject a
  header and body mismatch with -32020 before any backend is touched,
  partition private cache entries by caller, and never pass the
  caller's token through to a backend
- SDK tiers (SEP-1730): conformance, feature, triage, and critical-bug
  commitments, and relegation after four weeks of continuous failures

* docs(mcpa): pin MCP Apps metadata shapes in the protocol brief

The extension summary named _meta.ui.csp and _meta.ui.permissions
without their shape or location. Checked against the MCP Apps
specification (ext-apps 2026-01-26, draft agrees):

- a tool's _meta.ui carries resourceUri and visibility, which defaults
  to model and app and gates what the agent lists and what an app may
  call
- the UI resource's _meta.ui carries csp, an object of connectDomains,
  resourceDomains, frameDomains, and baseUriDomains origin lists, and
  permissions, an object of camera, microphone, geolocation, and
  clipboardWrite flags
- the host builds CSP from declared domains only, may restrict further,
  applies a restrictive default when csp is omitted, and may honor
  permissions that apps must not assume
- the app's ui/initialize is unrelated to the removed core initialize

* feat(mcpa): capstone that reads one exchange end to end

One incident-console server driven through a single transcript that
exercises every domain:

- server/discover with cache hints after an unsupported version is
  corrected from the -32022 data.supported list
- protocol version and client capabilities in _meta on every request
- a schema-invalid call returned with isError true and corrected
- a consent round trip with an HMAC-signed, principal-bound
  requestState, a retry on a new id, and a tampered state rejected
- -32021 when the client never declared elicitation or the tasks
  extension
- a long diagnostic run as a task, polled to completion, and a second
  task cancelled
- request-scoped notifications/progress and the Mcp-Method and Mcp-Name
  header contract
- a wrong-audience token rejected with 401 before any JSON-RPC body is
  read
- one traceparent trace id carried through every hop, and a hash-chained
  audit log that pinpoints a tampered entry
- a readiness checklist mapping every objective to what a candidate must
  be able to do

* docs(mcpa): teach the tutor and guides the stateless 34-lesson route

- tutor skill (and its Claude Code mirror): the 2026-07-28 revision is
  taught as current, with no initialize handshake, no sessions, and
  per-request _meta plus server/discover; older revisions appear only as
  what changed, and deprecated features as still working until removal
- the protocol brief and the wire-shape checker join the tutor's source
  list, and the tutor runs the checker when a learner edits a transcript
- three full mocks with distinct emphasis, and a fresh mock for every
  retake so a second score measures readiness rather than recall
- the capstone description now matches lesson 33's integrated exchange
- learner guide: 34-lesson route, 30-question diagnostic, three mocks,
  the multi round-trip lesson as the worked example, and the wire
  checker in the local verification suite
- root README: the MCPA summary describes the new route, and the skills
  table and install list include mcpa-certification

* ci(certifications): gate MCPA transcripts on the 2026-07-28 wire shape

Runs the wire-shape checker's own tests and then the checker over every
MCPA lesson transcript, so a lesson that reintroduces the legacy
handshake, drops the per-request _meta fields, omits resultType, or
emits an undefined error code fails CI. Both scripts are added to the
workflow's path filters.

* feat(mcpa): MCP Apps interactive interfaces lesson

- the io.modelcontextprotocol/ui extension negotiated per request, with
  a text-only fallback for hosts that never declare it
- a tool's _meta.ui carrying resourceUri and visibility: the agent's tool
  list excludes tools without "model", and an app's tools/call is refused
  for tools without "app", before any consent prompt
- the ui:// resource fetched with an ordinary resources/read and
  recognized only by the text/html;profile=mcp-app mime type
- the resource's _meta.ui csp object (connectDomains, resourceDomains,
  frameDomains, baseUriDomains) turned into a Content Security Policy
  that starts from default-src 'none' and admits only declared domains,
  with the specification's restrictive default when csp is omitted
- permissions flags (camera, microphone, geolocation, clipboardWrite)
  honored at the host's discretion and never assumed by the app
- the sandboxed iframe, a sandbox proxy on its own origin for web hosts,
  and the app's ui/ JSON-RPC dialect over postMessage, including a
  ui/initialize unrelated to the removed core initialize

* feat(mcpa): register all 34 lesson figures and index the route

- site/figures-mcpa-certifications.js rebuilt from each lesson's figure
  snippet: 34 mechanism figures (blueprint weights through the capstone
  flow), each with its own CSS prefix and marker ids, all rendering an
  SVG under a stub DOM; the ten figures of the legacy route are gone
- certifications/mcpa/README.md: the lesson index now lists all 34
  lessons by title, the route diagram follows the new domains, and the
  overview names the protocol brief, the wire-shape checker, the
  30-question diagnostic, and the three mocks

* docs(mcpa): give each deprecated feature its own source and removal floor

The brief grouped all six deprecated features under SEP-2577 with one
2027-07-28 removal floor. The specification's deprecated registry
records them separately:

- Roots, Sampling, and Logging: SEP-2577, deprecated in 2026-07-28,
  earliest removal on or after 2027-07-28
- Dynamic Client Registration: PR #2858, deprecated in 2026-07-28,
  earliest removal on or after 2027-07-28
- includeContext "thisServer" and "allServers": SEP-2596, deprecated in
  2025-11-25, removal follows Sampling
- HTTP+SSE: SEP-2596, deprecated in 2025-03-26, earliest removal three
  months after SEP-2596 reaches Final

Lesson 15 already teaches the registry's values; this brings the brief
in line so later questions do not inherit the grouped floor.

* docs(mcpa): state the x-mcp-header limits with their RFC 2119 strength

The brief said x-mcp-header was "never for secrets" and that clients
drop invalid tools. The tools page is more precise:

- only integer, string, and boolean parameters that are statically
  reachable from the schema root can be mirrored; number is excluded
- server developers SHOULD NOT mark sensitive parameters (passwords,
  API keys, tokens, PII), because header values are visible to
  intermediaries; this is a SHOULD NOT, not a prohibition
- HTTP clients MUST reject a tool whose x-mcp-header values violate the
  constraints by excluding it from their tools/list result

* docs(mcpa): teach what a revision date means and how hosts load skills

Two facts the assessments test were not taught by any lesson:

- lesson 01 and the brief: a revision identifier is a YYYY-MM-DD date
  marking the last backwards incompatible change, so a Current revision
  can take compatible fixes without being renamed (Draft, Current,
  Final)
- lesson 30 and the brief: reading a skill's SKILL.md through
  resources/read only retrieves text; skill content is untrusted input
  tagged with its origin, explicit user policy decides whether a skill
  is loaded, hosts should let users inspect a skill first, may not let
  it trigger host-side execution without per-skill approval, and ignore
  permission-widening frontmatter such as allowed-tools unless the user
  approved it (SEP-2640)

* docs(mcpa): teach the x-mcp-header mirroring limits in the transports lesson

The transports lesson introduced x-mcp-header mirroring and the base64
sentinel but not its limits, which the assessments test:

- only integer, string, and boolean parameters statically reachable
  from the schema root can be mirrored, never number
- a Streamable HTTP client must exclude a tool whose x-mcp-header
  values break those constraints from its tools/list result
- server developers should not mark sensitive parameters such as API
  keys or tokens, because header values are visible to intermediaries

* fix(site): refresh the figure manifest cache key for the rebuilt MCPA figures

lesson.html pins figure-manifest.js with a content hash. Rebuilding
site/figures-mcpa-certifications.js with the 34 new figures changed the
generated manifest, so the pinned key moves from 0980822a99ac to
339ef88a8714; test_build_artifacts.js checks that the committed page
matches the manifest the build produces.

* docs(i18n): regenerate the translated READMEs with the MCPA sections

The English README gained the MCPA route row, the MCPA section, the
mcpa-certification skill row, and the updated install list, but the
twelve i18n/<lang>/README.md files were never regenerated, so
build_readme_i18n.py --check failed. Regenerated with the script; the
new blocks have no hand-authored translations yet and fall back to
English as the generator documents, and no existing translation was
dropped.

* feat(mcpa): diagnostic and three full-length mocks on the 2026-07-28 protocol

Four original assessments declared on the mcpa-f track, 210 questions,
every key checked against the protocol brief and the specification
pages it cites:

- diagnostic (30 questions, 30 minutes): one concept per item across
  all 18 objectives, for placing a learner by domain
- mock 1 (60 questions, 90 minutes): operational scenarios, such as
  scaling a stateful tool behind a load balancer, one-click local
  server consent, registry preview planning, and DCR application_type
- mock 2 (60 questions, 90 minutes): wire-level messages, such as
  missing _meta fields, -32021 and -32022 error data, progress
  monotonicity, HTTP cancellation by closing the stream, all-zero
  traceparent ids, and MCP Apps mime types
- mock 3 (60 questions, 90 minutes): design and security trade-offs,
  such as where state lives, requestState protection, token audience,
  skill loading consent, and SDK tier risk

Each mock follows the blueprint split (10/8/16/14/12 across the five
domains), uses every objective, and references all 34 lessons. Items
that repeated another file's scenario were rewritten to test a
different fact, and answer positions are balanced by
debias_certification_questions.py.

* chore(mcpa): balance answer positions across the 34 lesson quizzes

Applies debias_certification_questions.py to the MCPA lesson quizzes so
correct answers follow the per-file balanced position cycle the CI
check enforces. Only option order changes; every question, option, and
explanation is unchanged, and no Claude certification file is touched.

* fix(mcpa): answer unknown methods with -32601 in four lesson servers

The dispatchers in lessons 04, 11, 12, and 14 fell through to -32602
(invalid params) for a JSON-RPC method they do not implement. An
unknown method is -32601 (method not found); -32602 is reserved for an
unknown tool, missing _meta, and other invalid parameters. Every other
lesson dispatcher already used -32601, so a learner reading these four
servers top to bottom would have learned the wrong code.

Also adds a test for lesson 03's validate_error_shape, the one shape
validator its tests never exercised.

* fix(mcpa): align three labs with what their lessons say they show

- lesson 30: the text pointed learners at the sixth exchange for the
  malformed no-slash-here identifier, but it is the seventh
- lesson 32: the demo printed "prefer remote" while calling
  resolve_install_target with prefer="package"
- lesson 33: acknowledge_incident is listed by tools/list but a plain
  tools/call answered "Unknown tool" (-32602); it now returns a tool
  execution error saying the tool is served only over the authorized
  HTTP endpoint, with a test

* fix(scripts): flag legacy and violation wrappers that do not wrap a message

check_mcpa_wire.py skipped every entry marked legacy or violation, and
when the wrapped message was not an object (a typo such as None or a
bare method string) the entry produced no finding at all, hiding an
authoring mistake. Such wrappers are now reported, matching how every
other malformed entry is handled, with a regression test for both
wrapper kinds.

* docs(mcpa): give every lab the source header the lesson contract requires

AGENTS.md asks each lesson's code/main.py to open with a 4 to 6 line
header citing its docs/en.md path and its spec or RFC sources. The MCPA
labs had a one-line docstring. Each header now names the lesson's full
docs/en.md path, what the lab does, and the specification pages, SEPs,
RFCs, or W3C documents it implements.

* fix(mcpa): require an explicit approval before consent-gated work runs

Two labs treated any elicitation answer with action "accept" as consent,
even when the form content said no:

- lesson 25: accepting the delete_file confirmation with approved false
  still deleted the file; consent now needs action accept and a content
  object whose approved field is exactly true, and a non-object answer
  is handled safely
- lesson 20: accepting the vault read with proceed false still returned
  the private note; the vault now needs proceed exactly true

Each fix has a test showing the refused path leaves no side effect.

* fix(mcpa): turn malformed wire input into refusals instead of exceptions

Six labs raised on attacker-controlled or malformed input instead of
answering it:

- lesson 05: a -32022 error with an empty supported list raised
  IndexError; the probe now records a modern era with no confirmed
  version and only caches a retry version after a successful discover
- lesson 09: an x-mcp-header value that is not a string crashed the
  linter, and object or array properties were not flagged; only string,
  integer, and boolean parameters may be mirrored
- lesson 14: a non-ASCII requestState raised during signature checks; it
  is now rejected as malformed
- lesson 19: a base64 sentinel header with invalid base64 or UTF-8
  raised; it now decodes to a mismatch and gets the HeaderMismatch reply
- lessons 27 and 33: a malformed traceparent raised ValueError; lesson
  27 restarts the trace with a new root and lesson 33 continues without
  a trace id

Each case has a regression test.

* fix(mcpa): close gaps in the labs' own security controls

- lesson 22: only the first CALL server.tool instruction in server
  content was checked, so a harmless first instruction could hide a
  cross-server one; every match is now quarantined and checked on relay
- lesson 26: the pinned tool descriptor left out annotations, so a
  silent destructiveHint flip was not caught as a rug pull, although the
  lesson's own threat matrix pins annotations; they are now part of the
  hashed descriptor
- lesson 32: the gateway log stored the caller's raw bearer token as the
  principal and printed it in the transcript; it now records a
  non-reversible principal reference, and the backend answers an
  unimplemented method with -32601 instead of -32602

Each fix has a test.

* fix(mcpa): expire idle baskets from their last activity

Lesson 04 tells learners a basket expires after five idle ticks, but
is_expired measured from creation, so an actively used basket still
expired. Baskets now record their last activity, adding an item
refreshes it, and a test shows an item added inside the window keeps
the basket alive.

* docs(mcpa): match run locations and rejection rules to the labs and spec

- lessons 09, 10, and 12 told learners to run python3 code/main.py from
  the repository root, where that relative path does not exist; they
  now say to run it from the lesson directory like the other labs
- the lesson 14 checklist said a protocol error is the wrong channel for
  a tampered or expired requestState; the spec requires rejection but
  does not prescribe the channel, so the checklist now names the lab's
  choice, a tool execution error, and a fresh input_required result as
  valid options
- the lesson 21 patterns sheet said a tools/call without the tasks
  extension always gets -32021; per SEP-2663 the server returns an
  ordinary result when it can finish within the request and -32021 only
  when it cannot, and tasks/get, tasks/update, and tasks/cancel without
  the declaration get -32021

* docs(mcpa): say the MCPA track is on GitHub only for now

The website build renders only the first certification program, so no
MCPA page is published there yet. GETTING_STARTED, both copies of the
tutor skill, and the README certification row pointed learners at
website routes that do not exist. They now send learners to the GitHub
lesson and assessment paths and say the website does not carry MCPA
yet. The translated READMEs are regenerated from the English one.

* fix(audit): stop treating the MCPA practice mock size as an exam fact

The official MCPA page does not publish an item count, and the fact
ledger records it as not published. The audit's MCPA-F exam facts listed
items 60, so check_track verified the practice mock size as if it were
official. The item count is removed from the verified facts; the track
keeps 60 as the curriculum's chosen mock length.

* fix(mcpa): refuse differently cased cross-server instructions in lesson 22

The embedded-instruction pattern matches CALL server.tool without regard
to letter case, but the relay check compared the captured names exactly,
so CALL Tickets.delete_all_tickets in untrusted server content still let
a relay to tickets.delete_all_tickets through as allowed. Quarantine and
relay checks now compare server and tool names case-insensitively, so a
case variant is refused, and a test covers the case-shifted instruction
and the same-server case.

* feat(site): render every certification program, not only the first

parseCertifications read only the first folder under certifications/, so
the website showed Claude alone: the catalog, track, assessment, and
lesson pages, the homepage spotlight, search, sitemap, and llms.txt never
saw MCPA. The build now loads every program, tags each track, lesson, and
assessment with its programId, derives each program's learner guide and
tutor skill paths, and fails on duplicate program, track, or assessment
ids across programs.

- the catalog renders one section per program with its own access
  notice, GitHub tutor links, and track grid, and the no-JavaScript
  discovery block follows the same structure
- track, assessment, and lesson pages show the disclaimer and scoring
  notice of the track's own program instead of a hardcoded Anthropic one
- lesson data loading, the language picker, and the api lesson and
  certification routes accept any certifications/<program>/lessons path
- the homepage spotlight shows both badges and names both providers, and
  build.js keeps its track, lesson, and question counts in sync
- program.json gains shortName and accessNoticeTitle, and the MCPA badge
  is marked square so it is not clipped to the Claude badge outline
- exam facts read "Not published" when a track marks its item count or
  passing score unpublished, so the MCPA card no longer presents the
  practice mock size as the official question count
- a track with four assessments lays them out two by two
- tests derive track counts from the data and cover a second program in
  the lesson and certification routes

* docs(mcpa): send learners to the MCPA track now that the site renders it

The GitHub-only wording existed because the website could not show a
second program. With the multi-program build, GETTING_STARTED, both
copies of the tutor skill, and the README point to the MCPA track page
again, the certifications index lists both programs with their onboarding
guides, and the translated READMEs are regenerated.

* docs(i18n): translate the MCPA goal row in the Portuguese and Russian READMEs

The Portuguese and Russian READMEs translate every row of the "choose
what you want to build" table, but the new MCPA row had no entry in
readme_translations.py, so it rendered in English between translated
rows. Both languages now carry the row, with the onboarding guide and
the MCPA track links unchanged, and the translated READMEs are
regenerated.

* feat(site): add a Sponsor us page rendered from SPONSORS.md

SPONSORS.md promises a sponsor page on the curriculum site, but the site
had no sponsor page and no route to one. build.js now renders SPONSORS.md
into site/sponsors.html on every build, so the page cannot drift from the
file the maintainer edits.

- the renderer covers what SPONSORS.md uses: headings with GitHub-style
  anchor ids, paragraphs, lists with wrapped items, aligned tables, bold,
  inline code, and links, where repository files resolve to GitHub and
  javascript: or parent-directory links render as plain labels
- raw HTML is limited to a, picture, source, and img with https-only
  URLs; any other tag is escaped, and a closing tag is kept only when its
  opening tag was kept
- the SerpApi logo follows the site's theme toggle instead of the
  operating system color scheme
- "Sponsor us" joins the hamburger menu through header.js and the footer
  of every page, and is added to the interface strings for translation
- /sponsors is served from sponsors.html with the same markdown
  negotiation as the other public pages, and the page is listed in the
  sitemap and llms.txt
- tests pin the rendered page to SPONSORS.md, the HTML allowlist, and
  the menu and footer links

* fix(site): give the privacy, contact, and developer pages the shared header

The three trust pages shipped a stripped header with no header.js, no
search or theme controls, no site fonts, and an old stylesheet key. At
1400px and below the stylesheet renders the header nav as a dropdown
panel that header.js normally hides behind the menu button, so on these
pages the panel stayed open over the content.

They now use the same header markup as the other pages, load the site
fonts, the current stylesheet, and the shared theme, progress, header,
and search scripts, gain a skip link to main, and style their eyebrow
line. The shared asset test now covers all three pages so their cache
keys cannot fall behind again.
2026-09-25 10:20:11 +05:30
Rohit Ghumare 8050434e5c fix: repair lessons, harden security, and gate lesson tests and quiz bias (#480)
* fix(phase-13/06): bootstrap sys.path so the documented test command runs

The lesson doc says to run unittest discovery over code/tests, but the test
imported main with no path setup, so discovery from the lesson root failed
with ImportError. Insert the code directory on sys.path the way the later
protocol lessons already do. Passes from the lesson root and from code/.

* fix(phase-13/07): bootstrap sys.path so the documented test command runs

Discovery over code/tests failed with ImportError because the test imported
main with no path setup. Insert the code directory on sys.path to match the
later protocol lessons.

* fix(phase-13/08): bootstrap sys.path so the documented test command runs

The documented discovery command raised ImportError on import main. Add the
sys.path bootstrap used by the sibling lessons so the test runs from the
lesson root and from code/.

* fix(phase-13/09): bootstrap sys.path so the documented test command runs

The documented discovery command raised ImportError on import main. Add the
sys.path bootstrap used by the sibling lessons so the test runs from the
lesson root and from code/.

* fix(phase-19/29): make the fixture tests directory an importable package

The demo fixture ships a namespace-style tests directory with no __init__.py,
so a regular tests package elsewhere on sys.path could shadow it and the
in-repo test runner failed to import the fixture module. Add an empty
__init__.py so the fixture tests resolve regardless of what else is installed.

* fix(phase-19/39): bound generation by chars and gate the demo on loss

decode_response replaces invalid UTF-8 bytes, so a 4-byte generation can
re-encode to more than 4 bytes; the test now bounds the decoded character
count, which is the real invariant that generate enforces. The demo's success
gate keyed on exact-match improvement, which the documented padding mask makes
unreachable, so it now checks that training loss decreased.

* fix(phase-19/59): test patch-projection grad via a nonzero reduction

Summing the CLS token straight out of the final LayerNorm is an algebraic
zero for any input, so the gradient reaching the patch projection was always
zero and the test failed for a reason unrelated to the encoder. Reduce with a
sum of squares, which the demo already uses, so the test exercises a real
gradient path.

* fix(phase-19/47): load checkpoints weights-only, jail shard paths

torch.load ran with weights_only=False, so restoring an untrusted checkpoint
executes whatever the pickle names. Store RNG state as primitives so it
survives the weights-only loader, load every payload with weights_only=True,
reject shard paths that resolve outside the checkpoint directory, and raise
ValueError on integrity failures instead of assert. Add regression tests for a
pickled object and a shard path escape, and update the docs, skill, and quiz.

* fix(phase-11/09): guard run_code with an AST check, not a blocklist

The substring blocklist read the snippet as text, so an attribute chain such
as the object-subclass walk reached the real interpreter through __globals__.
Parse the snippet and walk the tree, rejecting import statements, dunder
attribute access, and unsafe builtin names by structure. Add regression tests
for the escape, and make the tool description and docs state plainly that this
is a teaching filter, not real isolation. Align the TypeScript port's wording
and block the constructor and globalThis gadgets in its blocklist.

* fix(site): serve markdown at / before the static file wins

The homepage markdown-negotiation rewrite lost to the static index.html, so
requesting text/markdown at / returned cached HTML. Move it into a legacy
route, which is evaluated before the filesystem. Add a readiness-test guard
that fails if any negotiation rewrite is shadowed by a static file, and assert
the root route.

* fix(phase-19/86): parse nested sequences in the stdlib YAML fallback

The PyYAML-free fallback stopped gathering a rule's lines at the first nested
sequence item, so a rule with an any_of block lost that block and every field
after it, and the engine rejected the rule for a missing explanation. The
gather now ends on indentation alone, so a deeper sequence stays part of its
rule. Verified the fallback matches PyYAML byte for byte on rules.yml, which
restores this lesson and the end-to-end safety gate that composes it on a
standard Python install.

* test(ci): run each lesson's own tests on push and pull request

CI executed the certification labs but never the 523 lessons, so a lesson that
could not import its own module reached main unnoticed. Adds
scripts/run_lesson_tests.py, which discovers each lesson's tests across the four
layouts in the repo and runs them the way the lesson docs say, and a
lesson-tests job that runs it. The runner installs no scientific dependencies:
a lesson that needs one is skipped by scanning its source, so the job stays
green while the stdlib lessons run for real. Documents the command in
CONTRIBUTING.

* test(ci): gate quiz answer-length bias and ratchet it down

The quizzes de-bias answer position but not answer length: on 84% of questions
the correct option is the longest by a wide margin, so a reader can guess it
without knowing the material. Adds scripts/check_quiz_bias.py, which measures
the share of length-biased questions and, in --check, fails when a change pushes
the rate above a baseline set to today's level. New or edited quizzes cannot add
bias, and the baseline ratchets down as quizzes are rebalanced. Wires it into
the curriculum workflow next to the position gate and documents the rule in
AGENTS.md. Reducing the existing rate is a separate content pass; this stops it
getting worse and makes it measurable.

* fix(phase-11/09): add module docstring, honest TS wording, ast import

Address review: give function_calling.py a module docstring like the sibling
lessons, align the TypeScript run_code tool description with the honest wording
already used on the Python side (a teaching filter, not real isolation), and add
the missing ast import to the docs example's import block so the example runs.

* fix(phase-19/39): fail the demo on a non-finite final loss

The success gate compared the final loss to the first with >=, so a NaN final
loss made the comparison false and the demo exited 0. Require the final loss to
be finite before comparing, so a diverged run is reported as a failure.

* docs(phase-19/47): note the torch 2.6 requirement for weights_only

Before torch 2.6 the weights_only loader had a known bypass (CVE-2025-32434),
so the security guarantee this lesson relies on holds only from 2.6 on. Say so
next to the weights_only explanation.

* fix(site): match the root markdown Accept header case-insensitively

Media types are case-insensitive, so a client sending Text/Markdown should
still reach the markdown route. Add the (?i) flag to the root route's Accept
matcher.

* fix(ci): fail a lesson when a real test fails next to a missing dep

The lesson-test runner skipped a suite whenever its output mentioned a missing
optional module, which could hide a genuine assertion failure in the same run.
Only skip when the output shows no test failure alongside the missing module.

* fix(ci): fail the quiz-bias check on an unreadable quiz file

The scan skipped a quiz.json it could not parse and carried on, so a malformed
file would leave the gate green on an incomplete scan. Collect read and parse
errors, report each file, and exit non-zero when any are found.
2026-09-24 17:27:49 +05:30
Rohit Ghumare d86fedaa51 fix: dark-mode mermaid fills, Apple Silicon Docker build, fnm unzip, ROADMAP rows, site chrome translations (#477)
* fix: dark-mode mermaid fills, Apple Silicon Docker build, fnm unzip, ROADMAP rows, site chrome translations

- site/lesson.html: mermaidPreprocess handles 3-digit hex fills so fill:#dfd stays legible in dark mode (#433)
- 07-docker-for-ai: pin FROM to linux/amd64 and document why the cu124 layer fails on Apple Silicon (#476)
- 01-dev-environment: add unzip to the apt line, fnm's installer needs it (#473)
- ROADMAP.md: add Phase 11 lessons 16 and 17, 521 rows to 523
- site: translate interface strings for the eight CI languages via ui-i18n.js + ui-strings.js, picker dispatches aifs:lang, drift guarded by test_ui_i18n.js in CI (#469, #404)

* docs: describe fnm's unzip check and scope the CUDA image to x86_64 hosts

- 01-dev-environment: the installer checks for unzip up front and exits with its own message; macOS goes through Homebrew
- 07-docker-for-ai: the linux/amd64 pin means the image is for x86_64 Linux hosts with an NVIDIA GPU

* feat(i18n): generate site chrome translations in the translate pipeline

The hand dictionary becomes site/ui-strings.json: an English key list plus
per-language overrides. scripts/translate_ui_strings.py fills every other key
through the lesson translator's provider layer, reuses what is already
published, protects file names, paths, and commands behind the same
placeholders, and writes i18n/<lang>/ui.json. A new ui-strings job in
translate.yml runs it per CI language and publishes to the translations
branch with the same race-safe worktree loop, so a new label or a new
language needs no translation written by hand.

site/ui-i18n.js now fetches i18n/<lang>/ui.json from the translations branch
at runtime, caches it per language, and falls back to English until a language
is published. Tests cover source consistency, precedence, placeholder
protection, the page drift guard, and the fetch path.

* fix(i18n): retranslate keys whose override was removed and keep failed dictionary loads retryable

- ui.json now carries {strings, pinned}; a key that was pinned in the last publication but has no override now is translated again instead of reusing the old pin
- the runtime no longer caches a failed fetch, so a language published later is picked up on the next switch without a reload

* fix(i18n): refresh flat ui.json values once when pin provenance is missing

A flat published file predates the {strings, pinned} shape and cannot say
which values came from overrides, so every value in it counts as pinned and
is retranslated on the first run instead of being reused blindly.
2026-09-24 09:22:11 +05:30
Rohit Ghumare d18b8fe5a9 fix(book): wrap inline code and fail incomplete PDF builds (#460)
* fix(book): keep inline table code inside PDF margins

* fix(book): preserve Unicode and fail incomplete PDF builds

* fix(book): wrap inline code in PDF prose without extra symbols

* fix(book): wrap long plain-text identifiers in PDF tables

* fix(book): preserve Unicode sequences in table wrapping
2026-09-07 17:04:38 +05:30
Rohit Ghumare f068c1e63f fix(book): wrap long code lines and reference URLs in PDFs (#459) 2026-09-07 15:44:04 +05:30
Rohit Ghumare bcd09d9102 fix(book): preserve literal tokens in EPUB and PDF (#458) 2026-09-07 15:08:32 +05:30
Rohit Ghumare 2cde5bc42b fix(site): sync counts, repair actions, and harden public resources (#456) 2026-09-07 13:00:23 +05:30
Rohit Ghumare 6cdb135c5c feat: add AI Engineering Learning Paths (#444) 2026-08-30 09:53:30 +01:00
Rohit Ghumare 6571f5430a feat(site): improve motion, responsive UX, and agent readiness (#426) 2026-08-23 19:21:54 +01:00
Rohit Ghumare ed131aeebb Merge pull request #423 from rohitg00/feat/course-site-learning-dx
feat: improve course-wide learning experience
2026-08-23 18:08:42 +01:00
Rohit Ghumare ed6d0c0196 feat: add agent skills track and stateless MCP curriculum (#422)
* feat(phase-13/22): teach portable agent skill contracts

Agent skills need a portable contract before host-specific metadata and runtime policy can be reasoned about.

* fix(phase-13/23): make the ecosystem capstone accurate

The capstone should model current A2A operations, portable artifact metadata, and deterministic trace timing.

* feat(phase-13/24): teach skill discovery and disclosure

A useful skill catalog needs explicit scope precedence and bounded progressive disclosure before instructions are loaded.

* feat(phase-13/25): teach invocation policy and routing

Human, model, application, and skill activation need separate policy decisions before relevance ranking can be trusted.

* feat(phase-13/26): teach skill sandbox and trust boundaries

Skill instructions are untrusted input, so authority must remain host-owned and every filesystem, network, and command boundary must fail closed.

* feat(phase-13/27): add the skill release gate

A distributable skill needs adversarial structure, routing, safety, artifact, provenance, installation, and portability evidence before release.

* feat(skills): install and render complete skill bundles

Progressive-disclosure skills must keep companion references, scripts, assets, and evals intact across discovery, installation, and lesson rendering.

* docs(curriculum): index the agent skills mini-course

The expanded Phase 13 sequence needs consistent lesson links, durations, translations, and shared terminology across every learner entry point.

* feat(certification/11): teach stateless MCP integration

Certification learners need the same stateless wire model as the production curriculum.

* feat(phase-11/14): modernize MCP protocol contracts

The foundational MCP lesson must no longer teach the removed session lifecycle.

* fix(phase-13/01): align tool terms with stateless MCP

The tool interface introduction should point to the current protocol vocabulary.

* feat(phase-13/06): teach stateless MCP fundamentals

Learners need the current per-request contract before building clients or servers.

* feat(phase-13/07): build a stateless MCP server

The server lab should model the protocol that new implementations actually ship.

* feat(phase-13/08): build a stateless MCP client

The client lab must negotiate every request without relying on session state.

* feat(phase-13/09): teach current Streamable HTTP

Transport examples need the current POST-only lifecycle and notification behavior.

* feat(phase-13/10): teach stateless resources and prompts

Resource and prompt discovery must reflect stateless cache and result contracts.

* feat(phase-13/11): teach per-request sampling

Sampling calls must carry current capabilities and stateless response semantics.

* feat(phase-13/12): teach roots and elicitation retries

Elicitation retries and roots handling need current capability and MRTR boundaries.

* feat(phase-13/13): teach stateless MCP tasks

Task storage and subscriptions must survive cross-instance stateless requests.

* feat(phase-13/14): update MCP Apps contracts

Apps learners need current bridge, subscription, and discovery boundaries.

* feat(phase-13/15): update MCP threat boundaries

Threat modeling must cover current routing and MRTR state boundaries.

* feat(phase-13/16): update MCP OAuth contracts

OAuth examples must bind issuers and resources while using current errors.

* feat(phase-13/17): update gateway and registry contracts

Registry admission must separate publication identity from runtime discovery.

* feat(phase-13/18): teach production MCP authentication

Production auth should implement real PKCE, CIMD, and resource-bound caching.

* docs(phase-13/22): add a runnable skill quickstart

Beginners need an exact repository-root path from bundle inspection to host use.

* fix(phase-13/23): make the capstone stateless

The ecosystem capstone must compose the same current contracts taught upstream.

* docs(phase-13/24): clarify host discovery limits

Learners should distinguish known context budgets from host fallback behavior.

* docs(phase-13/26): clarify sandbox prerequisites

The safety lab needs explicit prerequisites and a viable conceptual fallback.

* docs(phase-13/27): add real-host release evidence

A production claim should require installed-host evidence beyond deterministic fixtures.

* docs(phase-16/02): update MCP legacy comparison

The interoperability comparison should use the current stateless MCP lifecycle.

* feat(phase-19/13): modernize the MCP registry capstone

The production capstone must separate Registry publication from stateless runtime discovery.

* docs(curriculum): index agent skills and stateless MCP

Learners need one coherent route through the skills track and current MCP sequence.

* feat(skills): add a focused agent skills learner path

A dedicated route removes placement and navigation friction for focused learners.

* feat(mcp): add production engineering track

* fix(cert-11): harden MCP integration contract

* fix(phase-11-14): classify MCP handler failures

* fix(mcp-07): validate JSON-RPC request identifiers

* fix(mcp-08): reuse strict response decoding

* fix(mcp-09): harden HTTP transport boundaries

* fix(mcp-11): isolate returned tool descriptors

* fix(mcp-12): make continuation state single-use

* fix(mcp-14): align lesson response metadata

* fix(mcp-15): expire and consume continuation state

* fix(mcp-16): bind OAuth enrollment and code exchange

* fix(mcp-18): enforce redirect and code lifetimes

* fix(mcp-23): validate task identifiers

* fix(skills-24): clarify discovery boundaries

* fix(skills-25): deny unknown invocation actors

* fix(skills-26): validate approval policy shape

* fix(mcp-28): terminate unsafe cursor pagination

* fix(mcp-29): preserve completed request state

* fix(mcp-30): require secure remote endpoints

* fix(mcp-31): strengthen conformance checks

* fix(agent-skills): align route prerequisites

* fix(scripts): harden skill bundle installation

* fix(site): validate learning and artifact boundaries

* fix(course): address review edge cases

* fix(mcp): tighten notification and redirect validation

* fix(mcp): secure reproducible lesson state

* fix(mcp): use required lesson header comments
2026-08-23 18:01:53 +01:00
Rohit Ghumare cd5bd53d82 fix(i18n): make translation publishing retry-safe (#401) 2026-08-09 19:13:33 +01:00
Rohit Ghumare 69502d8e93 feat: add AI-native certification curriculum and learning surfaces (#395)
* 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.
2026-08-09 15:45:01 +01:00
Rohit Ghumare 5d73526816 fix(readme): restore count-pinned toolkit sentence for the counts-sync bot (#390)
The learning-flow rewrite dropped the exact sentence check_readme_counts.py
pins ('The repo ships N skills and N prompts'), so the README counts auto-fix
job failed on main. Restore the countable phrasing and regenerate the
translated READMEs.
2026-08-02 22:55:19 +01:00
Rohit Ghumare 7953bfad74 fix(i18n): shard translation CI by phase + commit README translations + fix language picker (#387)
* fix(i18n): shard translation CI by phase, commit README translations, limit picker to supported languages

The translate workflow ran one job per language, but a full 503-lesson language
run is ~27h on a CPU runner. Every job hit the 5.5h limit and was killed before
its publish step, so it banked nothing and the translations branch never got
created: it would retry and die forever.

CI sharding
- Matrix is now one job per (language, phase). The largest phase (19, 85
  lessons) is ~4.5h, comfortably under the limit; most are 1-1.6h. max-parallel
  raised to 20.
- Cache is per-(language, phase) (i18n/<lang>/.cache/<phase>.json) and each job
  publishes only its own i18n/<lang>/phases/<phase>/ slice, so disjoint shards
  merge without clobbering. translate_lessons.py gains --phase __root__ for the
  README and a per-phase cache path.

README translations (committed to main, not CI)
- scripts/build_readme_i18n.py rebuilds i18n/<lang>/README.md by replacing only
  the translated line-spans in a copy of the English README; the banner, badges,
  584-row lesson table, and every link are preserved byte-for-byte (round-trip
  identity asserted every run). Root-relative links are rewritten to resolve two
  levels deep.
- scripts/readme_translations.py holds hand-authored translations (highest
  quality for a landing page) for 12 languages: es, fr, pt, de, it, zh, ja, ko,
  hi, ar, ru, tr. Unmapped blocks fall back to English.
- README language bar points at the committed files and lists all 12. i18n/
  README.md is un-ignored; lesson artifacts stay ignored.
- CI guard: build_readme_i18n.py --check fails on drift; the counts bot
  regenerates them when it syncs the English stats block.

Language picker
- build.js emits only source + ci:true languages into langs.js, so the site
  switcher offers only languages the site can actually serve (English + the 5
  ci languages) instead of all 40 registry entries. Cache-bust bumped.

Fixes the timed-out run in the translate workflow.

* feat(learning): AI-native learning flow, learn-first homepage, evidence-backed learner wall

The course gains a terminal-first learning experience driven by any coding
agent, and the homepage leads with it.

Learning skills (skills/ canonical, .claude/skills/ mirror for cloners)
- start-learning: one-time onboarding. Three-question interview, placement
  quiz, writes LEARNING.md (mission, entry phase, 20-phase path, progress log,
  review queue) that every later session reads and updates.
- learn: the tutor loop. Warm-up recall from the previous lesson's quiz, then
  the next lesson taught interactively (problem, concept, build, use), then the
  post-stage quiz, then progress recorded. Works cloned or entirely over
  raw.githubusercontent.com; no setup required.
- course-guide: topic router over the README contents. A topic, question, or
  bug in; the exact lessons plus the right next command out.
- find-your-level: 503-lesson count, agent-neutral question flow, raw-fetch
  fallback for ROADMAP.md, hand-off to start-learning/learn.
- check-understanding: no-clone fallback fetching lesson docs from raw.
- npx skills add rohitg00/ai-engineering-from-scratch installs exactly these
  five for any SKILL.md agent (verified against this tree: 5 found, no dupes,
  none of the 388 lesson artifacts). CI guard: skills/ and .claude/skills/
  must stay identical.

README
- "Start learning in 30 seconds" section up top; Getting Started reordered
  with terminal learning as Option A; skills table covers all five; the
  toolkit section no longer claims npx installs the 388 outputs (it never
  did; they install via scripts/install_skills.py).

Homepage
- Masthead install card: the two-command flow with real agent marks and a
  copy chip (icon, hover invert, press scale, copied state, clipboard
  fallback). Colophon "cp" button upgraded to the same component and its
  label-swap no longer destroys the icon.
- Cycling figure plate fills the masthead's empty right side and explains
  the course: FIG_001 forward pass draws itself and runs signal pulses;
  FIG_002 types out a /learn agent session with a blinking caret; FIG_003
  learning curves with graph grid, area fill, on-curve milestone markers
  (computed on the bezier), axis arrowheads, and a rider dot. Sequential
  fade between plates so text can never double-expose; fixed per-tier
  width/offset so the plate never clips at any viewport; reduced-motion
  shows a static plate.
- Learner wall: seamless JS-filled marquee (clones halves until the loop
  covers any viewport, constant scroll speed, no blank gaps) with real
  marks for every name that has a redistributable SVG (simple-icons plus
  official Wikimedia files in site/logos/); IIT Bombay and Windsor are
  type-set because only fair-use logos exist. Anonymized pull quote from a
  Google AI engineer beneath. Grayscale with dark-theme invert.
- Mobile: command wraps instead of horizontal scrolling.
2026-08-02 21:57:30 +01:00
Rohit Ghumare 62cdefbe4c feat(site): full curriculum figure coverage (503 lessons) + lang-picker CSS cachebust (#380)
* feat(site): 39 more interactive figures — wave 3 across thin phases

Extends the figure system into the phases that were still sparse: LLM
engineering, multimodal, agents depth, alignment, plus vision/speech/genai
remainders. Five new module files (1,959 LOC) on the shared LF toolkit:

- figures-llmeng.js (P11/P13, 8): few-shot curve, chain-of-thought, constrained
  decoding, prompt-cache hit, semantic cache, function-call args, LLM-judge
  rubric, lost-in-the-middle
- figures-multimodal.js (P12, 7): contrastive matrix, cross-attention fusion,
  modality projection, CFG guidance scale, VQ codebook, video patches, CTC align
- figures-agents2.js (P14/P16, 8): ReWOO plan, tree-of-thoughts, self-refine,
  memory blocks, Voyager skills, LangGraph state, orchestration patterns, debate
- figures-alignment2.js (P9/P18, 8): PPO clip, reward model, constitutional AI,
  actor-critic, interpretability probe, SAE features, jailbreak defense,
  scalable oversight
- figures-foundations2.js (P4/P6/P8, 8): augmentation, transfer learning, BN
  train/eval, CTC collapse, MFCC pipeline, autoencoder bottleneck, normalizing
  flow, score matching

Embedded in 39 figure-free lessons. Validated headless: all 173 registered
figures (16 core + 157 module) mount with zero console errors; PPO clip,
CLIP contrastive matrix, and tree-of-thoughts verified in light and dark.

* feat(site): 81 animated SVG figures across capstone, agents, CV, NLP, infra

Wave 4a. Shift from slider widgets to unique, concept-specific SMIL-animated
SVG illustrations (no JS loops, no real compute, light DOM). 10 new module
files, each figure a distinct visual matched to its lesson:

- figures-capstone-a/b (P19, 16): tokenizer merges, sliding window, training
  loop, DPO, RAG flow, eval grid sweep, sandbox runner, safety checkpoints
- figures-agents3 (P14, 8): HTN tree, workflow chain, actor mailbox, debate
  convergence, computer-use cursor, voice pipeline, injection hijack, cascade
- figures-nlp3 (P5, 9): POS tags, dependency arcs, QA span, summarize collapse,
  topic drift, coref links, NLI router, relation triples, constrained decode
- figures-cv2 (P4, 8): detection NMS, segmentation flood, GAN, diffusion denoise,
  NeRF rays, CLIP matrix, metric embedding, depth sweep
- figures-llms3 (P7/P10, 8): MoE routing, encoder-decoder, RNN vs parallel,
  speculative draft-verify, multi-token predict, self-critique, loss masking,
  activation recompute
- figures-autonomous2 (P15, 8): AlphaEvolve loop, Darwin-Godel archive, bounded
  gates, circuit breaker, checkpoint replay, cost governor, injection boundary
- figures-swarms2 (P16, 8): consensus wave, auction, stigmergy, hierarchy token,
  message bus, roles, blackboard, speaker election
- figures-infra2 (P17, 8): cache-aware router, cold start, model cascade,
  prefill/decode split, batch lanes, semantic cache, edge bandwidth, load waves
- figures-systems3 (P11/12/13/8/6, 8): masked diffusion, any-to-any stream,
  video diffusion, inpaint, agentic RAG, MCP NxM, A2A lifecycle, RVQ codec

Embedded in 80 figure-free lessons. Validated headless: all 254 registered
figures mount with zero console errors, 1062 SMIL animation nodes present,
samples (NMS, stigmergy, RAG, detection) verified rendering.

* feat(site): 80 more animated SVG figures across capstone, CV, speech, tools

Wave 4b. Ten more SMIL-animated module files, each figure a unique
concept-specific illustration (no JS loops, no real compute, light DOM):

- figures-capstone-c/d (P19, 16): embedding lookup, transformer block, GPT
  assembly, weight remap, grad accumulation, atomic checkpoint, HyDE, BLEU,
  reliability diagram, ZeRO shard, pipeline bubble, constitution loop
- figures-cv3 (P4, 8): RoIAlign, latent compression, CTC, pose heatmap,
  gaussian splat, rectified flow, open-vocab, track association
- figures-speech2 (P6, 8): ASR attention, EER crossover, TTS stack, codec
  tokens, VAD cascade, full-duplex, WER alignment, voice factorize
- figures-multimodal2 (P12, 8): patch-n-pack, LLaVA projector, M-RoPE axes,
  video token budget, action tokens, doc layout, MaxSim, agent loop
- figures-tools2 (P13, 8): tool loop, parallel fanout, schema routing, client
  merge, transport handshake, task lifecycle, tool poisoning, router failover
- figures-agents4 (P14, 8): memory fusion, crew-vs-flow, handoff, subagent
  isolation, SWE-bench gate, agent-human gap, span tree, eval layers
- figures-swarms3 (P16, 8): contract-net, work-stealing, handoff routing,
  agent-card discovery, debate topology, theory-of-mind, CTDE, checkpoint
- figures-genai3 (P8/P5, 8): VAR next-scale, FID, PatchGAN, StyleGAN mapping,
  hybrid retrieval, Matryoshka, entity linking, needle-in-haystack
- figures-misc2 (P15/P17/P11, 8): propose-then-commit, priority tiers, research
  loop, speculative tree, gateway fallback, sequential test, schema funnel

Embedded in 80 figure-free lessons. Validated headless: all 334 registered
figures mount with zero console errors, 2061 SMIL animation nodes; samples
(contract-net auction, TTS stack) verified rendering.

* fix(site): bump asset versions so the language picker CSS refreshes

The picker markup and CSS shipped, but the style.css link kept the old
?v=20260525a query, so returning visitors' browsers served cached CSS
without the .lang-panel rules and the picker rendered unstyled and
always-open. Bump every asset version (and version the new langs.js /
lang-picker.js) to force a fresh fetch.

* feat(site): full curriculum figure coverage — 169 animated figures, all 503 lessons

Wave 5 completes the interactive figure system: every lesson in every phase
now carries a concept-specific animated SVG. Sixteen new module files
(7,688 LOC), each figure a unique SMIL illustration with motion craft applied
throughout (spline ease-out entries from opacity 0 at 95 percent scale,
staggered cascades, exits faster than entries, calm 2.5-6s loops, no JS
animation loops, no real compute):

- figures-capstone-e/f/g/h/i (P19, 49 figures)
- figures-alignment3/4 (P18, 23)
- figures-workbench (P14, 15): the agent workbench mini-track animated
- figures-tools3 (P13, 11)
- figures-setup (P00, 12): commit DAG, GPU dispatch, secret injection, venv
  isolation, docker layers, LSP round trip, flame graph, more
- figures-foundations3 (P01/02/09, 11)
- figures-visaudio4 (P04/06/08, 9)
- figures-nlp5 (P05/07, 8)
- figures-llmstack5 (P10/11/12, 11)
- figures-autoswarm5 (P15/16, 12)
- figures-infra4 (P17, 8)

Coverage: 0 figure-free lessons remain; all 503 lesson docs carry a figure.
Validated headless: 506 registered figures mount with zero console errors,
4,505 SMIL animation nodes.
2026-08-01 14:43:01 +01:00
Rohit Ghumare dda194f840 fix(quiz): correct answer is always in the same position (slot B) (#381)
Every "Test Your Understanding" quiz placed the correct answer in option B.
Across the 2026 questions in 338 quiz files the correct answer sat at index 1
in 61.5% of cases (uniform would be ~25%), and 107 files had every answer at B,
making the quizzes guessable without reading them.

scripts/debias_quizzes.py rewrites each question's option order with a
deterministic, content-seeded permutation and updates the correct index to
follow the moved answer. It is idempotent: options are canonicalised to a sorted
base before permuting, so re-running produces byte-identical output. Questions
whose options reference each other by position ("all of the above", "both A and
B") are left untouched. The correct-answer value, the option set, and every
explanation are preserved exactly; only order and the index change.

Result: A 23.8% / B 26.3% / C 23.5% / D 26.4%.

The script doubles as a CI guard: `--check` exits non-zero if any quiz is not
de-biased, wired into the curriculum workflow so new lessons cannot regress.

Fixes #368
2026-08-01 14:24:15 +01:00
Rohit Ghumare 3227f17628 feat(i18n): free NLLB-200 translation pipeline, zero repo bloat (#379)
English stays canonical. Translations generate to a separate translations
branch (never main); the site, README, and books all consume them. Default
engine is NLLB-200 in the CI runner: no API key, no Vercel cost.

One pipeline, three surfaces, none bloating main:
- lessons: 503 docs -> translations branch, fetched at runtime with English
  fallback; English path byte-identical to before
- README: translated to the same branch, linked from the README header
- books: build_book.py --lang reads translated markdown and emits
  aiefs-vol{n}-{slug}-<lang>.epub/.pdf release assets (English fallback)

- languages.json: 40-language registry (FLORES-200 + ci flag) driving the
  script, the site switcher, and the CI matrix
- scripts/translate_lessons.py: prose-only walker keeps code/math/figures/
  tables/HTML/bold/links/metadata out of the model (byte-lossless across all
  503 lessons + README); per-language sha256 cache written per lesson so runs
  resume and never redo unchanged English; providers pluggable (nllb default)
- .github/workflows/translate.yml + translate-requirements.txt: one job per
  language, restores its cache, translates changed docs, pushes race-safe
- site switcher (40 languages, English fallback); build.js emits gitignored
  site/langs.js from the registry
- docs/i18n.md: architecture, no-waste guarantee, cost, quality sample
2026-08-01 12:53:35 +01:00
Rohit Ghumare d1cb9d1933 feat: book edition pipeline, fundamentals-first headlines, animated figures, verified bug fixes (#348)
Book pipeline: six-volume EPUB/PDF compilation built by CI from lesson
sources (book/, scripts/build_book.py, themed title pages with edition
stamps, site-matching print theme), attached to every GitHub release.
Homepage Books section and README section link the latest release.

Fundamentals-first headline policy across the course: 16 lesson titles
and 30+ taglines/section headings now lead with the concept (agent
state machines, actor model, role-based teams, memory paging, serving
engine internals, permission modes); framework and product names are
demoted to attributed in-body examples. README, ROADMAP, quizzes, and
prerequisite references synced. New agent-memory taxonomy section maps
memory types to representative implementations.

Vendor-neutral model policy: runnable defaults read the LLM_MODEL env
var with undated aliases; dated snapshot ids removed; multi-provider
phrasing in the setup lesson.

Lessons deepened with original material: prediction-game origins of
perplexity (05/16), scripted-era chatbot lineage 1950-2001 (05/17),
causal-triangle derivation from prefix averaging plus GPT-5 date fix
(07/07). Three new animated site figures back them (figures-history.js).

llms.txt now carries per-lesson raw markdown links so agents can fetch
full lesson text directly.

Bug fixes verified with executed repros: capstone solved flag keyed to
test results, 405B cost estimator overflow, f-string crash on
Python <3.12, no-torch demo path, negative stable BCE, all-zero
stationary distribution, inverted Cohens d, per-lesson quiz panel,
lesson-fetch retry with honest errors, decision-trees doc completed,
editor shortcuts, rustc run command, Docker python3.12 build with doc
sync, git lesson fork flow, FIPA receiver field, fnm under Rosetta,
15 curl-verified link fixes, remaining imdb dataset id spot.
2026-07-25 20:24:56 +01:00
Rohit Ghumare 9e136ec480 Update README 2026-06-25 20:42:51 +01:00
Rohit Ghumare 831f93eb8b fix(site): preview lesson docs from the deploy's branch, not always main (#289)
lesson.html hardcoded the raw.githubusercontent main branch for every lesson's
markdown, so PR preview deploys (and any non-main branch) always rendered main's
content. Content PRs could never be previewed before merge.

build.js now writes build-meta.js with the build's git ref (VERCEL_GIT_COMMIT_REF,
or local git, falling back to main); lesson.html reads window.__AIFS_REF and
fetches docs/quiz from that branch. Production (main) is unchanged; PR previews
now render their own lesson edits. build-meta.js is deploy-generated and gitignored.
2026-06-14 17:42:11 +01:00
Rohit Ghumare cb55ea0cc6 feat(site): curriculum-wide interactive figure system (134 widgets, 13 modules) (#279)
* feat(site): interactive training-foundations figures in 5 lessons

Add five theme-aware interactive widgets to lesson-figures.js, embedded
via the existing ```figure fence:

- gradient-descent (P1.08 optimization): drag learning rate, watch the
  descent path converge or diverge past lr > 1
- softmax-temperature (P3.04 activations): divide logits by T, reshape
  the distribution from argmax to uniform
- bias-variance (P2.10): slide model complexity across the U-shaped
  test-error curve, see the sweet spot move
- l2-regularization (P3.07): raise lambda, watch every weight shrink
- lr-schedule (P3.09): compare warmup, cosine, step, exponential decay

Validated headless: all five mount with no console errors, sliders and
selects drive re-render, both light and dark themes render correctly.

* feat(site): interactive LLM-internals figures in 5 lessons

Batch 2, building on the same widget system:

- sampling-decoder (P10.04 mini-gpt): temperature then top-k then top-p
  filtering over the logits, survivors renormalized
- scaling-laws (P7.13): Chinchilla loss from params and tokens, with the
  20-tokens-per-parameter compute-optimal rule
- quantization (P10.11): bits per weight against model size and the
  precision lost at fp16/int8/int4/int2
- rope-explorer (P7.04): rotary frequencies across position and dimension,
  base controls wavelength and usable context
- lora-params (P11.08): rank against the 2r/d trainable fraction

Validated headless: all five mount with no console errors, sliders and
selects drive re-render, both light and dark render correctly.

* feat(site): interactive evaluation and representation figures in 5 lessons

Batch 3, same widget system:

- precision-recall-threshold (P2.09 model-evaluation): slide the cutoff
  across two class distributions, watch precision/recall/F1 trade
- cross-entropy-loss (P3.05 loss-functions): -log(p_true), the price of
  being confident and wrong
- cosine-similarity (P11.04 embeddings): the angle between two vectors is
  the similarity, magnitude drops out
- tokenizer-tradeoff (P10.01 tokenizers): vocab size against tokens-per-word
  and the embedding table cost
- rag-chunking (P11.06 rag): chunk size, overlap, and top-k against chunk
  count and context tokens per query

Validated headless: all five mount with no console errors, math checks out
(thr 0.8 -> P 1.00/R 0.11, -ln(0.05)=2.996, cos 90 deg = 0, 224 chunks),
sliders drive re-render, both light and dark render correctly.

* feat(site): interactive figure system — 74 new widgets across 11 phases

Expand the lesson-figure system from a handful of widgets into a curriculum-wide
library. Refactor lesson-figures.js to expose a shared LF toolkit (el, svgEl,
slider, select, fmtInt, clamp, lerp, raf, register) and split widgets into eight
per-phase module files that plug in via LF.register.

New module files (3,682 LOC) and the concepts they make draggable:
- figures-math.js (P1, 11): vector projection, matrix transform + determinant,
  eigenvectors, derivative tangent, chain rule, gaussian, bayes update,
  entropy/KL, PCA axes, fourier synthesis, convex vs nonconvex
- figures-ml.js (P2, 10): regression fit/MSE, logistic boundary, SVM margin,
  kNN smoothness, k-means steps, tree depth, feature scaling, naive bayes,
  class imbalance, k-fold CV
- figures-dl.js (P3, 9): perceptron boundary, MLP forward pass, vanishing
  gradients, optimizer trajectories, weight-init variance, dropout, batchnorm,
  learning curves, gradient clipping
- figures-vision-speech.js (P4/P6, 8): convolution kernel, pooling, receptive
  field, conv output size, CNN params, spectrogram window, mel scale, aliasing
- figures-transformers.js (P5/P7, 9): attention heatmap, multihead split, causal
  mask, sqrt(d_k) scaling, word2vec arithmetic, BPE merges, GQA sharing,
  residual stream, flash-attention memory
- figures-genai-rl.js (P8/P9, 9): diffusion denoise, noise schedule, VAE latent,
  GAN minimax, Q-learning gridworld, value iteration, epsilon-greedy, discount
  horizon, policy-gradient ascent
- figures-llms-systems.js (P10/P12/P13, 9): beam search, speculative decoding,
  MoE routing, context window, perplexity, continuous batching, ViT patches,
  multimodal fusion, MCP round trip
- figures-agents-alignment.js (P11/P14/P16/P18, 9): agent loop, ReAct trace,
  tool routing, swarm message scaling, supervisor tree, RLHF reward-KL,
  DPO margin, context budget, guardrail gates

Each widget embedded in its lesson via the figure fence (74 lessons). All
theme-aware through CSS vars, vanilla ES5, no dependencies.

Validated headless: all 90 registered figures (16 prior + 74) mount with zero
console errors in a master harness; rich SVG visualizations (attention heatmap,
gridworld policy, convolution feature map, swarm graphs) render correctly in
both light and dark.

* feat(site): 44 more interactive figures — NLP, LLM internals, infra, autonomy

Wave 2 extends the figure system into the phases that were still bare,
plus deeper coverage of the large NLP and LLM phases. Five new module
files (2,219 LOC), each plugging into the shared LF toolkit:

- figures-math2.js (P1, 9): SVD low-rank reconstruction, tensor broadcasting,
  log-sum-exp stability, Lp unit balls, monte-carlo pi, system conditioning,
  random-walk diffusion, roots of unity, graph degree
- figures-nlp2.js (P5, 8): BoW/TF-IDF, RNN unroll, LSTM gates, seq2seq
  alignment, edit distance, n-gram backoff, BIO tagging, sentiment logits
- figures-llms2.js (P10, 9): RMSNorm vs LayerNorm, SwiGLU, RLHF pipeline,
  DPO loss, paged KV cache, expert capacity, sliding-window attention,
  differential attention, weight tying
- figures-infra.js (P17, 9): data/tensor/pipeline parallelism, ZeRO sharding,
  GPU memory breakdown, throughput-latency, autoscaling, cost-per-token,
  roofline
- figures-frontier.js (P15/P19, 9): task decomposition, reflection loop,
  memory consolidation, world-model rollout, autonomy oversight, pass@k,
  eval-harness matrix, canary rollout, trace spans

Embedded in 44 lessons via the figure fence. Validated headless: all 134
registered figures (16 core + 118 module) mount with zero console errors in
a full harness; pipeline-bubble, SVD energy, and trace-span visualizations
render correctly in light and dark.

* fix(site): address review findings on figure widgets

- sampling-decoder: formula now reads 'cumulative >= p' (nucleus keeps the
  smallest set covering p, matching the implementation)
- supervisor-hierarchy: drop the dead capped-total accumulator; show the exact
  geometric total and note when the diagram caps a level at 64 so the number
  and the drawn nodes stay consistent; handle b=1 (total = depth + 1) instead
  of the closed form that is undefined at b=1
- image-patch-tokens: use ceil(size/patch) so non-divisible sizes count the
  partial patch row; formula shows the ceil and meta notes the padded size
- debugging-neural-networks: normalize the one-off Type 'Practice' to 'Build'

Verified in browser: all three widgets render with the corrected text/math,
no console errors.

Skipped: the 'figure fence is not an approved language tag' findings. lesson.html
keys on codeLang === 'figure' to emit the widget mount point; the fence body is
the figure id. Renaming the fence to the figure id would stop it rendering.
There is no fence-language allowlist for these lesson docs.
2026-06-10 19:35:56 +01:00
Rohit Ghumare b963cf63ff fix(site): About page dark mode + header overlap (#275)
About page shipped without the inline theme bootstrap every other page
has, so the theme toggle was dead and the page was stuck on light. Add
the same localStorage/matchMedia bootstrap + toggle wiring.

It also cleared the 64px fixed header with only 64px top padding, so the
eyebrow tucked under the header. Bump .about top padding to 100px (80px
mobile) to match the glossary page.
2026-06-08 11:09:10 +01:00
Rohit Ghumare b749aab1b4 docs(phase-14): close three harness-engineering gaps in Agent Workbench (#274)
Close three harness-engineering gaps in the Agent Workbench mini-track:
- 33 (Instructions): progressive disclosure — thin AGENTS.md router + tiered docs
- 36 (Scope Contracts): feature_list.json as the project-level scope primitive
- 40 (Handoff): leave a clean state — cleanup phase before the handoff packet
2026-06-08 10:11:26 +01:00
Rohit Ghumare 0b2b7292e1 feat(site): add About page (#270)
* feat(site): add About page + nav/footer links + /about rewrite

* fix(site): add command palette trigger to About page header

About page loaded cmdpalette.js but had no [data-cmd-palette] trigger,
unlike the other five pages. Insert the same search-toggle button
between </nav> and the theme toggle so Cmd-K and click both work.
2026-06-08 00:09:28 +01:00
Rohit Ghumare 95292efdfb fix(figures): keep transformer-block labels inside their boxes (#269) 2026-06-07 12:18:31 +01:00
Rohit Ghumare 4a7c1240a9 feat(site): SEO/AEO foundation - sitemap, llms.txt, JSON-LD, canonical (#267)
* feat(site): SEO/AEO foundation: sitemap, llms.txt, JSON-LD, canonical

* chore(site): stop tracking generated sitemap.xml + llms.txt (build-time only)
2026-06-07 11:38:50 +01:00
Rohit Ghumare 533fe6be8d feat(site): interactive lesson figures + KV-cache sizer (#265)
* feat(site): interactive lesson figures + KV-cache sizer

Adds an in-lesson interactive figure layer. Authors drop a fenced block in
docs/en.md:

    ```figure
    kv-cache
    ```

which the lesson renderer hydrates into a real widget (sliders, live output),
theme-aware via the site's CSS vars. First widget: a KV-cache sizer — drag
sequence length, batch, layers, kv-heads, head-dim, dtype and watch the cache
size cross a single GPU's memory. Wired into 07/12 (KV cache & FlashAttention).

Mechanism: `figure` fenced block -> <div class="lesson-figure" data-figure>,
mounted by lesson-figures.js after render. No deps; figures live in lessons,
not on the homepage. Validated interactivity + light/dark parity.

* feat(site): animated figures in lesson content + delegate from fenced block

The fenced ```figure``` block now mounts both interactive widgets (defined in
lesson-figures.js) and the animated SVG explainers (figures.js), via one
syntax. Embeds animated figures directly in lesson bodies:

- attention-matrix  -> 07/02 self-attention
- transformer-block -> 07/05 full transformer
- tokenizer-bpe     -> 10/01 tokenizers
- kv-cache-sizer    -> 07/12 (interactive sliders)

Animated figures render live in normal browsers and fall back to a clean
static frame under prefers-reduced-motion. Validated all four mount via the
lesson path; light/dark parity.

* docs(07/02): replace ASCII pipeline with mermaid flowchart
2026-06-07 10:58:35 +01:00
Rohit Ghumare afcc4a6bf2 Merge pull request #263 from rohitg00/readme-traffic-stats-v2
docs(readme): 30-day traffic proof, single-source + self-healing
2026-06-07 01:22:06 +01:00
Rohit Ghumare c0d320da4c Update README.md 2026-06-06 10:45:58 +01:00
Rohit Ghumare a2f95e0cf4 Merge pull request #247 from rohitg00/site-count-sync
fix(site): sync hardcoded curriculum counts to live total (473 → 503)
2026-06-03 01:12:18 +01:00
Rohit Ghumare a4fd73bc8a Merge pull request #246 from rohitg00/index-merged-lessons
docs(site): index merged-but-unlisted lessons (468 → 503)
2026-06-03 01:01:21 +01:00
Rohit Ghumare a5285f6d78 Merge pull request #245 from rohitg00/site-fix-tables-diagrams
fix(site): table pipe rendering + theme-safe mermaid diagrams
2026-06-03 00:31:23 +01:00
Rohit Ghumare d1e000f5c8 Merge pull request #244 from rohitg00/lesson18-mcp-auth-spec-update
docs(mcp-auth): update lesson 18 to MCP 2025-11-25 authorization spec
2026-06-03 00:00:19 +01:00
Rohit Ghumare 7cf6217b6b Merge pull request #212 from rohitg00/feat/phase-19-track-i
feat(phase-19): track I safety red-team lessons 82-87
2026-06-02 17:30:19 +01:00
Rohit Ghumare b27839962f Merge pull request #215 from rohitg00/feat/phase-19-track-h
feat(phase-19): track H distributed training lessons 76-81
2026-06-02 17:25:53 +01:00
Rohit Ghumare d7ba77d75f Merge pull request #210 from rohitg00/feat/phase-19-track-g
feat(phase-19): track G eval harness lessons 70-75
2026-06-02 17:25:32 +01:00
Rohit Ghumare 40d4c76ad5 Merge pull request #213 from rohitg00/feat/phase-19-track-f
feat(phase-19): track F production RAG lessons 64-69
2026-06-01 17:13:34 +01:00
Rohit Ghumare e2f378f954 Merge pull request #209 from rohitg00/feat/phase-19-track-e
feat(phase-19): track E multimodal LLM lessons 58-63
2026-06-01 17:04:12 +01:00
Rohit Ghumare 3835018295 Merge pull request #227 from rohitg00/fix/markdown-table-pipe-escapes
fix(docs): escape pipes inside inline code so markdown tables render across 19 lessons
2026-05-27 21:52:27 +01:00
Rohit Ghumare 49b82e660f Merge pull request #228 from rohitg00/fix/loose-primitive-usage
fix(docs): drop loose  usage; keep canonical MCP / JAX / PyTorch terms
2026-05-27 21:48:22 +01:00
Rohit Ghumare 47ff7490f3 Merge pull request #226 from rohitg00/chore/site-readme-counts-473
docs: bump site/README to 473 lessons; add Phase 19 deep-build tracks
2026-05-27 20:49:36 +01:00
Rohit Ghumare bcfdc9a61f Merge pull request #225 from rohitg00/chore/agents-md-and-site-autorebuild
docs: add AGENTS.md; ci: auto-rebuild site/data.js on main push
2026-05-27 20:03:12 +01:00
Rohit Ghumare 01f84138d2 Merge pull request #203 from rohitg00/feat/phase-19-track-d2
feat(phase-19): track D auto research lessons 54-57
2026-05-27 19:41:42 +01:00
Rohit Ghumare 8f510e2f2b Merge pull request #204 from rohitg00/feat/phase-19-track-d1
feat(phase-19): track D auto research lessons 50-53
2026-05-27 19:40:26 +01:00
Rohit Ghumare c4c798827c Merge pull request #208 from rohitg00/feat/phase-19-track-c1
feat(phase-19): track C train end-to-end lessons 42-45
2026-05-27 19:39:46 +01:00
Rohit Ghumare 60dc2e80ef Merge pull request #207 from rohitg00/feat/phase-19-track-c2
feat(phase-19): track C train end-to-end lessons 46-49
2026-05-27 19:35:27 +01:00
Rohit Ghumare 231bf5e6b3 Merge pull request #211 from rohitg00/feat/phase-19-track-b3
feat(phase-19): track B NLP LLM lessons 38-41
2026-05-27 19:35:01 +01:00
Rohit Ghumare 355a25186f Merge pull request #206 from rohitg00/feat/phase-19-track-b2
feat(phase-19): track B NLP LLM lessons 34-37
2026-05-27 10:27:22 +01:00
Rohit Ghumare 13fdd72f42 Merge pull request #205 from rohitg00/feat/phase-19-track-b1
feat(phase-19): track B NLP LLM lessons 30-33
2026-05-27 10:20:13 +01:00
Rohit Ghumare cd751c2d89 Merge pull request #201 from rohitg00/feat/phase-19-track-a-agent-harness-1
feat(phase-19): track A agent harness 20-24 deep capstones
2026-05-27 10:09:00 +01:00
Rohit Ghumare fb477aa38d Merge pull request #200 from rohitg00/feat/phase-19-track-a-agent-harness-2
feat(phase-19): track A — agent harness lessons 25-29
2026-05-27 10:06:35 +01:00
Rohit Ghumare 49ae86bacf Merge pull request #224 from rohitg00/fix/readme-phase17-links
fix(readme): add Phase 17 lesson links so site catalog derives URLs
2026-05-27 10:06:18 +01:00
Rohit Ghumare c9a4409e8a Merge pull request #223 from rohitg00/ci/readme-sync-retry
ci(curriculum): rebase + retry bot push on non-fast-forward
2026-05-27 10:05:59 +01:00
Rohit Ghumare 9ca7fc6b40 Merge pull request #221 from rohitg00/chore/gitignore-catalog-json
chore: stop tracking catalog.json
2026-05-27 10:03:01 +01:00
Rohit Ghumare 6d42a30337 Merge pull request #217 from rohitg00/chore/ci-readme-counts-auto-fix
ci(curriculum): also auto-fix README counts on main push; PR check advisory
2026-05-26 23:57:12 +01:00
Rohit Ghumare 08b4c43ffe Merge pull request #198 from rohitg00/feat/phase-19-typescript-group-d
feat(phase-19): add TypeScript skeletons for capstones 12/13/16/17
2026-05-26 23:41:26 +01:00
Rohit Ghumare d24f02633b Merge pull request #216 from rohitg00/chore/catalog-regen-main-only
ci(curriculum): regen catalog.json only on main push, not on PRs
2026-05-26 22:04:04 +01:00
Rohit Ghumare d5a30d0d84 Merge pull request #197 from rohitg00/feat/phase-19-typescript-group-a
feat(phase-19): add TypeScript skeletons for capstones 01/02/03
2026-05-26 22:03:45 +01:00
Rohit Ghumare 343f403ace Merge pull request #199 from rohitg00/feat/phase-19-typescript-group-b
feat(phase-19): add TypeScript skeletons for capstones 04/06/08
2026-05-26 21:25:13 +01:00
Rohit Ghumare c1374e1d5a Merge pull request #196 from rohitg00/feat/phase-19-typescript-group-c
feat(phase-19): add TypeScript skeletons for capstones 09/10/11
2026-05-26 12:54:54 +01:00
Rohit Ghumare 6fe02914e5 Merge pull request #195 from rohitg00/chore/phase0-lang-fields-sync
chore(phase-00): sync docs/en.md Languages fields to Shell/Docker
2026-05-26 12:43:26 +01:00
Rohit Ghumare 1b935c30a7 Merge pull request #183 from rohitg00/feat/typescript-coverage-pass-1
feat(typescript): add code/main.ts to 6 lessons promising TypeScript
2026-05-26 10:42:33 +01:00
Rohit Ghumare f24cb1edb9 Merge pull request #185 from rohitg00/feat/rust-coverage-pass-2
feat: rust ports for 5 systems-heavy transformer/LLM lessons
2026-05-26 10:36:39 +01:00
Rohit Ghumare 4cd80622c5 Merge pull request #188 from rohitg00/feat/julia-coverage-phase-2-7
feat(julia): ML fundamentals + transformer Julia ports (phase 2 + 7)
2026-05-26 10:34:34 +01:00
Rohit Ghumare 8ad665dec9 Merge pull request #194 from rohitg00/chore/catalog-auto-regen-ci
ci(curriculum): auto-regen catalog.json instead of drift check
2026-05-26 10:28:52 +01:00
Rohit Ghumare c4e6169170 Merge pull request #187 from rohitg00/feat/typescript-coverage-pass-4
feat(phase17): TypeScript ports of 6 infrastructure/production lessons (pass 4)
2026-05-25 23:57:39 +01:00
Rohit Ghumare 3046c8f61e Merge pull request #184 from rohitg00/feat/typescript-coverage-pass-3
feat: TypeScript coverage pass 3 (protocols + agent engineering)
2026-05-25 23:56:38 +01:00
Rohit Ghumare d181c1735c Merge pull request #189 from rohitg00/feat/typescript-coverage-pass-2
feat: TypeScript coverage pass 2 (6 NLP/LLM-engineering lessons)
2026-05-25 23:56:13 +01:00
Rohit Ghumare 2442e1f241 Merge branch 'main' into feat/typescript-coverage-pass-2 2026-05-25 23:53:34 +01:00
Rohit Ghumare c602e3db91 Merge pull request #190 from rohitg00/chore/catalog-drift-fix
chore(catalog): sync code_files count after recent merges
2026-05-25 23:42:56 +01:00
Rohit Ghumare 51198aca85 Merge pull request #182 from rohitg00/chore/readme-lang-column-sync
docs(readme): sync lang column to on-disk source files
2026-05-25 21:04:13 +01:00
Rohit Ghumare 77a36e6177 Merge pull request #181 from rohitg00/feat/rust-coverage-pass-1
Rust coverage pass 1: dev env, edge inference, audio, INT8 quant
2026-05-25 21:03:39 +01:00
Rohit Ghumare 1517aa094b Merge branch 'main' into feat/rust-coverage-pass-1 2026-05-25 21:03:31 +01:00
Rohit Ghumare d692d00f56 Merge pull request #186 from rohitg00/feat/julia-coverage-phase-1-3
feat: julia ports for 8 math + deep-learning lessons
2026-05-25 21:02:59 +01:00
Rohit Ghumare 664862f1ee Merge pull request #173 from rohitg00/docs/readme-skills-sh-lead
docs(readme): lead with npx skills add, list agent-neutral target paths
2026-05-25 12:30:26 +01:00
Rohit Ghumare 0408294b3b Merge pull request #171 from rohitg00/fix/coderabbit-trailing-findings
fix: tighten crewai docs + skills install hint
2026-05-25 12:09:08 +01:00
Rohit Ghumare dbaef62d38 Merge pull request #149 from rohitg00/feat/phase18-quizzes
feat(phase-18): quiz backfill, 0/30 -> 30/30
2026-05-25 12:08:31 +01:00
Rohit Ghumare 702b75966d Merge pull request #170 from rohitg00/docs/readme-current-sponsors
docs(readme): add current sponsors row
2026-05-25 11:44:30 +01:00
Rohit Ghumare 03983ef549 Merge pull request #167 from rohitg00/feat/masthead-github-buttons
chore(site): bump asset cache version
2026-05-25 11:26:22 +01:00
Rohit Ghumare 22d328c1d6 Merge pull request #166 from rohitg00/feat/masthead-github-buttons
feat(site): masthead star + follow buttons with live count
2026-05-25 11:20:44 +01:00
Rohit Ghumare 4415dc80bc Merge pull request #150 from rohitg00/feat/phase5-quizzes
feat(phase-05): quiz backfill, 0/29 -> 29/29
2026-05-23 10:35:08 +01:00
Rohit Ghumare e86c007c70 Merge pull request #152 from rohitg00/fix/quiz-check-stage-rendering
fix(site): render check-stage quiz between Build and Use
2026-05-23 10:34:35 +01:00
Rohit Ghumare 0f961ba407 Merge pull request #148 from rohitg00/feat/phase19-quizzes
feat(phase-19): quiz backfill, 0/17 -> 17/17
2026-05-23 01:13:19 +01:00
Rohit Ghumare e2c27325aa feat(phase-17): quiz backfill, 0/28 -> 28/28 (#151)
* feat(phase-17/01): add quiz.json

* feat(phase-17/02): add quiz.json

* feat(phase-17/03): add quiz.json

* feat(phase-17/04): add quiz.json

* feat(phase-17/05): add quiz.json

* feat(phase-17/06): add quiz.json

* feat(phase-17/07): add quiz.json

* feat(phase-17/08): add quiz.json

* feat(phase-17/09): add quiz.json

* feat(phase-17/10): add quiz.json

* feat(phase-17/11): add quiz.json

* feat(phase-17/12): add quiz.json

* feat(phase-17/13): add quiz.json

* feat(phase-17/14): add quiz.json

* feat(phase-17/15): add quiz.json

* feat(phase-17/16): add quiz.json

* feat(phase-17/17): add quiz.json

* feat(phase-17/18): add quiz.json

* feat(phase-17/19): add quiz.json

* feat(phase-17/20): add quiz.json

* feat(phase-17/21): add quiz.json

* feat(phase-17/22): add quiz.json

* feat(phase-17/23): add quiz.json

* feat(phase-17/24): add quiz.json

* feat(phase-17/25): add quiz.json

* feat(phase-17/26): add quiz.json

* feat(phase-17/27): add quiz.json

* feat(phase-17/28): add quiz.json

* chore(catalog): rebuild after phase 17 quiz backfill

* fix(phase-17): randomize correct-answer positions across quizzes
2026-05-23 01:12:25 +01:00
Rohit Ghumare 41ca13515f feat(phase-14/15): expand crewai-role-based-crews to phase median (#146)
* feat(phase-14/15): expand crewai-role-based-crews to phase median

* fix(phase-14/15): wire Task.context through SequentialCrew kickoff

* fix(phase-14/15): route tools by name, persist Flow memory, deterministic embed seed
2026-05-22 22:05:56 +01:00
Rohit Ghumare b90acdc8e3 chore(scripts): extract shared frontmatter parser into _lib (#143)
* chore(scripts): extract shared frontmatter parser into _lib

* fix(scripts): tighten _lib frontmatter delimiter + column-0 key anchoring
2026-05-22 20:12:15 +01:00
Rohit Ghumare bc6d5ba1eb fix(a11y): skip-to-content link + focus-visible rings (#145) 2026-05-22 20:11:38 +01:00
Rohit Ghumare 463aba3ba1 feat(site): index outputs + phase-14 missions in cmd palette (#144) 2026-05-22 19:50:59 +01:00
Rohit Ghumare 2b7675aa70 fix(site): mermaid labels readable in light mode (closes #110) (#139) 2026-05-22 14:40:46 +01:00
Rohit Ghumare 42471796f1 fix(outputs): rename skills to remove name collisions (#141)
* fix(outputs): rename skills to remove name collisions

* fix(outputs): restore skill- prefix in renamed frontmatter names
2026-05-22 14:40:27 +01:00