Skip to content

websem: close the SVG <feConvolveMatrix> rows - #110

Merged
softmarshmallow merged 4 commits into
mainfrom
rung/fe-convolve-matrix
Aug 26, 2026
Merged

websem: close the SVG <feConvolveMatrix> rows#110
softmarshmallow merged 4 commits into
mainfrom
rung/fe-convolve-matrix

Conversation

@softmarshmallow

@softmarshmallow softmarshmallow commented Aug 26, 2026

Copy link
Copy Markdown
Member

Verdict

CLOSE/SPLIT.

This rung admits the complete measured static Chromium behavior of <feConvolveMatrix> and closes nine checklist rows: the element plus bias, divisor, edgeMode, kernelMatrix, convolution order, preserveAlpha, targetX, and targetY.

kernelUnitLength remains open for its lighting-primitive applicability. Shared graph, region, interpolation, resource, and dynamics rows remain open.

Measured behavior

Four twice-deterministic Chromium 149.0.7827.55 scratch matrices covered grammar, invalid states, graph routing, effect order, precision, and source classes. Every candidate also rendered through both actual n0 admissions and was compared by pixels.

The admitted contract carries rectangular kernels through 256 coefficients, kernel reversal, ordered divisor arithmetic, bias, asymmetric targets, all three edge modes, alpha preservation, both filter color spaces, all established graph inputs and result reuse, hard regions, primitive units, safe mappings, source geometry, target effects, <use>, and viewBox.

The corpus gains 40 convolution cells plus one blur edgeMode browser-drop cell. It now contains 741 Chromium-baked cells plus 10 sampled frames; the filter estate has 380 cells. Three precision/arithmetic patrols move the named refusal register to 146 rows:

  • general affine convolution target mappings
  • source-dependent paint-server inputs
  • divisors whose reciprocal exceeds finite resolved arithmetic

All 41 new cells are exact-byte controls with no new tolerance. No conformance score was produced or inspected, and this PR takes no FLIP action.

Sensitive gate

I temporarily removed the required kernel reversal. just gate rejected 11 convolution cells; the focused reversal cell changed 230 pixels at maximum channel delta 202, and broad failures reached 2,814 pixels at maximum delta 250. Restoring the reversal returned the complete gate to green.

The first hosted-x86 run then exposed two fixture-only delta-1 rounding surfaces: an sRGB three-color blur source and a fractional-luminance mask. Commit 87a1ab4 replaced those constructions without tolerance. A later full Cargo run found seven residual delta-1 pixels at an unrelated fill-opacity=".58" overlap that survived in the mask cell; commit 3624ed9 removes that fractional source too. Forcing the repaired blur from transparent-edge to repeated-edge sampling rejects it on 806 pixels at maximum delta 102. The opaque binary-mask control is identical to explicit filter-then-mask nesting, differs from reversed effect order on 75 pixels at maximum delta 99, and differs from no mask on 444 pixels at maximum delta 204. The complete 741-cell gate is exact on ARM and hosted x86 in both the dedicated host gate and the full Cargo test binary.

Independent verification

No Workflow runner is exposed in this environment, so .agents/workflows/verify-rung.js could not be invoked through its required tool. I reproduced both roles manually and independently:

  • TICK/LAW audited the exact nine flips, the open kernelUnitLength split, source grammar, and every documentation claim. It found two should-fixes; both were applied.
  • REPRO reran all four scratch matrices, direct target-overflow and divisor-fallback controls, both n0 admissions, and pixel comparisons. It found one scratch label that overstated a whitespace case; the scratch probe was corrected and rerun.

Verification

  • just bake: Chromium 149.0.7827.55 verified all 741 primitive oracles
  • just gate: 741 exact gates green locally on ARM
  • hosted n0 host gate and full Cargo reftest binary: 741 exact gates green on x86
  • just status: generated capability view fresh
  • cargo test --workspace --exclude grida-canvas-wasm
  • cargo clippy --no-deps --workspace --exclude grida-canvas-wasm -- -D warnings
  • cargo fmt --all -- --check
  • pnpm fmt:check
  • pnpm exec oxlint --deny-warnings
  • www typecheck and production build
  • grida-reftest typecheck, build, and tests
  • pre-PR OSS and link audit

@vercel

vercel Bot commented Aug 26, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
nothing Ready Ready Preview Aug 26, 2026 8:18pm

Request Review

@coderabbitai

coderabbitai Bot commented Aug 26, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

Next included review available in 20 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 428b200f-0a8d-4b1e-b350-6316eefc447a

📥 Commits

Reviewing files that changed from the base of the PR and between 693e9c4 and 3624ed9.

⛔ Files ignored due to path filters (86)
  • fixtures/web-first/chromium/svg-filter-blur-edge-mode-drop.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-axis-fractional.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-bias-large.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-blur-before.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-color-auto.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-color-default.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-color-linear.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-color-srgb.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-divisor-bias-target-grammar.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-divisor-sum-order.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-divisor-sum-overflow.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-edge-alpha-kernel-unit-grammar.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-empty-bias.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-generated-input.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-input-previous.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-kernel-large-65.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-kernel-max-256.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-kernel-over-max.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-kernel-reversal.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-kernel-texture-29.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-kernel-texture-64.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-kernel-uniform-28.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-morphology-after.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-order-kernel-grammar.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-primitive-units.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-quarter-turn.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-region-crop.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-result-reuse.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-sharpen.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-source-alpha-preserve.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-source-alpha.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-source-group.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-source-number-alias.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-source-path.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-source-stroke.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-target-clip.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-target-mask.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-target-opacity.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-target-y.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-use.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-filter-convolve-viewbox.png is excluded by !**/*.png
  • fixtures/web-first/svg-filter-blur-edge-mode-drop.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-axis-fractional.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-bias-large.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-blur-before.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-color-auto.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-color-default.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-color-linear.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-color-srgb.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-divisor-bias-target-grammar.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-divisor-sum-order.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-divisor-sum-overflow.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-edge-alpha-kernel-unit-grammar.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-empty-bias.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-generated-input.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-input-previous.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-kernel-large-65.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-kernel-max-256.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-kernel-over-max.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-kernel-reversal.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-kernel-texture-29.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-kernel-texture-64.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-kernel-uniform-28.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-morphology-after.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-order-kernel-grammar.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-primitive-units.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-quarter-turn.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-region-crop.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-result-reuse.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-sharpen.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-source-alpha-preserve.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-source-alpha.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-source-group.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-source-number-alias.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-source-path.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-source-stroke.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-target-clip.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-target-mask.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-target-opacity.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-target-y.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-use.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-filter-convolve-viewbox.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-filter-convolve-arithmetic-range.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-filter-convolve-paint-server-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-filter-convolve-transform-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-filter-primitive.svg is excluded by !**/*.svg
📒 Files selected for processing (16)
  • crates/n0/src/drawlist.rs
  • crates/n0/src/glyphless.rs
  • crates/n0/src/paint.rs
  • crates/n0_cli/README.md
  • crates/rframe/src/filter.rs
  • crates/rframe/src/lib.rs
  • crates/rframe/tests/filter_contract.rs
  • crates/websem/src/svg.rs
  • crates/websem/tests/unsupported_corpus.rs
  • docs/wg/consolidation/svg-engine-of-record.md
  • docs/wg/consolidation/web-checklist.md
  • fixtures/web-first/README.md
  • fixtures/web-first/STATUS.md
  • fixtures/web-first/oracle-bake.json
  • fixtures/web-first/primitives.json
  • fixtures/web-first/unsupported/README.md
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rung/fe-convolve-matrix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@softmarshmallow

Copy link
Copy Markdown
Member Author

Hosted-x86 exact-gate follow-up

The first hosted Cargo run found two fixture-only one-channel differences:

  • svg-filter-blur-edge-mode-drop: 336 pixels at maximum delta 1.
  • svg-filter-convolve-target-mask: 223 pixels at maximum delta 1.

Etiology: both controls unnecessarily sat on architecture-sensitive fractional raster surfaces. The blur source mixed three colors through an sRGB Gaussian kernel; the mask used #777, producing fractional luminance-mask coverage. Neither failure implicated feConvolveMatrix parsing, graph semantics, or its backend operation.

Commit 87a1ab4 replaces those constructions without tolerance: the blur control now uses a single-color boundary source in the default filter color space, and the mask control uses binary white/black geometry. Both replacements were recaptured through the hash-pinned Chromium module, rendered through strict and best-effort n0, and compared exactly on ARM.

Gate sensitivity remains explicit. Forcing nonzero Gaussian blur from transparent-edge to repeated-edge sampling makes the repaired blur cell fail on 806 pixels at maximum channel delta 102. Restoring the production path returns the complete 741-cell gate to green. The binary target-mask candidate differs from its no-mask control by 444 pixels at maximum channel delta 202.

No renderer code, tolerance, baseline rule, score, or FLIP record changed in this follow-up.

@softmarshmallow

Copy link
Copy Markdown
Member Author

Hosted-x86 exact-gate follow-up 2

The full Cargo job exercised a second test binary after the hosted n0 host gate passed and found seven residual pixels at maximum delta 1 in svg-filter-convolve-target-mask. The first differing pixel lies on the semi-transparent green overlap.

Etiology: the binary mask removed the original fractional luminance surface, but its source still carried unrelated fill-opacity=".58". That fractional source alpha was unnecessary to test target-mask ordering and remained architecture-sensitive. This is still fixture design, not convolution semantics.

Commit 3624ed9 makes the source opaque. Its Chromium 149 scratch matrix was twice deterministic and proves the claimed branch directly:

  • same-element filter+mask equals explicit filter-then-mask exactly;
  • reversing the effect order differs on 75 pixels at maximum delta 99;
  • removing the mask differs on 444 pixels at maximum delta 204.

All nine scratch candidates render exactly against Chromium through both strict and best-effort n0. The pinned bake verified all 741 oracles, and the local exact gate and status gate are green. The previous unmerged oracle was moved to /private/tmp/svg-filter-convolve-target-mask-pr110-second.png before the fresh bake; it was not overwritten. Final hosted x86 checks are now running.

@softmarshmallow
softmarshmallow merged commit b69e8e0 into main Aug 26, 2026
15 checks passed
@softmarshmallow
softmarshmallow deleted the rung/fe-convolve-matrix branch August 26, 2026 20:43
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.

1 participant