diff --git a/PLAN.md b/PLAN.md index 02e815f..e43dd2e 100644 --- a/PLAN.md +++ b/PLAN.md @@ -113,7 +113,7 @@ Learned from the independent validation ([#45](https://github.com/QuantEcon/data | CPython — intro site notebooks, Colab, every other series | any resolving form; `github.com/…/raw/` is fine | | Browser — `lecture-wasm` code-cell reads | `raw.githubusercontent.com/QuantEcon/data-lectures/main/lectures/`, or `media.githubusercontent.com/media/…` for LFS-tracked files | -`{download}` targets and prose links are plain navigations — CORS does not apply, and the `github.com` form is fine there. The audit classifies references by org/repo across all URL forms, so both spellings count as the same pattern: the strict check **cannot enforce this rule**; the repoint PR has to. Quick test from any `quantecon.github.io` page console: `fetch('')` — the bad form rejects, the good form resolves. +`{download}` targets and prose links are plain navigations — CORS does not apply, and the `github.com` form is fine there. The audit classifies references by org/repo across all URL forms, so both spellings count as the same pattern — but the strict build now also checks the *form*: any `lecture-wasm` code-cell read via a `github.com/…` URL fails the audit. That is a **post-merge net, not a gate** — the scan reads each lecture repo's `main`, so a violation turns the dashboard red at the next audit run rather than blocking the offending PR; the repoint PR remains the place the rule is actually upheld. Quick test from any `quantecon.github.io` page console: `fetch('')` — the bad form rejects, the good form resolves. Phase 4 inherits the requirement: `data.quantecon.org` must serve `access-control-allow-origin: *` before `lecture-wasm` can cut over to it — recorded as an acceptance criterion on [#37](https://github.com/QuantEcon/data-lectures/issues/37). diff --git a/scripts/build_audit.py b/scripts/build_audit.py index aa8ff50..c17f985 100644 --- a/scripts/build_audit.py +++ b/scripts/build_audit.py @@ -457,6 +457,21 @@ def scan(repos_dir: Path): f"{fname}: in pending wave {wave.get('pilot')} but already " f"read from data-lectures") + # Repoint rule 5 (PLAN): lecture-wasm executes code cells in the reader's + # browser, where the github.com/*/raw/ redirect fails CORS before it is + # followed — wasm reads must use raw.githubusercontent.com, or + # media.githubusercontent.com for LFS files. Only code-cell reads are + # scanned, so {download} and prose links (navigations, CORS-exempt) can + # never trip this. + for d in datasets: + for r in d["refs"]: + if (r["repo"] == "lecture-wasm" + and (r.get("url_form") or "").startswith("github.com/")): + mig_problems.append( + f"{d['file']}: lecture-wasm {r['lecture']} reads via " + f"{r['url_form']} — fails CORS in the browser " + f"(repoint rule 5)") + audit = { "generated": date.today().isoformat(), "repos": {n: {"sha": repos[n]["sha"],