Repository navigation
v466 — The Advanced drill owns its page
What changed
v466 — the Advanced drill owns its page. The Advanced steps used to fetch https://example.com/, and step 4 required the literal phrase "Example Domain" from it. example.com reworded its page, so a model that fetched it and saved the text correctly was graded 3/8 · 4 failed at step 4 and rewrote a good file until it gave up. Step 3 now fetches http://drill.local/advanced.html, served from disk by the app (ui/drill/advanced.html): no DNS, no socket, so it always answers — and it has to work that way, because fetching this app's own origin would deadlock under the single-threaded PHP server while it is answering the request that asked for it. assertPublicUrl is untouched: only a flat *.html name in ui/drill/ is answered, and loopback, LAN and metadata addresses are still refused. The page carries DRILL-PAGE-v1, which the write step and the read-back grade, and tests/php/drillPage.test.php fails if the page and the grader ever disagree about it.
The other drills were audited the same way. Frontier's typing step no longer pins PHP's exact sentence (it accepts any read-back that is not reported as unverified), and Hard, Easy and Browser grade the drill's own file, the strings the drill itself teaches, or the app's own local page — nothing whose wording lives outside this repo.
v465 — Advanced tracks the page it grades. Before the fixture moved in-house, the checks accepted every wording example.com has served and graded the saved content itself (at least 40 characters of page text) rather than a phrase in the arguments, while still refusing a placeholder save.
v464 — the two-pass check from a terminal. php tools/drill-selftest.php runs the self-test without a browser, and a failed pass now reports the first error it hit, at the step it happened on, instead of only counting it.
v463 — RUN TWO-PASS SELF-TEST in Config → Permissions. The run report lists each pass with the file it wrote.
v462 — every training pass writes its own drill file (…-p1.txt, …-p2.txt), so a second pass never starts on the first pass's bytes. The old training/ folder is renamed aside at Start rather than deleted, so the evidence of an earlier run survives.
Checks
JS 42 files / 1,395 assertions, PHP 35 files / 35 passed (3 skipped on this host: no symlink, no git), docs 14/14.
VERSION 461 → 466, APP_VERSION 461 → 463, every ?v= under ui/**, and both index.html files.