Skip to content

websem: admit ordered radial gradient circles - #134

Merged
softmarshmallow merged 1 commit into
mainfrom
rung/svg-radial-gradient-start-circle
Sep 6, 2026
Merged

websem: admit ordered radial gradient circles#134
softmarshmallow merged 1 commit into
mainfrom
rung/svg-radial-gradient-start-circle

Conversation

@softmarshmallow

@softmarshmallow softmarshmallow commented Sep 6, 2026

Copy link
Copy Markdown
Member

Outcome

Admit the bounded SVG fx/fy/fr slice through the engine of record. Keep
all three checklist rows open: Chromium-honored numeric provenance aliases
and CSS comments still require named refusals and have no own checklist row.

Measured crux and contract

The proposed start-only extension with a fixed nonzero end circle could not
represent Chromium's live zero-end radial. The owner GO ratifies the corrected
ordered-circle amendment: an optional pair preserves both centers, both
nonnegative radii, and their order. The absent form preserves old centered
serialization, debug output, and rendering. An independent producer maintainer
implemented cg/n0-model; consumers copy the complete fact without converting
through alignment or renormalizing geometry.

The probe also caught a shipped one-stop constant-fold escape: one color does
not mean an infinite painted domain. Chromium leaves 109 exterior pixels
unpainted, at maximum channel delta 217 against the old full-solid result.
The new route keeps the conical shader even for a one-stop ramp, including
repeat/reflect and zero-end cases.

Evidence and safety

  • 127 cells added only through just add, then Chromium-baked through the
    existing hash-pinned capture module. All 1,157 old oracle records/PNGs and old
    manifest records are unchanged. Total: 1,284 primitives plus 16 sampled frames;
    the 16 text pixel cells and 8 real-font geometry witnesses are unchanged.
  • 119 new cells are exact. Eight carry the existing ramp-quantization kind at
    measured bounds only: six 1px/Δ1 cells, mask 613px/Δ1, offset-filter 1,465px/Δ1.
    No blanket tolerance, old-cell weakening, numeric-control tolerance, or
    oracle overwrite.
  • Chromium 149 matrices cover 35 core, 75 precision/grammar, 262 interaction,
    64 boundary, 2 HTML, and 2 graduation sources. Every source also rendered
    through actual cargo run -p n0_cli --bin n0 in strict and best effort.
    The 9 amplified decimal/percentage/midpoint aliases choose the lower binary32
    neighbor; opposing controls differ 718–1,024px/Δ14–34. A separate amplified
    diagonal experiment did not discriminate Chromium controls and reached
    checked shader-construction refusal: no new normalization claim is made.
  • Replace 1 broad focal refusal with 27 exact-attribute fixtures: 260 total.
    Wider value/context families retain their own rows. No private CSS matcher,
    external I/O, animation, marker-source expansion, or other family is added.
  • Incapable Draft0/.grida writers reject present geometry, including inactive
    paints and strokes; frozen schema and old decoding are unchanged. Legacy
    painting carries the fact; legacy SVG import remains unchanged in scope.
  • Preview offscreen translation exposed 2px/Δ1 versus direct execution. A typed
    node-attributed cache refusal occurs before canvas/cache mutation. Direct
    retained-frame replay equals fresh, and paint changes retain owner damage.
    This does not attempt a generic cache precision repair.

Captured-essence ledger: the old focal refusal source graduates unchanged to
svg-radial-start-graduated-focal. Its obsolete inexpressibility assertion is
deliberately dropped. The temporary one-stop refusal is replaced by positive
domain witnesses. No other refusal, oracle, or unrelated caveat is dropped.

Gate sensitivity

Deliberately removing the start radius fails 79 cells (max 3,072px/Δ255); reversing
circle order fails 108 (max 4,096px/Δ255); replacing the normalized diagonal with
width fails 2 cells (each 1,116px/Δ214); premature one-stop folding fails 4
(three 109px and one 1,938px, all Δ217). Restore each mutation; final complete
just gate and just status are green, including every retained refusal.

Verification

  • just bake, just gate, just status: passed; additions-only manifest and
    oracle audit passed, capture policy/hash unchanged.
  • Producer cg/n0-model all-feature tests, focused websem/n0/rframe/legacy
    consumer tests, and legacy all-target check: passed.
  • cargo fmt --all -- --check, cargo clippy --no-deps, and CI's workspace
    Clippy with -D warnings: passed.
  • The initial workspace cargo test passed all non-Web crates, then its
    already-built status test failed after the audit corrected the generator
    mid-run. A fresh complete cargo test -p websem passed, as did
    cargo test --workspace --doc. The final cache suite, retained-frame replay,
    and active/inactive frozen-format guards passed after their last edits.
  • Link resolution and pre-PR public-data audit: passed.
  • Independent TICK/LAW: passed after correcting three documentation findings.
    Independent REPRO: passed after fixing and independently rerunning the
    scratch graduation wrapper against the moved, unchanged positive source.
    No must_fix or should_fix findings remain.
  • Hosted CI: all checks passed on ffc820e9, including the complete Linux
    test suite, strict Clippy, canvas build, legacy pixel sweep, native host and
    architecture gates, and docs/Node builds. The existing eight new measured
    blocks sufficed on Linux; no oracle or tolerance was changed for CI.
    CodeRabbit completed with no actionable comments.

No Workflow runner is exposed in this environment, so
.agents/workflows/verify-rung.js could not be invoked through scriptPath.
Its independent TICK/LAW and REPRO roles are reproduced manually by separate
reviewers, not presented as a successful Workflow invocation.

No conformance score was produced or inspected. No FLIP record, rule, or
baseline changed. No checklist tick changed; #81/#89/#90 split precedent
applies. External resources, text, generic damage/cache work, and #93 remain
separate follow-ups.

Preserve both circles and one-stop cone domains through the shared paint contract. Add 127 Chromium cells and 27 focused refusals without closing fx/fy/fr. Graduate the former focal refusal source unchanged; deliberately drop its obsolete inexpressibility assertion after re-homing the geometry in positive evidence. Keep frozen writers and preview-cache precision behind explicit guards.
@vercel

vercel Bot commented Sep 6, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated
nothing Ready Ready Preview Sep 6, 2026 9:44pm UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 6, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 1ed5d1a7-ea7f-4218-9c31-e97f36752dc3

📥 Commits

Reviewing files that changed from the base of the PR and between f5f61d1 and ffc820e.

⛔ Files ignored due to path filters (280)
  • fixtures/web-first/chromium/html-inline-svg-radial-start.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-box-percent.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-channel-opacity.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-clip.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-dashes.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-ellipse.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-filter.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-group-opacity.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-mask.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-nested.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-order.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-path.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-pattern.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-stroke.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-transform.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-client-use.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-default.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-explicit-default.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-decimal-higher.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-decimal-lower.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-equal-r.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-greater-r.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-midpoint-higher.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-midpoint-lower.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-negative-zero.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-negative.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-percentage-higher.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-percentage-lower.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fr-quarter.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-decimal-higher.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-decimal-lower.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-negative.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-on-end.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-outside.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-percentage-higher.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-percentage-lower.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fx-quarter.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fxy-fr-quarter.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fxy-quarter.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fy-decimal-higher.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fy-decimal-lower.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fy-percentage-higher.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fy-percentage-lower.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-fy-quarter.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-graduated-focal.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fr-comma.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fr-exponent.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fr-integer.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fr-nbsp.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fr-signed.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fr-trailingdot.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fr-whitespace.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fx-comma.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fx-exponent.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fx-integer.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fx-nbsp.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fx-signed.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fx-trailingdot.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fx-whitespace.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fy-comma.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fy-exponent.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fy-integer.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fy-nbsp.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fy-signed.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fy-trailingdot.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-grammar-fy-whitespace.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-mapped-viewbox.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-on-end-reflect.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-on-end-repeat.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-one-stop-default.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-one-stop-exterior-reflect.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-one-stop-exterior-repeat.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-one-stop-focal.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-outer-negative-focal.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-outer-zero-focal.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-outer-zero-fr.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-outer-zero-fx.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-outer-zero-one-stop-focal.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-outside-positive-fr.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-above.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-below.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-containing.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-disjoint.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-external-tangent.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-internal-tangent.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-intersecting.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-left.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-relation-right.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-same-circle-reflect.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-same-circle-repeat.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-circle-reflect.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-circle-repeat.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-outside-reflect.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-outside-repeat.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-reversed-reflect.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-reversed-repeat.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-zero-end-reflect.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-spread-zero-end-repeat.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-stops-alpha.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-stops-duplicate.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-stops-edges.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-stops-unsorted.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-all.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-empty-fr.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-empty-fx.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-empty-fy.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-explicit-focus.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-fr-negative.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-fr-zero.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-invalid-fr.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-local-center.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-multihop.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-override-fr.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-override-fx.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-override-fy.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-template-xlink.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-transform-rotate.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-transform-scale.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-transform-singular.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-transform-skew.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-transform-translate.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-transparent-cone.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-user-percent-fr.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-user-percent-fx.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-user-percent-fy.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-user-px.png is excluded by !**/*.png
  • fixtures/web-first/chromium/svg-radial-start-zero-stops-focal.png is excluded by !**/*.png
  • fixtures/web-first/svg-radial-start-box-percent.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-channel-opacity.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-clip.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-dashes.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-ellipse.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-filter.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-group-opacity.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-mask.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-nested.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-order.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-path.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-pattern.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-stroke.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-transform.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-client-use.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-default.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-explicit-default.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-decimal-higher.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-decimal-lower.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-equal-r.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-greater-r.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-midpoint-higher.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-midpoint-lower.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-negative-zero.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-negative.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-percentage-higher.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-percentage-lower.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fr-quarter.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-decimal-higher.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-decimal-lower.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-negative.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-on-end.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-outside.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-percentage-higher.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-percentage-lower.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fx-quarter.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fxy-fr-quarter.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fxy-quarter.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fy-decimal-higher.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fy-decimal-lower.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fy-percentage-higher.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fy-percentage-lower.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-fy-quarter.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-graduated-focal.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fr-comma.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fr-exponent.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fr-integer.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fr-nbsp.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fr-signed.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fr-trailingdot.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fr-whitespace.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fx-comma.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fx-exponent.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fx-integer.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fx-nbsp.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fx-signed.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fx-trailingdot.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fx-whitespace.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fy-comma.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fy-exponent.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fy-integer.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fy-nbsp.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fy-signed.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fy-trailingdot.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-grammar-fy-whitespace.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-mapped-viewbox.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-on-end-reflect.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-on-end-repeat.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-one-stop-default.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-one-stop-exterior-reflect.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-one-stop-exterior-repeat.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-one-stop-focal.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-outer-negative-focal.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-outer-zero-focal.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-outer-zero-fr.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-outer-zero-fx.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-outer-zero-one-stop-focal.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-outside-positive-fr.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-above.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-below.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-containing.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-disjoint.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-external-tangent.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-internal-tangent.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-intersecting.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-left.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-relation-right.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-same-circle-reflect.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-same-circle-repeat.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-circle-reflect.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-circle-repeat.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-outside-reflect.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-outside-repeat.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-reversed-reflect.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-reversed-repeat.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-zero-end-reflect.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-spread-zero-end-repeat.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-stops-alpha.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-stops-duplicate.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-stops-edges.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-stops-unsorted.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-all.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-empty-fr.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-empty-fx.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-empty-fy.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-explicit-focus.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-fr-negative.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-fr-zero.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-invalid-fr.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-local-center.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-multihop.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-override-fr.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-override-fx.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-override-fy.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-template-xlink.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-transform-rotate.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-transform-scale.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-transform-singular.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-transform-skew.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-transform-translate.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-transparent-cone.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-user-percent-fr.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-user-percent-fx.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-user-percent-fy.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-user-px.svg is excluded by !**/*.svg
  • fixtures/web-first/svg-radial-start-zero-stops-focal.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-css-comments.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-css-wide.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-decimal-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-math.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-midpoint-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-percentage-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-units.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-used-range.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fr-var.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-css-comments.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-css-wide.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-decimal-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-math.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-midpoint-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-percentage-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-units.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-used-range.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fx-var.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-css-comments.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-css-wide.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-decimal-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-math.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-midpoint-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-percentage-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-units.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-used-range.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-radial-start-fy-var.svg is excluded by !**/*.svg
📒 Files selected for processing (37)
  • crates/cg/src/types.rs
  • crates/cg/tests/radial_geometry.rs
  • crates/grida/examples/fixture_helpers/mod.rs
  • crates/grida/examples/fixtures/cover.rs
  • crates/grida/examples/fixtures/l0_paints_stack.rs
  • crates/grida/src/import/svg/paint.rs
  • crates/grida/src/io/io_grida_fbs.rs
  • crates/grida/src/painter/gradient.rs
  • crates/grida/tests/fbs_roundtrip.rs
  • crates/n0-model/README.md
  • crates/n0-model/src/model.rs
  • crates/n0-model/src/renderability.rs
  • crates/n0-model/src/textir.rs
  • crates/n0-model/tests/paint_rfd_conformance.rs
  • crates/n0-model/tests/radial_geometry.rs
  • crates/n0/src/cache.rs
  • crates/n0/src/glyphless.rs
  • crates/n0/src/paint.rs
  • crates/n0/tests/cache.rs
  • crates/n0_cli/README.md
  • crates/rframe/README.md
  • crates/rframe/tests/paint_stack.rs
  • crates/websem/src/svg_paint_server.rs
  • crates/websem/tests/capability_status.rs
  • crates/websem/tests/gradients_contract.rs
  • crates/websem/tests/radial_gradients_contract.rs
  • crates/websem/tests/unsupported_corpus.rs
  • docs/wg/consolidation/svg-engine-of-record.md
  • docs/wg/consolidation/web-checklist.md
  • docs/wg/feat-painting/paint-model.md
  • fixtures/web-first/README.md
  • fixtures/web-first/STATUS.md
  • fixtures/web-first/html-inline-svg-radial-start.html
  • fixtures/web-first/oracle-bake.json
  • fixtures/web-first/primitives.json
  • fixtures/web-first/probe_harness.ts
  • fixtures/web-first/unsupported/README.md

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

This change adds optional ordered start and end circles to radial gradients, preserves them through SVG import and runtime rendering, rejects them at unsupported serialization and preview-cache boundaries, and expands tests, fixtures, corpus records, and documentation for the new contract.

Changes

Ordered radial-circle support

Layer / File(s) Summary
Model and serialization contract
crates/cg/src/types.rs, crates/cg/tests/radial_geometry.rs, crates/n0-model/src/model.rs, crates/n0-model/src/renderability.rs, crates/n0-model/src/textir.rs, crates/n0-model/tests/*, crates/grida/examples/*, crates/grida/src/import/svg/paint.rs, crates/n0-model/README.md
RadialGradientPaint now has optional geometry with ordered start and end circles. Defaults keep the implicit centered radial. Validation, debug/serde behavior, model round-trips, and Draft 0/TextIr refusal cases now cover present geometry.
Rendering and format boundaries
crates/grida/src/painter/gradient.rs, crates/grida/src/io/io_grida_fbs.rs, crates/grida/tests/fbs_roundtrip.rs, crates/n0/src/glyphless.rs, crates/n0/src/paint.rs, crates/n0/src/cache.rs, crates/n0/tests/cache.rs, crates/rframe/tests/paint_stack.rs
Painters and shaders now use explicit circle geometry when present. cg→n0 compilation preserves the circles. The frozen encoder and preview cache now reject explicit geometry instead of dropping it, and tests cover rendering, preflight, diffing, and cache refusal.
SVG focal radial admission
crates/websem/src/svg_paint_server.rs, crates/websem/tests/gradients_contract.rs, crates/websem/tests/radial_gradients_contract.rs, crates/websem/tests/unsupported_corpus.rs, crates/websem/tests/capability_status.rs
SVG import now converts supported fx/fy/fr radial gradients into explicit circle geometry. One-stop radial handling keeps the conical domain. Contract tests now cover admitted focal geometry, inherited overrides, user-space percent resolution, and exact refusal reasons for unsupported value families.
Corpus and fixture expansion
fixtures/web-first/primitives.json, fixtures/web-first/oracle-bake.json, fixtures/web-first/STATUS.md, fixtures/web-first/html-inline-svg-radial-start.html, fixtures/web-first/probe_harness.ts, fixtures/web-first/unsupported/README.md
The web-first corpus adds radial-start fixtures, inline-HTML capture support, updated oracle metadata, new admitted cells, and narrower refusal rows for unsupported fx/fy/fr inputs.
Spec and README updates
docs/wg/feat-painting/paint-model.md, docs/wg/consolidation/svg-engine-of-record.md, docs/wg/consolidation/web-checklist.md, crates/n0_cli/README.md, crates/rframe/README.md, fixtures/web-first/README.md
Docs now define gradient-local radial circle geometry, record the ratified ordered-circle amendment, describe unsupported boundaries that must reject present geometry, and update evidence and coverage counts for the expanded radial corpus.

Estimated code review effort: 5 (Critical) | ~120 minutes

Merge Risk: ⚪ Minimal · up to ffc82

No actionable merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant SVG as SVG radialGradient
  participant Websem as websem parser
  participant CG as cg radial paint
  participant N0 as n0 renderer
  participant Cache as scene cache

  SVG->>Websem: fx / fy / fr + stops
  Websem->>CG: RadialGradientPaint with optional geometry
  CG->>N0: compiled radial paint
  N0->>N0: use conical shader when geometry exists
  N0->>Cache: submit frame or replacement drawlist
  Cache->>Cache: reject preview caching if geometry exists
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 82 functions across 25 files. (12 skipped… 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 identifies the main change: admitting ordered radial gradient circles in websem.
Description check ✅ Passed The description directly explains the ordered radial gradient circle support, compatibility behavior, testing, refusals, and verification for the changeset.
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.
Full details: Docstring Coverage

Explanation

Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 82 functions across 25 files. (12 skipped: 12 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch rung/svg-radial-gradient-start-circle

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
softmarshmallow merged commit fd4097f into main Sep 6, 2026
15 checks passed
@softmarshmallow
softmarshmallow deleted the rung/svg-radial-gradient-start-circle branch September 6, 2026 22:10
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