Repository navigation
Full-page evidence: hide fixed sheets over element shots, stitch pages that relay for the capture - #1149
Conversation
An organic-clip-path or bounce-easing finding reported on body now records, like radial-halo and dark-glow, the painted element whose computed style carries the declaration: a polygon() clip with the finding's vertex count, or the overshooting timing function or bounce animation it names. Evidence only; the finding still names the page. Co-Authored-By: Claude Code <noreply@anthropic.com>
…ge that relays for the capture - An element shot hides, for the shot only, each position: fixed layer the hit test lists above the flagged element (theguardian.com's support appeal over the lower two thirds of a phone viewport). Never the layer holding the element, one that scrolls along, or a backdrop painted under it. A shared tile serves another element only when no layer it left showing covers that element. - The beyond-viewport capture measures a sample of layout boxes before and after; when a quarter of them moved sideways (developer.apple.com folds its navigator for the capture's resize and slides the column back while it paints), the page is stitched from viewport tiles once settled. - Stitched tiles after the first also hide a sticky box the document's scroll has stuck at its offset, so a section bar under a header that scrolls away no longer repeats on every tile. Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
…c anchor shape - Remove four debug writes to a local path left in the fullpage tests. - A point's covering layers count only when the hit-test stack reaches the flagged element or something inside it: under a layer that takes no pointer events the stack runs past the element to the fixed backdrop beneath it, which stayed hidden as a cover. - An open modal (dialog[open], aria-modal="true") is never hidden. - Each element shot records the fixed layers hidden for it (ElementShot::hidden_covers). - The relayout fallback stitches only when the sample settles back to where it was measured (two measures in a row); a page in steady motion (a margin-left marquee) keeps its beyond-viewport capture. - Stitch tiles re-test sticky boxes on every later tile, so one that sticks only further down is hidden too. - The organic-clip-path anchor applies the scan's own polygon tests (count, grid, rectilinear, zigzag), shared through organic_polygon_vertices. - Twins: a backdrop under a pointerless element, a fixed box under a transformed ancestor, a shared tile with one covered element, an open modal, a never-ending marquee. Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
A page measured before the capture is stitched only once the boxes that moved during the capture are back where they were measured. Boxes that change later were painted in their measured place and no longer block. A box that moved at the capture and keeps its new geometry still keeps the beyond-viewport capture. Co-Authored-By: Claude Code <noreply@anthropic.com>
Card content under a link stretched over the card is not in the hit stack, so the walk met the card first and dropped the sheet over it (theguardian.com mobile: the support sheet stayed on 5 of 11 tiles). The element is made hit-testable for the walk only, so it is listed at its true paint position; the backdrop under it still stays. Co-Authored-By: Claude Code <noreply@anthropic.com>
Co-Authored-By: Claude Code <noreply@anthropic.com>
|
Nothing to fix. About this review
Reviewed 1 file on 23 Oct 2026, 18:25 UTC · Run page Reviews (4) · Last reviewed commit: Merge origin/main into corpus/round13-harness |
[Medium impact] The PR changes evidence capture for URL scans, not the findings themselves. Fix cover removal for sheets with opacity transitions before merging.
|
…ackdrop A stitch hid any sticky box sitting at its top offset. That is also a bar whose section starts on that tile's top edge, or one stuck on the tile its section starts on: neither was painted before, so the image lost it. Now a stuck box is hidden only once its own place in the document is above the tile. Element shots spared an open dialog only when it was the fixed layer or inside it. A fixed backdrop that wraps an aria-modal dialog is spared too. Co-Authored-By: Claude Code <noreply@anthropic.com>
A cookie banner holding a closed preferences panel marked aria-modal kept the banner over the flagged element. The wrapped modal now counts only when it is visible. Co-Authored-By: Claude Code <noreply@anthropic.com>
Regenerated the in-page bundle after branches A and C landed. Co-Authored-By: Claude Code <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 0d0276f. Configure here.
A day of main comes in: the round-13 measurement defects (#1151) and the straggler fix (#1135), hidden product mockups (#1137), legal and footnote blocks (#1146), full-page evidence capture (#1149), the Tune value fixes (#1108, #1154), the launcher and ignore-boundary round (#1116), the craft-floor launcher fallback (#1153), the reference docs reconciliation (#1117), the CSP meta reference fix (#1145), keeping installed skills when the bundle is unreachable (#1144), the debuginfo cut (#1150), and the generated provider syncs. No source conflicts: the in-page bundle and five sweep goldens conflicted as generated files. The bundle was regenerated from the merged source with `cargo xtask bundle`; the sweep goldens are main's as they stand, since main carries them as accepted deltas in DELTAS.md (its own new fixtures are not recorded in them yet), and this branch's sweep entries are covered by its existing DELTAS entries the same way. Prepared with AI assistance (Claude Code). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Round 13 of the detector corpus, branch F: the evidence a URL scan hands a reviewer. Nothing here changes what the engine detects. It changes the pictures and anchors that go with the findings, so a judge sees what the visitor sees.
Row 21: a fixed sheet over every element shot
On theguardian.com's phone pages, a fixed "This is the catch" support sheet covers the lower two thirds of the viewport. Every element shot past the screenshot's cut showed the sheet instead of the flagged element: 9 of 9 tiles on the international front, all 27 on an article.
Element shots now hide the fixed layers painted over the flagged element, for that shot only, and put them back afterwards. At 9 points over the element's visible part the engine walks
document.elementsFromPointdown to the element, and hides eachposition: fixedlayer it passes. Guards:pointer-events: auto, restored right after), so content that takes no pointer events, such as card text under a link stretched over the card, is listed at its true paint position.stitchuses).dialogor anaria-modallayer stays in the shot, and so does a fixed backdrop that wraps one: the visitor sees it.Each shot records what was hidden in
ElementShot::hidden_covers, so a judge can tell "chrome removed for this shot" from "what the visitor sees".Live, on the revised head: theguardian.com/international on a phone, 32 of 32 element shots hide the sheet and no tile shows it (base: every tile showed it). The article on desktop: 15 of 15. The article on a phone: 61 of 61. The international front on desktop has no fixed sheet and records none. The hit-testable step was added after review: without it, 6 of the 32 phone shots (card labels under a stretched link) kept the sheet on 5 of 11 tiles.
Row 23: a page that re-lays itself for the beyond-viewport capture
developer.apple.com's guideline pages answer the capture's resize (Chromium dispatches it at 1x1, then at the real size) by folding the navigator and sliding the column back over about 300ms, and the capture paints that state: the column at x 309 while the rects say 390.
The engine now measures a sample of layout boxes (a 6x6 grid of elements in the first viewport, offset geometry, so transforms do not count) before and right after the capture. When at least 2 boxes and a quarter of the sample moved sideways, it waits up to 2 seconds for the boxes that moved to come back to where they were measured, twice in a row 100ms apart, and then stitches the page from viewport tiles. A page that keeps moving (a marquee on
margin-left) never settles and keeps the beyond-viewport capture, and so does any page where a box that moved at the capture keeps its new geometry. Vertical moves are ignored: an image loading during the capture pushes content down without a relayout.This does not fix developer.apple.com itself. On the live page five navigator link labels change width at the capture (96px to 84px and similar) and keep their new widths, while the column comes back within 100ms. The engine cannot tell whether the image or the rects hold those labels' true place, so the page fails safe to the beyond-viewport capture, as on main, after a 2 second wait. Widening the rule to let it through would also let through pages whose picture really is wrong. The fallback is proven by a browser fixture that folds on resize and slides back; the never-ending ticker and the slide-only page are its twins.
The stitched fallback also needed a fix to
stitch: every tile after the first re-tests sticky boxes and hides one stuck at its owntopoffset once its own place in the document is above that tile, so an earlier tile already painted it. A section bar is no longer repeated at the top of every tile, and a bar whose section starts on the current tile (or exactly on its top edge) stays.Row 24: page-level anchors for organic clip paths and bounce easing
page_form_anchornow anchorsorganic-clip-path(an element whose computedclipPathis a polygon passing the scan's own off-grid and not-rectilinear tests, through a sharedcss_scan::organic_polygon_vertices) andbounce-easing(a computed timing function with the same bezier, or an animation the snippet names). None of the corpus's listed findings gain an anchor from it today: apple.com's polygon is on a media-controls pseudo-element, and framer's bounce curve is declared but computed by nothing at capture. A local page with all three page forms gets anchors for the halo and the polygon.Corpus numbers
Replays on main's runs, against main's replay of the same run (c51e529):
The violations are main's own against those runs' judged labels; this branch adds none and removes none.
No craft mark is removed on run 1009 (legit 0, harmless 0, false positive 0, unclear 0). Replays exercise detection, not the evidence step, so identical tables are the expected result; the evidence changes were checked live on the pages above.
Tests
crates/browser/tests/fullpage_screenshot.rs: the sheet is hidden (an_element_shot_hides_the_fixed_sheet_over_the_element,..._over_content_the_hit_test_misses), with twins that keep a fixed backdrop, a backdrop under content that takes no pointer events, a fixed box that scrolls along, an open modal, a modal wrapped in a fixed backdrop, and a shared tile only for elements no shown layer covers. The relayout fixture is stitched, with sticky bars that stick on a later tile, stick on the tile their section starts on, and start on a tile's top edge; a ticker that never stops and a page that only slides keep the beyond-viewport capture. Assertions read solid colour blocks, never text pixels.layout_moved,moved_boxesandsettled, including the apple shape (labels that move at the capture and stay keep the page unsettled), and for the anchors, with a zigzag polygon decoy.Gates on the merged head 1437fd2 (origin/main 5cb95ee merged in, no conflicts), before the review-round commit 8772352, which touches only
fullpage.rsand its browser tests (all 21 pass, and the bundle check holds):cargo build --release -p impeccable,cargo xtask bundle --check(both live assets up to date), the node oracle (no case changed, no re-record, no DELTAS entry),cargo test --workspace(2257 passed, 0 failed),bun run buildwith no tracked changes, andbun run testwith the branch binary.AI assistance: prepared by Claude Code, under instructions from @pbakaus.
🤖 Generated with Claude Code
Note
Medium Risk
Changes screenshot capture timing (up to 2s layout wait), in-page DOM opacity during shots, and new evidence fields; detection tables are unchanged but evidence output behavior shifts on real sites.
Overview
Improves evidence screenshots without changing detection rules: reviewers get clearer full-page and per-element images, plus better anchors for some page-level CSS findings.
Element viewport shots now temporarily hide
position: fixedlayers that paint over the flagged element (support appeals, cookie sheets), using a 9-pointelementsFromPointwalk with guards for backdrops, modals, transformed “fixed” content, and pointer-events edge cases. Shots record what was hidden inElementShot::hidden_covers, and tile reuse only applies when the previous capture left no covering layer.Full-page capture probes layout before/after a beyond-viewport screenshot; when enough boxes shift horizontally and then settle back, it stitches viewport tiles instead of keeping a capture painted during a resize-driven relayout (e.g. folding side nav). Continuous motion or permanent geometry changes still keep beyond-viewport. Stitching also hides sticky bars that were already painted on earlier tiles.
Evidence anchoring extends
page_form_anchortoorganic-clip-pathandbounce-easingvia sharedorganic_polygon_verticesin CSS scan logic.Browser and unit tests cover sheets, modals, shared tiles, relayout/sticky stitching, and layout probe helpers.
Reviewed by Cursor Bugbot for commit 0d0276f. Bugbot is set up for automated code reviews on this repo. Configure here.