Skip to content

fix: visual-diff marked boxes snap to quiet seams - #1

Merged
Cervator merged 5 commits into
mainfrom
fix/marked-box-snapping
Aug 10, 2026
Merged

Cervator merged 5 commits into
mainfrom
fix/marked-box-snapping

Conversation

@agent-refr

Copy link
Copy Markdown
Contributor

AI-assisted change proposal. Filed by agent driven by @Cervator via GDD.

Summary

  • Fixes the visual-diff marked images the owner flagged on chore: tighten home tagline (preview smoke test) mtl-hockey#1: the ring was the raw changed-pixel bounding box, so its edges landed mid-glyph (top edge set by a new comma's topmost pixel read as a strikethrough across unchanged words; desktop's tight crop showed disorienting mid-line slivers).
  • Ring edges now snap outward to the nearest quiet background seam of the after image (rows capped 48px; columns 480px so desktop crops widen to whole readable lines), with the stroke drawn just outside the snapped bounds; layouts with no seam within the cap keep the previous capped behavior.
  • README trust-model addendum from the port review: volundr must stay public (or callers need a token grant) because the diff job checks this repo out with the caller's GITHUB_TOKEN.

Test plan

  • Reproduced the defect locally by running diff.mjs over the exact before/after screenshots from mtl-hockey#1's diff artifacts; patched output rings the two changed lines completely with all glyphs intact and every edge in whitespace
  • After merge: re-run mtl-hockey#1's PR preview and eyeball the regenerated marked images (mobile + desktop)

Related

… slice glyphs

The raw changed-pixel bounding box put ring edges mid-glyph (a new trailing comma's topmost pixel set the box top mid-line, striking through unchanged words — observed on mtl-hockey#1's smoke diff). Edges now grow outward to the nearest uniform-background seam (rows capped at 48px, columns at 480px so desktop crops widen to whole readable lines), stroke drawn just outside the snapped bounds; busy layouts with no seam keep the old capped behavior. Verified locally against the exact failing screenshots. README also gains the stay-public caveat for the cross-repo tooling checkout.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 22 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 407255ab-f2a3-46d7-bf50-1a534405d0e7

📥 Commits

Reviewing files that changed from the base of the PR and between 4ebaa29 and 5e4c5f5.

📒 Files selected for processing (2)
  • visual-diff/snap.mjs
  • visual-diff/snap.test.mjs
📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved visual diff annotations by aligning changed-region boundaries with nearby blank areas.
    • Updated marked and cropped comparison images to use more precise region boundaries.
    • Refined visual diff reports with clearer before-and-after comparisons and less prominent pixel-diff images.
  • Documentation

    • Clarified trust requirements for pull request preview comparisons, including repository visibility and token requirements.
  • Tests

    • Added automated coverage for visual diff boundary detection across common layout scenarios.

Walkthrough

The visual diff job snaps changed-region boxes to quiet seams in the candidate image. It uses the snapped boxes for annotations and crops. Reports now show before and after images without displayed pixel-diff images. Tests cover edge and gap cases. The README documents the checkout token and repository visibility requirements.

Changes

Visual diff annotations

Layer / File(s) Summary
Snapped diff boxes
visual-diff/snap.mjs, visual-diff/diff.mjs
The job detects quiet rows and columns, snaps changed-region boxes, applies them to annotations and crops, and removes displayed pixel-diff images and links from reports.
Snapping validation
visual-diff/snap.test.mjs, visual-diff/package.json
The Node test suite covers insertion, deletion, quiet stroke bands, and 1–3px neighboring gaps. The package adds a node --test script.

Checkout trust model

Layer / File(s) Summary
Checkout requirements
README.md
The trust model documents that the repository must remain public unless callers provide an explicit token grant.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DiffJob
  participant snapBox
  participant ImageReports
  DiffJob->>snapBox: changed-region box and candidate image
  snapBox->>DiffJob: snapped box or raw edges
  DiffJob->>ImageReports: annotations, crops, and report references
Loading

Suggested reviewers: cervator

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 57.14% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: snapping visual-diff marked boxes to quiet seams.
Description check ✅ Passed The description directly explains the visual-diff fix, its behavior, trust-model update, and test plan.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/marked-box-snapping

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@README.md`:
- Line 67: Update the README statement about the pr-preview diff job to match
the supported access model: either document and implement a workflow_call secret
passed as the second checkout’s with.token, or remove the explicit-token
fallback and state that SiliconSaga/volundr must remain public. Ensure the
documentation does not imply the caller’s GITHUB_TOKEN can access a separate
private repository.

In `@visual-diff/diff.mjs`:
- Around line 149-160: Update the seek logic and its edge checks so a candidate
boundary is accepted only when BOX_STROKE consecutive rows or columns on the
exterior side are quiet, rather than relying on a single quiet row or column.
Ensure both insertion and deletion paths validate this exterior quiet band
before stopping, while preserving bounds handling and add coverage for one- to
three-pixel gaps.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 4119a5b3-f68b-4a5f-a3cb-848a32212844

📥 Commits

Reviewing files that changed from the base of the PR and between d8ba03e and a93c13f.

📒 Files selected for processing (2)
  • README.md
  • visual-diff/diff.mjs

Comment thread README.md Outdated
Comment thread visual-diff/diff.mjs Outdated
Cervator and others added 2 commits August 9, 2026 20:49
…erased

Owner feedback on the smoke diff: magenta tint over newly-added glyphs reads as deletion. Comment and report now carry marked + before/after only; the mask PNG is still written for debugging.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…s, honest README

Edges now require the full exterior stroke band quiet (a 1px seam no longer passes; deletion's d=0 edge is validated too) with raw-edge fallback; snapping extracted to snap.mjs with node --test coverage for insertion/deletion and 1-3px gaps; README states volundr must remain public (a caller's GITHUB_TOKEN cannot read a different private repo).

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@visual-diff/snap.mjs`:
- Around line 15-37: Update isQuietRow and isQuietCol in visual-diff/snap.mjs to
require that candidate bands represent unchanged background content, rather than
accepting any uniformly colored band; compare alpha alongside RGB in the pixel
predicate. In visual-diff/snap.test.mjs lines 28-37, assert the selected stroke
band is background content and add coverage for a uniform dark unchanged bar
that must not be selected.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b2be563f-d0ef-4772-83c8-19cb05590030

📥 Commits

Reviewing files that changed from the base of the PR and between 8f1fc22 and 5700477.

📒 Files selected for processing (4)
  • visual-diff/diff.mjs
  • visual-diff/package.json
  • visual-diff/snap.mjs
  • visual-diff/snap.test.mjs

Comment thread visual-diff/snap.mjs Outdated
Cervator and others added 2 commits August 9, 2026 22:03
Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…iform

Review round 2: a solid rule or banner interior is uniform but is content — bands now qualify only when they match the local background, estimated by 8-point majority vote on the crop perimeter (follows dark-themed pages; no majority → no snapping). Alpha included in comparisons; new test proves a stroke-thick uniform dark rule is never selected, asserted on raw pixels rather than the predicate under test.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
@Cervator
Cervator merged commit d6807e0 into main Aug 10, 2026
1 check passed
@Cervator
Cervator deleted the fix/marked-box-snapping branch August 10, 2026 04:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants