32 Commits
Author SHA1 Message Date
Vijay Janapa Reddi af79ff3edd Add formal algorithm blocks and the pseudocode extension that renders them
Introduce 13 LaTeX-typeset algorithm blocks across 8 chapters (Adam update,
gradient checkpointing, FlashAttention, backpropagation, mini-batch SGD,
reverse-mode AD, PTQ calibration, tiled GEMM, ring all-reduce, 1F1B pipeline,
continuous-batching scheduler, speculative decoding, power-of-two routing),
each integrated into existing prose with a motivating lead-in and a
systems-consequence follow-up.

Extension (book/quarto/_extensions/mlsysbook-ext/pseudocode):
- Vendored under the owned mlsysbook-ext/ namespace (moved from leovan/,
  version -mlsysbook-custom) and wired into the html, pdf, and epub filters.
- MIT Press cross-ref casing: @algo- -> 'algorithm N' mid-sentence,
  @Algo- -> 'Algorithm N' at sentence start.
- Right-aligned italic triangle comments (CLRS column convention).
- Static EPUB renderer (upstream supports only HTML via pseudocode.js and PDF
  via algpseudocodex; EPUB previously emitted raw \begin{algorithm}).
- Uses the algo- prefix: native @alg- collides with Quarto's algorithm theorem
  environment and FATALs the build.

Ref tooling (book/cli/commands): teach validate.py, bib.py, and info.py the
algo-/Algo- crossref prefix (LABEL_REF_PATTERN, EXCLUDED_CITATION_PREFIXES,
Algorithm label-def patterns, and a chunk-option label harvest that runs inside
the pseudocode fence) so check refs and check labels resolve @algo-/@Algo-
instead of misreading them as missing citations.

Verified rendering in HTML, PDF, and EPUB; check refs and check labels pass
book-wide.
2026-06-06 12:36:17 -04:00
Vijay Janapa Reddi c28ff74c38 Add vendored pseudocode extension and wire it into HTML/PDF filters
Vendor leovan/quarto-pseudocode into _extensions, patched for the book:
@algo-/@Algo- references render lowercase/capitalized per MIT Press style,
and algorithm comments default to a triangle marker in italics. Register
the filter in the shared HTML and PDF filter chains. Algorithm block
conversions in chapter prose follow in separate commits.
2026-06-06 11:33:47 -04:00
Vijay Janapa Reddi 5a6c71911d Standardize shared footer and version pill across Quarto sites
Add shared/config/footer-common.yml (mirrors navbar-common.yml) and point
slides, labs, kits, and instructors at it via metadata-files, replacing their
drifted inline footers. The release pill now lives in the footer right slot
(not dangling below the page) as a fixed muted-gray chip, pinned so it looks
identical regardless of each site's theme accent. mlsysim and the book keep
their own footers (dual license / build stamp) but carry the same pill span.
release-pill.html is now assets-only and populates every data-release-pill
span from each site's own release-manifest.
2026-06-03 15:27:50 -04:00
Vijay Janapa Reddi c8b887249c docs: generalize internal rule-file references in comments
Replace pointers to the private project rules/docs tree (relative .claude/rules
and .claude/docs paths) in code comments and docstrings with neutral phrasing
("the project prose style guide", etc.). Load-bearing runtime paths that the
tooling reads or writes are left intact.
2026-05-30 17:32:19 -04:00
Vijay Janapa Reddi c005be91aa chore(announcements): drop self-link CTAs from Line 1 of every subsite
Every subsite's announcement bar Line 1 carried a 'Start reading →' / 'Start building →' / 'Get started →' link that pointed at the very subsite the reader was already on. Clicking it was a no-op self-navigation.

Strip the CTA from Line 1 across all 8 sites that have the regression:
  - announcement-vol1.yml  drop 'Start reading →'
  - announcement-vol2.yml  drop 'Start reading →'
  - tinytorch              drop 'Start building →'
  - mlsysim                drop 'Get started →'
  - kits                   drop 'Get started →'
  - labs                   drop 'Preview →'
  - slides                 drop 'Browse decks →'
  - instructors            drop 'Start here →'

Line 1 keeps the bold identity statement, which is what readers came for. The other lines (Vol I / II links, sibling row, newsletter CTA) keep their navigations since they DO lead somewhere new.

announcement-book.yml is unchanged — its Line 1 already points at the ecosystem root (https://mlsysbook.ai/), not at /book/ where the reader is.
2026-05-13 20:35:33 -04:00
Vijay Janapa Reddi 03a3537e8f feat(book/legacy): add announcement-book.yml as source of truth for /book/ banner
Adds the third member of the announcement-* family (vol1, vol2, and now book) so the legacy /book/ landing page's banner content lives under version control like the others, in the same shape and house style.

/book/ has no live Quarto build (preserved as a frozen gh-pages artifact by site-publish-live.yml), so the YAML does not drive a build directly. The header comment documents the manual sync requirement: edits to this file should be mirrored to book/index.html on gh-pages with the equivalent rendered HTML, and the data-announcement-id should be bumped so dismissals of previous banners reset.

The actual gh-pages HTML edit ships in a separate commit on the gh-pages branch.
2026-05-13 16:25:26 -04:00
Vijay Janapa Reddi 11194193c0 feat(bars): add StaffML to ecosystem cross-link row across 8 Quarto sites
For the public launch, every site's "Alongside the book" (or "Build
with your students") row now lists StaffML alongside TinyTorch, Hardware
Kits, MLSys·im, and Labs. Two coupled changes:

  • StaffML appended with verb "practice" — pairs cleanly with the
    existing verbs (build / deploy / model / explore / practice).
  • MLSys·im verb changed from "simulate" to "model" to match the
    project's own self-description ("first-principles analytical
    modeling for ML training and inference; model the physics before
    you build"). MLSys·im is analytical, not Monte-Carlo simulation;
    the new verb is more honest and the audience reads it cleanly.

Also restores tinytorch/quarto/config/announcement.yml to the canonical
4-line ecosystem template. That file had been silently rewritten to a
release-only banner ("🎉 v0.1.11 released — ...") by the
tinytorch-publish-live workflow, dropping the ecosystem cross-links
entirely. Restoration here; workflow fix is a separate commit.

Per-site row state after this commit (each site omits itself):

  site, vol1, vol2:  TinyTorch · Kits · MLSys·im · Labs · StaffML
  instructors:       TinyTorch · Kits · Slides · StaffML
  kits:              TinyTorch · MLSys·im · Labs · StaffML
  labs:              TinyTorch · Kits · MLSys·im · StaffML
  mlsysim:           TinyTorch · Kits · Labs · StaffML
  tinytorch:         Kits · MLSys·im · Labs · StaffML
  slides:            (teacher-focused row, unchanged)

The staffml site itself has its own Next.js ecosystem navbar
(EcosystemBar.tsx) which is out of scope for this Quarto-only sweep
and audited separately.
2026-05-12 09:55:35 -04:00
Vijay Janapa Reddi 7de913cc34 fix: update quiz-generation.md path refs after context cleanup
The canonical spec moved from .claude/rules/ to .claude/docs/shared/.
Updated all 4 files that referenced the old path.
2026-04-27 14:32:22 -04:00
Vijay Janapa Reddi 3c95e3e67c refactor(quizzes): rename book/tools/scripts/genai/quiz_refresh to quizzes
The genai/ folder advertised an implementation detail (AI-driven) and
held only one tool. The siblings under book/tools/scripts/ are all
named by purpose (audit/, glossary/, mit_press/, publish/, ...) — this
brings the quiz pipeline into line with that convention.

Changes:
- git mv book/tools/scripts/genai/quiz_refresh -> book/tools/scripts/quizzes
- empty genai/ parent directory removed
- 4 path-string references rewritten (filters.yml comment, three
  internal docstrings/CLI examples in README/generate_quizzes/
  build_audit_context)
- 2 BUILD.md + DEVELOPMENT.md tree-listing entries updated to point at
  the new path
- README.md title and tagline updated (no longer "Quiz Refresh — runner";
  the "quiz-refresh pattern" label is replaced with "spec-plus-runner
  pattern" since the directory name now self-documents)
- generate_quizzes.py: meta["generated_by"] now writes
  "quizzes/generate_quizzes.py" (was "quiz-refresh/generate_quizzes.py");
  --skip-existing matcher loosened from "quiz-refresh" substring to
  "generate_quizzes" so it accepts both old and new descriptors
- 33 chapter quiz JSONs and 30 _audit/*_audit.json files: the
  generated_by metadata string updated to match new descriptor
- extract_anchors.py docstring: "quiz-refresh pipeline" -> "quizzes pipeline"

Verified post-rename:
- All scripts parse (ast.parse on all three .py files passes)
- validate_quiz_json.py works on sample chapters from each volume
- --skip-existing dry-run matches the new descriptor correctly
- git grep finds no remaining "genai/" or "quiz_refresh" references;
  the one remaining "quiz-refresh" reference is an intentional
  backwards-compat note in the --skip-existing comment block

The chapter quiz corpus and the spec at .claude/rules/quiz-generation.md
are unchanged in content — this is purely a directory + descriptor rename.
2026-04-25 08:09:47 -04:00
Vijay Janapa Reddi 32c28ecdcf Merge branch 'feat/quiz-refresh' into dev 2026-04-24 14:48:23 -04:00
Vijay Janapa Reddi e91b1e2515 feat(quiz-filter): re-enable inject_quizzes.lua + fix self-guard bug
Wave 1 + 2 of the quiz refresh landed 1867 questions across 33
chapters on feat/quiz-refresh. With all JSONs in place and the
validator green across every chapter, re-enable the HTML-side
injection so readers actually see the quizzes at end of each ##
section + the "Self-Check Answers" roll-up at the end of each
chapter.

Two bug fixes this commit also picks up:

1. Remove the module-level self-guard that used
   ``quarto.doc.is_format("html")`` to short-circuit non-HTML
   loads. ``is_format`` returns false at filter-load time (before
   format detection has completed), so the guard was returning
   an empty filter table for HTML builds too — silently disabling
   all quiz injection. Cross-format protection is already provided
   at the config layer: ``shared/html/filters.yml`` is the only
   per-format filters.yml that lists this filter; pdf/ and epub/
   lists do not. Verified by rendering vol1/training and observing
   the filter's "📝 [Quiz Filter]" log emit.

2. Fix playwright_verify.py selectors to match the actual rendered
   DOM: Quarto emits ``<h2 data-anchor-id="...">`` (the id lives
   on the enclosing <section>), and the self-check-answers block
   is ``<section id="self-check-answers">`` not ``<h2 id=...>``.

End-to-end render check:
  $ quarto render contents/vol1/training/training.qmd
    → 📝 Document has quizzes - processing
    →  8 quiz sections injected
  $ playwright_verify.py training.html
    → Q=8  A=8  self-check-answers=yes  errors=0 warnings=0

Filter is now live for HTML builds; PDF and EPUB remain clean
(they never loaded the filter, and the filter's config-layer gating
is unchanged).
2026-04-24 14:17:43 -04:00
Vijay Janapa Reddi ad98437b4c docs(announcements): unify announcement bars across nine Quarto sites
Every site's announcement bar now follows one template:

  Line 1  — identity + primary CTA (what is THIS site)
  Line 2  — the book (or, on book sites, the other volume)
  Line 3  — "Alongside the book:" sibling row (3 most-relevant verbs)
  Line 4  — newsletter

The book is the anchor of the curriculum; every other site is a verb
applied to it — TinyTorch (build), Hardware Kits (deploy), MLSys·im
(simulate), Labs (explore), Slides + Instructors (teach). Making that
shape visible in every bar turns nine independent sites into chapters
of one curriculum.

Removed stale copy: "Happy New Year!" on kits + labs, "coming in 2026"
on labs (we are in 2026; replaced with "Coming Summer 2026"), TinyTorch
v0.1.10 single-line release notice (belonged in a release changelog,
not the always-visible nav bar).

Normalized outbound links: /book -> /vol1/ and /vol2/, consistent
trailing-slash hygiene on every URL. Newsletter link points to
https://mlsysbook.ai/newsletter/ (the actual Quarto page) instead of
#subscribe (which only resolves on the landing page).

The landing site (mlsysbook.ai) uses a 5-line variant that covers all
four learner verbs + the teacher-tools row; every other site uses the
4-line form.

StaffML is a Next.js app, not a Quarto site, so its banner is out of
scope for this PR and will ship as a separate React component change.
2026-04-23 16:35:57 -04:00
Vijay Janapa Reddi d0a2bd109a chore(book): disable quiz injection pending Vol1/Vol2 regeneration
Inline quiz callouts and the SocratiQ widget are disabled in both HTML
builds while the book goes through a major content refresh. The existing
*_quizzes.json files are stale against the current prose and will be
regenerated on a parallel branch before the filter is re-enabled.

- Comment out inject_quizzes.lua in shared/html/filters.yml
- Add a quarto.doc.is_format("html") self-guard inside the filter so
  it is a no-op if accidentally loaded under pdf/epub/latex
- Comment out the SocratiQ TOC entry and bundle.js <script> include
  in _quarto-html-vol{1,2}.yml

JSON files, YAML quiz: entries, custom-numbered-blocks, and the
socratiq.qmd landing page are left in place so re-enabling is a
four-line revert.
2026-04-23 16:00:25 -04:00
Vijay Janapa ReddiandGitHub 73967f7c42 PR-2: Visual polish (announcement bars, theme persistence, dev-mirror fix, audit script) (#1405)
* fix(dev-mirror): compute prefix from dev-side depth in rewrite-dev-urls.sh

The previous implementation hard-coded PREFIX="../" for any non-root
subsite, which silently mis-rewrote every absolute mlsysbook.ai link on
the dev preview for nested subsites (vol1, vol2 — they live at
/book/vol1/ and /book/vol2/ on dev). The most visible symptom was the
navbar title-href landing one level too shallow: clicking the navbar
title from inside Vol I went to /book/ instead of the unified landing
page at the dev root.

Fix: derive PREFIX from the number of path segments in the calling
subsite's dev-side path (book/vol1 → 2 hops → '../../') and use the
mlsysbook.ai key (not the dev-path) for self-link detection. Add an
explicit error if the caller passes a subsite name that is not in the
SUBSITES map, instead of silently producing wrong rewrites.

Sample rewrites with the fix:
  vol1 page  https://mlsysbook.ai/        → ../../
  vol1 page  https://mlsysbook.ai/vol2/   → ../../book/vol2/
  vol1 page  https://mlsysbook.ai/kits/   → ../../kits/
  kits page  https://mlsysbook.ai/        → ../
  kits page  https://mlsysbook.ai/vol1/   → ../book/vol1/

Live builds are unaffected — they use the original absolute URLs.

* feat(book): per-volume announcement bars (Crimson / ETH-Blue)

Split the shared book announcement bar into two volume-scoped files so
each volume gets audience-appropriate copy AND inherits the right brand
tint. Vol I keeps the Harvard-Crimson tint (its theme accent) and the
Foundations-flavored content; Vol II picks up the ETH-Blue tint (its
theme accent) and Scale-flavored content that leads with the new
volume launch and the cross-ecosystem build path.

Files:
  - announcement-vol1.yml — new, Vol I copy, no hard-coded color (uses
    `type: primary` so .announcement / .alert-primary get $accent =
    $brand-crimson via theme-harvard.scss)
  - announcement-vol2.yml — new, Vol II copy, same pattern but theme
    feeds $accent = $brand-eth-blue via theme-eth.scss
  - announcement.yml      — emptied to a no-op with a deprecation note;
    keep for one release cycle to avoid breaking any external metadata
    reference, then delete

The CSS that translates `type: primary` into the per-theme tint already
lived in book/quarto/assets/styles/_base-styles.scss (`.announcement {
  background: linear-gradient(... lighten($accent, 52%) ...) }`). No
SCSS changes needed — the previous behavior of a single shared bar
just hid that the tint was already theme-driven.

Resolves the "Vol II announcement should be ETH-themed" QA note.

* feat(theme): cross-site dark-mode persistence + FOUC guard

Make dark-mode preference flow seamlessly across every subsite under
mlsysbook.ai (Quarto-built and Next.js alike) and eliminate the
theme-flash that dark-mode readers see on first paint.

Quarto subsites (book / labs / kits / slides / instructors / mlsysim /
tinytorch / unified site):
  - shared/config/site-head.html now inlines a tiny pre-paint script
    that reads `quarto-color-scheme` from localStorage (or falls back
    to OS preference) and applies `data-bs-theme`,
    `data-quarto-color-scheme`, and `style.color-scheme` on <html>
    BEFORE any other script runs. Eliminates the visible flash that
    was happening because Quarto's own toggle script runs late.
  - Listens for `storage` events so a toggle in tab A propagates to
    tab B without a refresh.
  - Inlined deliberately: the script is tiny, must be synchronous in
    <head> to avoid the flash, and inlining sidesteps per-subsite
    asset path differences. Canonical externalized source kept at
    shared/scripts/theme-persist.js for documentation/testability —
    if you change one, mirror to the other.

StaffML (Next.js):
  - public/theme-bootstrap.js now reads the Quarto-side key as a
    fallback when StaffML has no local preference, so a user toggling
    dark mode on the book lands here in dark mode on first visit.
  - components/ThemeProvider.tsx mirrors writes back to
    `quarto-color-scheme`, so navigating onward to any Quarto subsite
    inherits StaffML's choice. Both subsystems retain their own keys
    as primary so each app's behavior is unchanged in isolation.

The `quarto-color-scheme` key is the bridge contract — keep it stable
across all theme code paths.

* test(audit): Playwright site-audit script (sidebar / darkmode / assets)

Single Playwright-driven QA script that the release-prep plan needs in
three flavors. Implemented as one CLI with three subcommands so the
shared boilerplate (browser launch, URL list, output dirs, screenshot
naming) lives in one place and the per-site source-of-truth list does
too.

Subcommands:
  sidebar    Assert every Quarto subsite exposes a populated, visible
             #quarto-sidebar / .sidebar-navigation. Skips sites that
             intentionally have no sidebar (landing, slides, StaffML).
             Catches the regression where Vol I/II builds dropped the
             sidebar after a config refactor.

  darkmode   Force dark-mode via localStorage + data attributes, scroll
             top→bottom in 800px chunks (so lazy content renders), and
             screenshot full-page into _audit/darkmode/<site>.png for
             eyeball review. Surfaces "half-themed" widgets that CSS
             linters can't find (announcement bar, footer tiles, code
             blocks, etc.).

  assets     Listen for failed network requests + 4xx/5xx responses on
             every site URL. Catches the broken <img> embeds reported
             during dev-mirror review (TinyTorch big-picture PDF
             viewer, Vol II cover) before they hit production.

Targets dev / live / local with --target. Use --only <substring> to
narrow scope. JSON report written to _audit/<cmd>.json for CI ingest.
Exits non-zero on issues so it can become a blocking CI check once the
baseline is clean.

Requires `npm i -D playwright && npx playwright install chromium`.
2026-04-20 09:05:52 -04:00
Vijay Janapa ReddiandGitHub 8f09e80c4c PR-3: Scripts, audits, cleanup (build stamp, PDF dropdown, 404s, mirror guard, dedup, RELEASE-PREP) (#1406)
* feat(footer): build-time "last updated" stamp

Add a small build-time stamp to the page footer ("Last updated YYYY-MM-DD
· <site> · <commit>") so readers can see at a glance that the site is
fresh. Quarto's per-page `date-modified` already exists for chapter
pages, but it doesn't capture site-level rebuilds (theme tweaks,
navbar changes, deploy reruns).

Pieces:
  - shared/scripts/inject-build-stamp.sh: wraps a token-replace over a
    build directory. Search-and-replace on `<!-- MLSB_BUILD_STAMP -->`
    means sites that haven't adopted the token are unaffected — opt-in
    rollout per subsite.
  - book/quarto/config/shared/html/footer-common.yml: token added next
    to the existing copyright line in the shared book footer.
  - shared/config/footer-site.yml: token added next to the copyright
    in the unified-site footer.
  - shared/config/site-head.html: minimal CSS for `.mlsb-build-stamp`
    (small, neutral, dark-mode aware).
  - .github/workflows/kits-publish-live.yml: representative wiring —
    runs the stamp step after build and before deploy. Other publish-
    live workflows can adopt the step the same way as they roll
    through release-prep validation.

* feat(navbar): expose paper.pdf for TinyTorch / MLSys·im / StaffML

Each of these subsites already builds a companion paper.tex in CI and
ships the PDF alongside the HTML site. Surface those papers in the
navbar dropdowns where readers actually look for them:

  Build menu:
    - TinyTorch     → site
    - TinyTorch Paper (file-pdf icon, opens in new tab)
                    → /tinytorch/assets/downloads/TinyTorch-Paper.pdf
    - MLSys·im      → site
    - MLSys·im Paper (file-pdf icon, opens in new tab)
                    → /mlsysim/mlsysim-paper.pdf

  Prepare menu (after a separator):
    - StaffML Paper (file-pdf icon, opens in new tab)
                    → /staffml/downloads/StaffML-Paper.pdf

Paper URLs are intentionally kept in lockstep with the build steps in
tinytorch-publish-live (assets/downloads/), mlsysim-publish-live
(site root), and staffml-publish-live (out/downloads/). If a build
path moves, both the workflow and this navbar entry need to move
together — there is no single source.

* feat(404): per-site 404 pages for slides / instructors / unified site

The book, kits, labs, mlsysim, and tinytorch subsites already have
flavored 404.qmd pages that route lost readers to the right
neighborhood. Add the missing three so every subsite under
mlsysbook.ai has a coherent recovery experience instead of falling
back to GitHub Pages' default white-page 404.

  - slides/404.qmd       — slide-deck flavored copy, pointers back to
                           the deck index, the volumes, and the hub.
  - instructors/404.qmd  — instructor-flavored copy, pointers to the
                           course map, slides, and both volumes.
  - site/404.qmd         — landing-page flavored copy, the most
                           ecosystem-wide nav (links to every subsite)
                           because this is the most common 404 source
                           for inbound links from the legacy single-
                           volume mlsysbook.ai.

StaffML already has its own React not-found.tsx so no work needed.
TinyTorch's legacy Sphinx 404.md is preserved for now (still wired on
the Sphinx site that hasn't migrated yet).

* ci(precommit): block subsite-mirror drift on shared assets

Add a pre-commit hook that runs `shared/scripts/sync-mirrors.sh --check`
on every commit. The hook fails if any of the per-subsite real-file
mirrors (subscribe-modal.js, theme SCSS partials, logo) has drifted
from its canonical source in `shared/`.

Why a guard, not just a sync: Quarto's resource-copy step preserves
symlinks instead of dereferencing them, so we have to keep real
copies. Without the guard, "I'll edit the canonical and forget to
re-sync" silently re-introduces the duplicate-divergence bug we just
spent effort fixing. `always_run: true` because a mirror can drift via
deletion of the canonical, not just by editing the canonical itself.

To re-sync after a deliberate change:
  bash shared/scripts/sync-mirrors.sh

* refactor(audit): duplicate-file finder + clean up obvious leftover

Add shared/scripts/find-duplicates.py as a periodic duplication
auditor. It SHA-1 hashes every source-y file across the ecosystem
roots, groups identical contents, subtracts the intentional groups
declared in shared/scripts/sync-mirrors.sh, and reports the rest as
unintended duplicates. JSON report written to .audit/duplicates.json
for CI ingest later; --strict makes it exit non-zero.

Defaults err on the side of being useful out of the box:
  - Skips symlinks (those are deliberate aliases, not duplicates).
  - Skips small files (<256B) — LICENSE stubs, .gitkeep, etc.
  - Skips _site / _build / node_modules / .next / out / .git.
  - Source-y suffix list (.js, .ts, .scss, .css, .html, .yml, .py, .sh).
    Binary assets (images, PDFs) are NOT scanned because their dup
    story is different (logos, icons are intentionally repeated).

Initial-cleanup pass:
  - Delete tinytorch/scripts/cleanup_repo_history.sh — byte-identical
    leftover; the canonical version lives at
    tinytorch/tools/maintenance/cleanup_history.sh and is the one
    referenced by tinytorch/tools/maintenance/README.md.

After this commit the only remaining unintended duplicate is
runHistoryProvider.ts in three vscode-ext packages (kits / labs /
tinytorch). Promoting that into a shared vscode-ext package is real
refactor work — out of scope for release-prep, captured for later.

Add .audit/ and _audit/ (the latter from the Playwright site-audit
script) to .gitignore.

* docs(release-prep): handoff notes covering all five PR groupings

Add a single document at the worktree root that walks through what
this branch contains, why each piece is there, the recommended PR
split (PR-1 safety-net, PR-2 visual polish, PR-3 scripts/audits/
cleanup, PR-4 TinyTorch prep, PR-5 cutover skeletons), what was
intentionally LEFT OUT (and why), and what verification was done
locally vs. what still needs the dev mirror to exercise.

Treat this as the cover memo for the staged-rollout foundation
work; once the five PRs are individually merged into dev, this file
will outlive the branch but the per-PR sections still document why
each piece exists for anyone debugging months from now.
2026-04-19 16:23:26 -04:00
Vijay Janapa Reddi 396506d29d refactor(site): unify 4 site subsites into single Quarto project
Architecture:
- Merge landing, about, community, newsletter into one site/ project
- Move navbar-common.yml to shared/config/ (used by 12 configs)
- Create shared/config/footer-site.yml for centralized footer
- Create shared/scripts/subscribe-modal.js as canonical copy
- Single _quarto.yml replaces 4 independent configs
- One site_libs/ copy replaces four

Features gained:
- Google Analytics on ALL hub pages (was only on book volumes)
- Subscribe modal on landing page (was missing)
- Centralized footer with consistent links

Workflows updated:
- site-preview-dev.yml: matrix strategy → single build job
- site-publish-live.yml: loop over subsites → single build + deploy
- sync-newsletter.yml: builds from unified site project
- publish-all-live.yml: removed stale subsite input
- rewrite-dev-urls.sh: added --shallow flag for unified builds

All 12 navbar-common.yml references updated:
  book vol1/vol2, site (unified), slides, instructors, interviews,
  kits, labs, mlsysim
2026-03-21 13:30:24 -04:00
Vijay Janapa Reddi d9bf132b95 fix(site): community page TOC, dark mode, MIT Press logo, and navbar link
- Remove content-visible wrapper from community index.qmd so Quarto
  generates TOC entries for the four ## sections
- Add ul.collapse override in _toc.scss to ensure TOC list is visible
- Add explicit .quarto-dark overrides in community.css for opening text,
  card headings, and body text visibility
- Scope dark mode blockquote rule to blockquote:not([class]) to avoid
  overriding custom spotlight quotes
- Add .content p/li dark mode color rule in _site-dark.scss
- Replace MIT Press SVG placeholder with proper PNG logo
- Update community index.qmd to reference mit-press.png
- Fix Global Network navbar link to /community/ (remove #outreach anchor)
- Update landing _quarto.yml to use shared style-site.scss and site-head.html
2026-03-21 13:07:07 -04:00
Vijay Janapa Reddi 5cbab2e7f4 fix(about,navbar): correct avatar URLs and Global Network anchor
Fix Marco Zennaro and Jeremy Ellis GitHub avatar URLs to use their
real usernames. Update Global Network navbar link to #outreach anchor.
2026-03-21 08:24:29 -04:00
Vijay Janapa Reddi 3cfd8ded46 feat(about): redesign about page with origin story, timeline, and people sections
Add "Our Story" section telling the 2020-2026 arc from Harvard classroom
to global curriculum. Replace Press with visual Milestones timeline.
Reorganize Team into People grouped by contribution area (Curriculum,
Hardware & Labs, Global Outreach, edX). Remove thin Adopters section
(community page owns that story). Update navbar: add Our Story and
Milestones, move Discussions to GitHub dropdown, add MIT Press logo
to community partners.
2026-03-20 19:18:30 -04:00
Vijay Janapa Reddi 79039bd402 feat(community): redesign community page around mission-driven narrative
Restructure community page from information architecture to story arc:
opening statement, global network map, community voices, outreach cards,
events, and partner logos. Add real TinyML4D map image and all partner/
sponsor logos from tinyml.seas.harvard.edu and book acknowledgements.
Update navbar dropdown to include Global Network, Events, and Partners.
Fix contributor count to 95+ (deduplicated across API and all-contributors).
2026-03-20 19:18:30 -04:00
Vijay Janapa Reddi 0b1092c4ac fix(navbar): revert to Interactive Labs — more inviting than Software Labs 2026-03-20 15:07:29 -04:00
Vijay Janapa Reddi 539c9ecf9c fix(navbar): rename to Software Labs (pairs with Hardware Kits) 2026-03-20 15:05:29 -04:00
Vijay Janapa Reddi 5aa145e019 style(navbar): use sliders icon for Interactive Labs 2026-03-20 14:56:05 -04:00
Vijay Janapa Reddi 6cbb0ac690 style(navbar): use play-circle icon for Interactive Labs 2026-03-20 14:52:07 -04:00
Vijay Janapa Reddi d5b4446879 fix(navbar): rename to Interactive Labs 2026-03-20 14:50:26 -04:00
Vijay Janapa Reddi c12b22641e fix(navbar): rename Labs to Co-Labs, remove outdated Coming 2026 tag 2026-03-20 14:49:25 -04:00
Vijay Janapa Reddi 05d97db43f feat(website): add About, Community pages and redesign Newsletter
New subsites:
- /about/ — Mission, Team, Contributors (auto-pulled from GitHub API),
  Adopters, Press, License sections with card-based design
- /community/ — Programs (TinyML4D, SciTinyML, Show & Tell, edX),
  Events calendar, Global Network map, Partners

Newsletter redesign:
- Buttondown API sync script (scripts/sync_newsletter.py) pulls
  published emails as .md files with auto-categorization and
  guest author detection
- Grid layout with banner images from Buttondown
- Embedded subscribe triggers shared subscribe-modal.js
- Dynamic stats (_stats.yml) updated by sync workflow
- Daily sync workflow at 6am UTC with build + deploy pipeline

Infrastructure:
- Navbar updated with anchor links (#mission, #team, #events, etc.)
- Subscribe button triggers shared modal across all subsites
- Contributors auto-update workflow generates about/contributors.json
- Deploy workflows for about/ and community/ subsites
- merge_contributors.py merges GitHub API with .all-contributorsrc
2026-03-20 14:44:49 -04:00
Vijay Janapa Reddi b64bc98669 fix(site): improve mobile responsiveness for navbar and landing visuals
- Bump navbar collapse-below from lg (992px) to xl (1200px) since
  5 left dropdowns + 4 right items need more horizontal space
- Remove redundant collapse-below/background/pinned/collapse overrides
  from vol1 and vol2 configs (now inherited from shared navbar)
- Add mobile breakpoints for Beamer frame, blueprint schematic, and
  flashcard stack (text scaling, grid stacking, reduced spacing)
2026-03-19 17:08:54 -04:00
Vijay Janapa Reddi 5790e2706c feat(site): centralize navbar across all subsites
Single source of truth for the navigation bar in navbar-common.yml.
New 5-dropdown structure: Read | Build | Teach | Community | About.

- Add generate-navbar.py script to merge shared + site-local dropdowns
- Add _navbar-local.yml for slides, instructors, mlsysim (site-specific menus)
- Generate _navbar-generated.yml for all 6 subsites (committed, no CI changes needed)
- Strip hardcoded navbars from all _quarto.yml configs (landing, vol1, vol2, slides,
  instructors, mlsysim, kits, labs, newsletter)
- Add community/ and about/ paths to rewrite-dev-urls.sh for dev preview

To update navbar: edit navbar-common.yml, run generate-navbar.py --all, commit.
2026-03-19 10:41:25 -04:00
Vijay Janapa Reddi 354cb2000f chore: extract shared HTML footer and update announcement banner
- Add config/shared/html/footer-common.yml with common page-footer elements
  (copyright/license left, GitHub/star right, background, border)
- Reduce _quarto-html-vol1.yml and _quarto-html-vol2.yml page-footer to
  volume-specific center link only; shared elements imported via metadata-files
- Update announcement bar: lead with two-volume launch, keep four-line format
2026-03-02 17:38:30 -05:00
Vijay Janapa Reddi df8c3174e5 Refactor: centralize Quarto shared config and streamline PDF build fragments.
Moves common diagram and PDF title/build settings into shared metadata layers, simplifies per-volume configs to keep only volume-specific values, and carries related chapter figure text/asset updates needed in the current working set.
2026-02-12 20:14:31 -05:00
Vijay Janapa Reddi 2390c3ab31 Refactor: consolidate Quarto config layers and content reorganization.
Unifies Quarto metadata into shared base/format/volume fragments while carrying through chapter path, asset, and tooling updates to keep the repository consistent and easier to maintain.
2026-02-12 15:38:55 -05:00