The strict audit reports a media.githubusercontent.com read of a data-lectures path as fully migrated and exits 0. So the high_dim_data fold can be declared complete, migration.yml can be flipped to repointed, the dashboard stays green — and all six datasets are unreadable in every consuming lecture.
This is the first gate on QuantEcon/workspace-lectures#23 step 3. Its whole value is being red at the moment the lecture repoints hit main; landed after the fold it is worth nothing.
The hole
scripts/build_audit.py:397-398 derives migrated from the org/repo pattern alone, so media.githubusercontent.com/media/QuantEcon/data-lectures/main/lectures/<file> and raw.githubusercontent.com/QuantEcon/data-lectures/main/lectures/<file> are indistinguishable to every consistency check.
The flag that would separate them already exists. :196 computes "lfs_media": "media.githubusercontent.com" in url per reference, and the only thing that ever reads it is a dashboard badge at scripts/render_audit.py:841. Nothing asserts.
Reproduced end to end: a doctored lecture-python-intro and lecture-wasm with all 12 .md reads on the media host, migration.yml flipped to repointed, gives --strict EXIT=0, no warnings. That is the exact state a mechanical org/repo swap produces, which is what repoint rule 6 exists to prevent.
Worse, the comment introducing the rule-5 check at :462-463 currently reads "…must use raw.githubusercontent.com, or media.githubusercontent.com for LFS files." Since nothing under lectures/ is or will be an LFS object, that sentence now blesses the trap, and any patch has to amend it or leave the file self-contradictory.
The same shape, one step further out
branch_pinned at :195 is the identical computed-never-asserted pattern, read only by another badge at render_audit.py:843. And datasets are keyed by basename (:277, :388), so the path is never checked either.
Consequence: rewriting all 12 reads to raw.githubusercontent.com/QuantEcon/data-lectures/nonexistent-branch/WRONG_DIR/<file> also gives EXIT=0 — even with the lfs_media check applied. The host check alone is not enough.
A resolvability check is the better shape, and it subsumes the host one: for every reference with pattern == 'data-lectures', assert ref == 'main', path == 'lectures/<basename>', and that the file exists in this repo. That catches a wrong host, a wrong branch, a wrong directory, and a repoint that lands before its file — and it makes the Phase 4 data.quantecon.org cutover (#15) mechanically checkable later by flipping the expected form.
Zero false positives: all 33 real data-lectures references across the eight scanned repos today are exactly (main, lectures/<basename>). Verified: the check applied to today's main exits 0; applied to the doctored trees it exits 1 with 12 named warnings.
Notes for whoever writes it
- The code belongs after
:473, the comment after :465 — they are not adjacent.
- It is roughly 12 lines, 7 of comment and 5 of code.
:462-463 must be amended in the same change.
- Warning wording that reads well next to the existing rule-5 one:
forbes-global2000.csv: lecture-python-intro heavy_tails reads it via media.githubusercontent.com — the LFS media host 404s plain-git files (repoint rule 6).
What this still will not catch
Worth stating so the gate is not oversold. The audit scans lectures/**.md only and excludes /_static/ (:215-216, :222-224), so the three _static/lecture_specific/inequality/data.ipynb:37 builder reads stay invisible — those are hand-edit-and-hand-check in all three repos. And SCAN_REPOS (:48-57) excludes translations by decision, so lecture-intro.zh-cn's seven reads of the same six files are outside the scan entirely. Both are noted in repoint rules 1 and 6 as amended in #53.
Making the .ipynb reads visible is a separate, small change — a ~5-line edit to the file filter plus the cell extractor surfaces both — and is worth doing on its own merits, but it is not this issue.
Rules and context: PLAN.md repoint rules 1, 5 and 6 (as corrected in #53). Plan: QuantEcon/workspace-lectures#23 step 3.
The strict audit reports a
media.githubusercontent.comread of adata-lecturespath as fully migrated and exits 0. So thehigh_dim_datafold can be declared complete,migration.ymlcan be flipped torepointed, the dashboard stays green — and all six datasets are unreadable in every consuming lecture.This is the first gate on QuantEcon/workspace-lectures#23 step 3. Its whole value is being red at the moment the lecture repoints hit
main; landed after the fold it is worth nothing.The hole
scripts/build_audit.py:397-398derivesmigratedfrom the org/repo pattern alone, somedia.githubusercontent.com/media/QuantEcon/data-lectures/main/lectures/<file>andraw.githubusercontent.com/QuantEcon/data-lectures/main/lectures/<file>are indistinguishable to every consistency check.The flag that would separate them already exists.
:196computes"lfs_media": "media.githubusercontent.com" in urlper reference, and the only thing that ever reads it is a dashboard badge atscripts/render_audit.py:841. Nothing asserts.Reproduced end to end: a doctored
lecture-python-introandlecture-wasmwith all 12.mdreads on the media host,migration.ymlflipped torepointed, gives--strictEXIT=0, no warnings. That is the exact state a mechanical org/repo swap produces, which is what repoint rule 6 exists to prevent.Worse, the comment introducing the rule-5 check at
:462-463currently reads "…must useraw.githubusercontent.com, ormedia.githubusercontent.comfor LFS files." Since nothing underlectures/is or will be an LFS object, that sentence now blesses the trap, and any patch has to amend it or leave the file self-contradictory.The same shape, one step further out
branch_pinnedat:195is the identical computed-never-asserted pattern, read only by another badge atrender_audit.py:843. And datasets are keyed by basename (:277,:388), so the path is never checked either.Consequence: rewriting all 12 reads to
raw.githubusercontent.com/QuantEcon/data-lectures/nonexistent-branch/WRONG_DIR/<file>also gives EXIT=0 — even with thelfs_mediacheck applied. The host check alone is not enough.A resolvability check is the better shape, and it subsumes the host one: for every reference with
pattern == 'data-lectures', assertref == 'main',path == 'lectures/<basename>', and that the file exists in this repo. That catches a wrong host, a wrong branch, a wrong directory, and a repoint that lands before its file — and it makes the Phase 4data.quantecon.orgcutover (#15) mechanically checkable later by flipping the expected form.Zero false positives: all 33 real
data-lecturesreferences across the eight scanned repos today are exactly(main, lectures/<basename>). Verified: the check applied to today'smainexits 0; applied to the doctored trees it exits 1 with 12 named warnings.Notes for whoever writes it
:473, the comment after:465— they are not adjacent.:462-463must be amended in the same change.forbes-global2000.csv: lecture-python-intro heavy_tails reads it via media.githubusercontent.com — the LFS media host 404s plain-git files (repoint rule 6).What this still will not catch
Worth stating so the gate is not oversold. The audit scans
lectures/**.mdonly and excludes/_static/(:215-216,:222-224), so the three_static/lecture_specific/inequality/data.ipynb:37builder reads stay invisible — those are hand-edit-and-hand-check in all three repos. AndSCAN_REPOS(:48-57) excludes translations by decision, solecture-intro.zh-cn's seven reads of the same six files are outside the scan entirely. Both are noted in repoint rules 1 and 6 as amended in #53.Making the
.ipynbreads visible is a separate, small change — a ~5-line edit to the file filter plus the cell extractor surfaces both — and is worth doing on its own merits, but it is not this issue.Rules and context:
PLAN.mdrepoint rules 1, 5 and 6 (as corrected in #53). Plan: QuantEcon/workspace-lectures#23 step 3.