Repository navigation
course: #/course, 27 lessons from zero to a chip, orchestrated by .t27 specs - #1420
Merged
Merged
Conversation
lut-treemap draws yosys stat -json hierarchy as a treemap: which submodule eats the LUTs. t27c-stages runs the wasm t27c on a real spec in the reader's browser and shows each stage (lex, parse, typecheck, the seven backends). Both are gallery entries 28 and 35; the gallery now holds 42 widgets. Closes #1395 Closes #1418 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…cs/course/course.t27 The course is a t27 program. specs/course/course.t27 orders 9 modules x 3 lessons, names the widget each lesson embeds, its also-try widgets and its tutorial spec, and holds every English word; specs/course/course-ru.t27 is the contract for the Russian bundle i18n/course.ru.json (L3 keeps .t27 ASCII). scripts/course-from-spec.mjs compiles both, runs their test blocks, requires every gallery widget to be used, every lesson spec to compile clean on all 7 backends, and every RU string to keep the EN digits and placeholders; it writes src/lib/course.generated.ts and public/learn/course.t27. src/pages/Course.tsx only draws the generated file: pure black, a 9 x 3 map with progress in localStorage (nothing is sent), and a lesson page with the widget in a relative iframe, chips to swap in the also-try widgets or the lesson's spec in the player, prev/next. EN and RU follow the site's language. The paid FPGA training that lived at #/course moves to #/fpga-training. CI: website-checks runs check:course and test:course; the language audits visit #/course/hello-t27 as well as #/course. Closes #1414 Closes #1415 Closes #1416 Closes #1417 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
X Brain Health CheckScore: 100.0/100 X Brain is above merge threshold |
…ap, outlined numerals Owner, 2026-10-05: large type and headlines as in a men's glossy. Pure black stays; no green. The serif is the reader's system Didot/Bodoni (Georgia fallback, which also carries Cyrillic); nothing is downloaded. Long Russian words hyphenate and the minimum size drops so 375 px has no overflow (scrollWidth 459 -> 375). Closes #1417 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Outfit 800 for every headline, cover numeral, drop cap and pull quote; JetBrains Mono for lesson numbers and spec paths; no serif, no italics. Long Russian words hyphenate instead of breaking mid-air. Checked at 1440 px and 375 px (scrollWidth 375 on the map and three lessons). Closes #1417 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
🧪 Brain Stress Test ResultsTests: 261/261 passed, 0 leaked |
var(--font) instead of var(--font, ...) so qa/queen-fallback-parity.mjs sees one font stack (it failed 230/233 on the previous push). The progress bar takes its column count from the generated lesson list instead of a hard-coded 27. Closes #1417 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-vs-nvfp4, uart-bucket) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A course at
#/course: 27 lessons from "what is an FPGA" to a bitstream on a real board, one working widget per lesson, for people who have never written hardware. The course is a t27 program:specs/course/course.t27holds the order, the widget each lesson opens and every English word; the Russian words live ini18n/course.ru.jsonunder the contractspecs/course/course-ru.t27(L3 keeps.t27ASCII).Stacked on #1413 (the nine widgets the course embeds and the main typecheck fix); this PR will be rebased when that one lands.
Shape. 9 modules x 3 lessons: the chip, numbers in hardware, your t27 program, the compiler (t27c and t27b), from spec to logic, reading synthesis, place and route, the bitstream, on the board. All 42 gallery widgets are used; each lesson has its own main widget, and 10 lessons also open their tutorial spec in the player.
Page. Pure black, no green fields. A 9 x 3 map where a finished lesson is a white cell (progress in localStorage, nothing sent), and a lesson page with goal, text, a task, the widget in a relative iframe, chips that swap in the also-try widgets or the lesson's spec, prev/next. EN and RU follow the site's language button; widgets keep their own English words.
Checks.
scripts/course-from-spec.mjscompiles both specs with the wasm t27c and runs their test blocks; fails on a widget id not in the gallery, a gallery widget left unused, a repeated main widget, a lesson spec that does not compile clean on all 7 backends, an RU string whose digits or placeholders differ from the EN one, a missing or orphan RU key, or a superlative in either language.website-checksruns it with--checkplus its 15 tests.The paid FPGA training that lived at
#/coursemoves to#/fpga-training; the nav note and the two Verification links follow.Closes #1414
Closes #1415
Closes #1416
Closes #1417
Closes #1418
Closes #1419
Closes #1395
{ "version": 1, "head_sha": "d4fad37373c83cf76c5e0aca6dd94f64959fca38", "summary": "A 27-lesson course at #/course, from what an FPGA is to a bitstream on a board, orchestrated by specs/course/course.t27 and rendered on a black page in English and Russian, one gallery widget per lesson.", "changes": [ "specs/course/course.t27: 9 modules, 27 lessons, the widget, also-try widgets and tutorial spec of each lesson, every English word, 4 test blocks.", "specs/course/course-ru.t27 and i18n/course.ru.json: the Russian words under a contract that requires full coverage and no orphan keys.", "scripts/course-from-spec.mjs (+15 tests) writes src/lib/course.generated.ts and public/learn/course.t27; wired into prebuild, prebuild:ci and website-checks.", "src/pages/Course.tsx and Course.css: the map and the lesson page; the old paid course page becomes src/pages/FpgaTraining.tsx at #/fpga-training.", "Two widgets the course needed: lut-treemap (yosys stat hierarchy as a treemap) and t27c-stages (the wasm compiler's stages on a real spec); the gallery holds 42.", "Three more widgets, each from its own spec under specs/widgets/: t27-cell, t27-vs-nvfp4 and uart-bucket; the course grows to 30 lessons in 10 modules and the gallery to 45.", "qa/browser-audit.mjs visits #/course/hello-t27 so the language audits see a lesson page as well as the map." ], "tests": [ {"command": "node scripts/course-from-spec.mjs --check", "result": "30 lessons in 10 modules, 45 widgets, 10 lesson specs compile clean; locales en, ru; spec tests 6, asserts 24, all hold", "status": "passed", "evidence": "Local run on this branch."}, {"command": "node --test scripts/course-from-spec.test.mjs", "result": "15 pass, 0 fail", "status": "passed", "evidence": "Local run on this branch."}, {"command": "node scripts/widgets-from-spec.mjs --check && node scripts/widget-pages-from-spec.mjs --check", "result": "45 widgets, spec tests 7 / asserts 22; 27 tool pages, spec tests 140 / asserts 740, all hold", "status": "passed", "evidence": "Local run on this branch."}, {"command": "npm run typecheck:ratchet", "result": "179 errors across 26 files; baseline 179 across 26; no file gained", "status": "passed", "evidence": "Local run on this branch."}, {"command": "npm run check:subpath-urls", "result": "409 source files, 2 message files and public/manifest.json, 8 known exceptions -- ok", "status": "passed", "evidence": "Local run on this branch."}, {"command": "vite dev, #/course and lessons 5, 11, 27 at 1280 px and 375 px, EN and RU", "result": "black page, widget and spec player load in the iframe, mark-done persists across reload, no sideways scroll at 375 px, no English-only line in RU on the four routes checked", "status": "passed", "evidence": "Local preview; Chrome is not installed on this Mac, so qa/ru_audit.mjs itself runs only in CI."} ], "limitations": [ "Widgets inside the iframes keep their own English words; only the course's own text is bilingual.", "Progress is per browser; there is no account and nothing is sent.", "A crawler fetching t27.ai/#/course gets the home page's preview: per-route og pages live in the apex repository and are not part of this PR.", "The t27c-stages builder found seven compiler defects (the HIR Verilog backend emits no adder logic, typecheck errors do not stop the backends, an undeclared name passes typecheck, among others); they are reported as t27 issues, not fixed here." ], "tags": ["t27", "FPGA", "Course", "Widgets"], "blog": { "title": "From zero to a chip: a 27-lesson FPGA course written as a t27 spec", "summary": "Every lesson opens a real tool built from runs on our bench, and the course itself is a .t27 file the compiler checks.", "outline": [ "Why a course for people who have never written hardware starts at the chip, not at Verilog.", "The 9 x 3 shape: chip, numbers, your program, the compiler, logic, synthesis, place and route, bitstream, board.", "The course as a program: test blocks that fail the build on an unused widget or a translated number that changed.", "What building the compiler lesson found in t27c itself: seven defects, from a Verilog backend with no adder logic to typecheck errors that do not stop codegen." ] } }🤖 Generated with Claude Code