Repository navigation
Eval: Playwright runner against a stub of the eval page - #10
Conversation
run_detect.py opens the eval page in headless Chromium and calls its own decode() and detectFaces() for every test image (docs/contracts.md, section 3), then writes the detections file of section 4 and a run_info.json with the versions, hashes and timings. It serves the images on the page's own origin, stops the run if the page asks for another origin, adds an EXIF orientation tag to the images Open Images stores turned, and checks every decoded size against the manifest. Until app/eval.html exists, --page stub uses eval/stub/, which has the same interface and finds magenta rectangles instead of faces. Four tests in Chromium cover the orientation, a rerun with identical boxes, the SHA-256 check and the guard against other origins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
a2c3219 to
34c5e16
Compare
Stub runs go to data/stub-runs/ and are refused in results/; images that cannot be served upright are found before the browser starts; the JPEG header walk skips fill bytes and markers without a length; the page is closed before the last check for requests to other origins; run_info records uncommitted changes anywhere in the repository, app/ included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Review note on #10, merged. This needs a follow-up before the first detection run. An image's own EXIF orientation can flip it against its boxes without the size check noticing. No image in the current draw has one: the two camera originals in it, 6ae23606d22bad2d (3780 × 6111) and cce0d9c5636f322e (6000 × 4000), carry Orientation 1 or none. But a redraw after the review could bring in another original. I suggest refusing any image whose EXIF Orientation is present and not 1, in Related, from #2: part B and 🤖 Review written with Claude Code |
Third step of the evidence half (
docs/plan.md, "Your half", item 2). Stacked on #9, which is stacked on #2: merge those first.What is in it
eval/run_detect.pyopens the eval page (docs/contracts.md§3) in headless Chromium with Playwright and, for each test image, calls the page's ownsolidMask.decode()andsolidMask.detectFaces()with score threshold 0.05. It writesresults/detections/<run-id>.jsonl(§4) and arun_info.json(versions, hashes, timings, git commit, likerun_info.jsonin the MNIST repo)./__eval__/images/, soconnect-src 'self'allows the fetch and nothing leaves the machine. Any request to another origin stops the run.createImageBitmap(..., {imageOrientation: "from-image"})turns them upright, as it does a phone photo. Every decoded size is checked against the manifest..partfile; run ids are never reused.boxesSha256(the SHA-256 of every line after the run line, which names the run). The protocol's reproducibility rule now says this.eval/stub/: a stand-in forapp/eval.htmlwith the samewindow.solidMaskinterface and the app's CSP. Its "detector" returns the bounding box of each solid magenta patch, so the runner andscore.pycan be tested with known answers.--page stubis the default until the app's eval page exists.score.pygives a miss rate of 0. A rerun gives identical boxes; changed images are refused; a page that fetches from another site stops the run. Swapping the EXIF codes for 90° and 270° makes the tests fail.For Pratyush
app/eval.html(§3) is what this runner needs from the app:decode,detectFaces,renderandinfo, on a page served by the dev server. No special handling of image URLs is needed, since the runner serves them on the page's origin. Thenrun_detect.py --page http://localhost:5173/eval.htmlruns the real detector.nmsIoUdefaults to 0.3 for YuNet (as inapp/src/config.ts) and 0.5 for YOLO5Face.Not done yet
none: the rotation and darkening images, and the darkening noise parameters that the protocol fixes ineval/transforms.pybefore the first run. Those need decisions (fill colour for the enlarged canvas, resampling, noise model) that I'll bring as a separate PR.How to check
🤖 Generated with Claude Code