You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+11-5Lines changed: 11 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -14,20 +14,26 @@ The format is inspired by [Keep a Changelog](https://keepachangelog.com/en/1.1.0
14
14
- Figure contracts: XML well-formedness and text-escaping (Contract 11), mechanical caption rules (Contract 5c), reverse section-figure containment, and an end-to-end check that attached figures appear in rendered pages.
15
15
- The marginalia gestalt shows one card per attachment with the production figcaption, so caption/figure disagreements are visible during review; prototype pages regenerate in `make build` and are covered by `make check-generated`.
16
16
- Behavioral test suite for Turnstile clearance signing, challenge modes, cookie attributes, and HTML cache keys.
17
-
-`scripts/refresh_golden_fixture.py`: regenerates the golden fixture as a structural snapshot and prints a reviewable summary of teaching-structure changes.
18
-
- Security headers on Worker HTML responses and static assets (nosniff, referrer-policy, frame protections); POST body size cap with a friendly 413 page.
17
+
- Security headers on Worker HTML responses and static assets (nosniff, referrer-policy, frame protections, and a full CSP); POST body size cap with a friendly 413 page.
19
18
- An end-to-end "adding a new example" workflow and a complete quality-check table in `CONTRIBUTING.md`.
20
19
21
20
### Changed
22
21
23
22
- The Makefile pins every Python invocation to 3.13 via `uv run`, so `make verify` matches CI regardless of the system interpreter; `make dev`/`deploy` use the workers dependency group.
24
23
- CI workflows: deduplicated PR runs with explicit permissions and concurrency; preview workflow passes inputs through env vars (no shell interpolation next to the Cloudflare token), pins wrangler, and passes the smoke-bypass secret; the regenerate workflow pulls before building and retries with a rebuild on push races.
25
-
- Quality gates got teeth: curated scores are bounded against the criterion heuristic (`--max-delta`), waivers must carry future ISO expiry dates and are flagged when stale, the journey-section average floor is enforced, confusable-pair tokens cannot be satisfied inside a longer sibling token, every `:::note` block is checked, `paired_pages` requires `see_also` discoverability, and the rubric-audit snapshot computes its findings from live registries instead of hardcoding PASS verdicts.
26
-
- The golden parity gate compares the full parsed cell structure (including cell kinds) against the snapshot through the loader, with no dependence on the legacy walkthrough grouping.
24
+
- Quality gates got teeth: curated scores are bounded against the criterion heuristic (`--max-delta`), waivers must carry future ISO expiry dates and are flagged when stale, the journey-section average floor is enforced, confusable-pair tokens must appear inside teaching cells and cannot be satisfied inside a longer sibling token, every `:::note` block is checked, `paired_pages` requires both `see_also` discoverability and registry-named cell evidence, scope-first-pass pages must link registry-named focused neighbors, and the rubric-audit snapshot computes its findings from live registries instead of hardcoding PASS verdicts.
25
+
- Editorial metadata moved from Python literals into `docs/quality-registries.toml`: journeys, see-also edge labels, figure attachments, captions, and curated scores now load through `src/editorial_registry.py`.
26
+
- Removed the migration-era golden fixture and parity/refresh scripts after the Markdown-backed release window; ordinary content edits now rely on verifiers, content gates, generated diffs, and browser/runtime checks rather than snapshot refreshes.
27
27
- ASGI bridge: WebSocket close events reach the close handler (`onclose` was assigned to `onopen`), headers use latin-1 per the ASGI spec, and application lifespan runs once per Worker instead of per request.
28
28
- Unknown `TURNSTILE_CHALLENGE_MODE` values fail closed to requiring a challenge; the smoke-bypass header compares in constant time.
29
29
- Template substitution is single-pass, so submitted code containing `__TOKEN__` text can no longer corrupt the rendered page; embedded JSON escapes `<` so `</script>` in example code cannot break out of the inline script.
30
-
- Small accent-colored text uses `--accent-text` (#C83800) for WCAG AA contrast; the editor textarea has an accessible label.
30
+
- Worker HTML cache keys ignore ordinary query strings (routes ignore them too), so arbitrary `?utm=` or cache-busting params cannot fragment the rendered-page cache.
31
+
- FastAPI GET handlers now call renderers directly instead of delegating to the legacy pure-Python `route()` helper and reparsing URLs.
32
+
- Oversized request bodies are capped in the ASGI bridge before the FastAPI app reads them, so the Worker no longer buffers unbounded POST bodies before rejecting them.
33
+
- Deployment smoke refuses to send the Turnstile smoke-bypass secret to non-HTTPS origins.
34
+
- Worker and static responses now include HSTS alongside CSP, frame, referrer, and nosniff headers.
35
+
- Check-script boilerplate is consolidated through `scripts/_common.py`; quality gates share the canonical loader, registry reader, and frontmatter parser.
36
+
- Small accent-colored text and the primary Run button use WCAG-AA contrast colors; the editor textarea has an accessible label.
31
37
- Content corrections across 29 example pages: dict-iteration RuntimeError scoped to key insertion/removal, PEP 695 `type` statement teaching, NotImplemented-returning operator methods, visible positional-only/keyword-only TypeError demos, divergent broad-except demonstration, honest sandbox-boundary framing for subprocesses/threads/networking, cell-specific prose replacing copied intros, and four broken inline links now rendering as real anchors.
Copy file name to clipboardExpand all lines: CONTRIBUTING.md
+8-9Lines changed: 8 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,6 @@ Then run:
49
49
50
50
```bash
51
51
make verify
52
-
scripts/check_example_migration_parity.py
53
52
scripts/format_examples.py --check
54
53
make verify-python-version VERSION=3.13
55
54
git diff --check
@@ -68,9 +67,9 @@ These scripts enforce the catalog-level rules from `docs/example-quality-rubric.
68
67
69
68
| Script | What it gates |
70
69
| --- | --- |
71
-
|`scripts/check_registry_integrity.py`| Every owner slug in `docs/quality-registries.toml` exists in `manifest.toml`; tokens are present; each `paired_pages` pair is discoverable through `see_also`. |
72
-
|`scripts/check_confusable_pairs.py`| Each confusable pair's owning page contains every token that signals the contrast; a token shadowed inside a longer sibling token (plain `def` inside `async def`) does not count. |
73
-
|`scripts/check_broad_surface_tours.py`| Each broad-title page either covers every required form or sets `scope_first_pass = true` with `see_also` links to focused neighbors. |
70
+
|`scripts/check_registry_integrity.py`| Every owner slug in `docs/quality-registries.toml` exists in `manifest.toml`; tokens are present; each `paired_pages` pair is discoverable through `see_also` and has registry-named cell tokens demonstrated inside a teaching cell. |
71
+
|`scripts/check_confusable_pairs.py`| Each confusable pair's owning page contains every token inside teaching cells; a token shadowed inside a longer sibling token (plain `def` inside `async def`) does not count. |
72
+
|`scripts/check_broad_surface_tours.py`| Each broad-title page either covers every required form or sets `scope_first_pass = true` with registry-named `focused_neighbors` linked through `see_also`. |
74
73
|`scripts/check_footgun_coverage.py`| Each canonical Python footgun has a page that contains both broken-form and fixed-form tokens. |
75
74
|`scripts/check_notes_supported.py`| Every `:::note` bullet (across all note blocks) shares at least one keyword with the page body outside the notes, so notes cannot assert behavior the page never demonstrates. |
76
75
|`scripts/check_program_covers_cells.py`| Every executable cell shares substantive code with the `:::program` block, so the editor reproduces what the cells teach; `standalone_cells = true` opts out visibly. |
@@ -82,16 +81,16 @@ These scripts enforce the catalog-level rules from `docs/example-quality-rubric.
82
81
|`scripts/check_journey_outcomes.py`| Every journey section declares learner outcomes. |
83
82
|`scripts/audit_example_graph.py --check`| The `see_also` graph has no broken targets, self-links, over-linked pages, or orphaned examples. |
84
83
85
-
The single source of truth for the registries is `docs/quality-registries.toml`. Add a new pair, broad tour, or footgun there, then update the owning page so the tokens appear in cells or prose.
84
+
The single source of truth for the registries is `docs/quality-registries.toml`. Add confusable pairs, broad tours, footguns, journey metadata, figure attachments, captions, and curated scores there, then update the owning page so the tokens appear in cells or prose.
86
85
87
86
## Adding a new example end to end
88
87
89
88
1. Write `src/example_sources/<slug>.md` (frontmatter, intro prose, one `:::program`, cells, notes) and add the slug to `manifest.toml`'s `order`.
90
89
2. Add `see_also` links in both directions — `scripts/audit_example_graph.py --check` fails orphaned pages.
91
-
3. Score the page against `docs/example-quality-rubric.md` and add the entry to `EXAMPLE_QUALITY_SCORES` in `src/marginalia.py`.
92
-
4. Attach a figure in `src/marginalia.py` (or add a `no_figure_rationales` entry with a review date) and score it; review it on `public/prototyping/marginalia-gestalt.html`, which shows the production caption under every figure.
93
-
5. Run `make build`, `make verify-examples`, `make quality-checks`, then `uv run python scripts/refresh_golden_fixture.py` and review the structural summary it prints.
94
-
6. Run the full `make verify` with a local Worker running, then commit — including the regenerated `src/example_sources_data.py`and fixture.
90
+
3. Score the page against `docs/example-quality-rubric.md` and add the `[[example_quality_scores]]`entry to `docs/quality-registries.toml`.
91
+
4. Attach a figure by adding `[[figure_attachments]]` and `[[example_figure_scores]]` entries to `docs/quality-registries.toml` (or add a `no_figure_rationales` entry with a review date); keep only new paint functions in `src/marginalia.py`. Review the result on `public/prototyping/marginalia-gestalt.html`, which shows the production caption under every figure.
92
+
5. Run `make build`, `make verify-examples`, `make quality-checks`, and `scripts/format_examples.py --check`.
93
+
6. Run the full `make verify` with a local Worker running, then commit — including the regenerated `src/example_sources_data.py`, `src/editorial_registry_data.py`, `src/asset_manifest.py`, and fingerprinted assets.
Copy file name to clipboardExpand all lines: README.md
+7-9Lines changed: 7 additions & 9 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -47,8 +47,8 @@ Python documentation links point to the official [Python documentation](https://
47
47
-`src/example_sources/*.md` contains the human-editable examples.
48
48
-`src/example_loader.py` parses Markdown examples into the runtime catalog.
49
49
-`src/examples.py` is a compatibility shim for the loaded catalog.
50
-
-`src/example_sources_data.py`is generated embedded source data for Cloudflare Workers.
51
-
-`src/marginalia.py`curates the figure registry (paint functions, attachments, scores); `src/marginalia_grammar.py` is the locked SVG drawing grammar.
50
+
-`src/example_sources_data.py`and `src/editorial_registry_data.py` are generated embedded data for Cloudflare Workers.
51
+
-`src/marginalia.py`keeps executable figure paint functions; attachments, captions, scores, journeys, and edge labels live in `docs/quality-registries.toml` and load through `src/editorial_registry.py`.
52
52
-`src/textfmt.py` renders inline prose (code spans and internal links) for pages and figure captions.
53
53
-`public/` contains static assets served by Workers Assets.
54
54
-`python_modules/` is generated by the Workers tooling and intentionally ignored by Git.
@@ -101,7 +101,6 @@ Then run the main checks before deploying or pushing:
101
101
102
102
```bash
103
103
make verify
104
-
scripts/check_example_migration_parity.py
105
104
scripts/format_examples.py --check
106
105
make verify-python-version VERSION=3.13
107
106
git diff --check
@@ -142,6 +141,7 @@ public/site.<hash>.css
142
141
public/syntax-highlight.<hash>.js
143
142
public/editor.<hash>.js
144
143
src/asset_manifest.py
144
+
src/editorial_registry_data.py
145
145
```
146
146
147
147
Rendered HTML uses only fingerprinted asset URLs. `public/_headers` gives these immutable cache headers:
@@ -160,7 +160,6 @@ Run checks, then deploy:
160
160
161
161
```bash
162
162
make verify
163
-
scripts/check_example_migration_parity.py
164
163
scripts/format_examples.py --check
165
164
make deploy
166
165
```
@@ -190,21 +189,20 @@ make build
190
189
make verify-examples
191
190
make quality-checks
192
191
scripts/format_examples.py --check
193
-
scripts/check_example_migration_parity.py
194
192
make check-generated
195
193
```
196
194
197
-
If the parity script reports intentional content differences, regenerate the
198
-
structural snapshot with `uv run python scripts/refresh_golden_fixture.py`,
199
-
review the summary it prints, and commit the fixture with your edit.
195
+
The migration-era golden fixture has been removed; intentional content edits are
196
+
reviewed through the Markdown diff, generated-source diff, verifier output, and
197
+
quality gates rather than a refreshed snapshot.
200
198
201
199
`make quality-checks` runs the content gates: registry integrity, confusable
`src/example_sources_data.py`is generated and committed so Cloudflare Workers can load examples in production. Do not edit it by hand.
205
+
`src/example_sources_data.py`and `src/editorial_registry_data.py` are generated and committed so Cloudflare Workers can load examples and editorial registries in production. Do not edit them by hand.
208
206
209
207
For a Python version migration, update `python_version` and `docs_base_url` in `src/example_sources/manifest.toml`, then run:
0 commit comments