Skip to content

websem: admit exact static SVG text faces - #128

Merged
softmarshmallow merged 1 commit into
mainfrom
rung/svg-text-face-descriptors
Sep 3, 2026
Merged

websem: admit exact static SVG text faces#128
softmarshmallow merged 1 commit into
mainfrom
rung/svg-text-face-descriptors

Conversation

@softmarshmallow

Copy link
Copy Markdown
Member

Verdict

T5b is ADMIT/SPLIT, with no checklist closure.

textlayout-v6 now receives one complete typed static face request and requires
one exact (weight, stretch, style) tuple inside the first reached named
family. The Web consumer carries the bounded descriptor profile through the
one Stylo cascade, and the host manifest declares the same exact facts beside
hash-pinned font bytes.

The complete CSS and SVG presentation-attribute font-weight, font-style,
and font-stretch grammars remain open. Fractional weights, arbitrary stretch
percentages, oblique angles, descriptor ranges, directional nearest-face
matching, synthesis, and variation remain explicit boundaries, so this PR
ticks no checklist row.

Measured crux

Chromium 149.0.7827.55 establishes the split around exact static matching:

  • Face matching considers stretch, then style, then weight; exact weight,
    style, stretch, and complete tuples select the exact declared face.
  • When no exact tuple exists, directional nearest-face selection is coupled to
    synthesis. A lone normal Ahem face requested at weight 700 or italic differs
    from its unsynthesized control by 164 or 272 pixels at maximum channel delta
    255. font-synthesis:none returns both to that control.
  • Equal effective tuples are stylesheet-source-order-sensitive. This includes
    italic versus oblique 14deg and normal versus oblique 0deg; the later
    declaration wins. An explicit host manifest has no CSS source-order fact.
  • Blink's font-selection values use signed quarter units and truncate during
    conversion, while the pinned Stylo values use 1/64 and round. Authored
    font-stretch:74.999% therefore selected a declared 74% Bungee face in
    Chromium, while Stylo's computed 75% bucket would select Ahem. Those controls
    differ by 1,062 pixels at maximum delta 255.
  • Chromium independently honors exact font-weight:400.5 and
    font-style:oblique 23deg resources. T5b refuses those wider sources before
    their provenance can disappear.
  • Direct Ahem and Bungee controls differ by 1,062 pixels at maximum delta 255.
    Every branch in the new descriptor cell is exact to an independent all-Ahem
    Chromium construction; changing any one branch to the normal tuple changes
    69 pixels at maximum delta 255.

Every probe used fixtures/web-first/probe_harness.ts and the shared
hash-pinned capture module. The committed cell also rendered through the
actual strict n0 command and matched the Chromium oracle at zero differing
pixels and zero maximum channel delta.

Contract and evidence

  • textlayout advances to v6. Style and every FontResource carry a finite,
    typed StaticFaceDescriptor: integral weight 1 through 1000, one of nine CSS
    stretch points, and normal or italic style.
  • Only an absent named family falls through. A reached family with no exact
    tuple and a reached exact-tuple tie are typed failures; manifest vector order
    cannot select a face. The selected content key and face index remain artifact
    identity.
  • The producer parses no CSS, rounds no source number, performs no nearest-face
    search or synthesis, discovers no ambient font, and does no I/O.
  • font-weight, font-style, and font-stretch presentation attributes enter
    below author CSS through the same Stylo longhands as CSS declarations. No
    second matcher exists, and no descriptor fact crosses rframe.
  • The repeatable host grammar is
    FAMILY=PATH@sha256:HEX[;weight=N][;style=normal|italic][;stretch=POINT].
    Fields are optional and order-independent; malformed, duplicate, unknown,
    and wider values refuse before the environment exists.
  • One new exact 100x100 cell covers six weight, four style, five stretch, and
    one complete-tuple branch across presentation attributes, inline CSS, author
    rules, inheritance, numeric/keyword aliases, and relative weight.
  • Four stable refusal rows guard fractional weight, oblique angle, stretch
    source precision, and a reached family with no exact tuple in strict and
    best-effort admission.
  • The estate is 1,051 primitive Chromium cells plus 16 sampled frames,
    thirteen exact text cells, eight exact-number real-font geometry witnesses,
    and 224 named refusals.

No existing oracle was overwritten. The new text cell was added only through
the fixture tooling; every previous primitive, animation, text, and geometry
oracle was reverified after the shared capture-module change.

Gate sensitivity

I deliberately changed the computed italic mapping to the normal tuple. All
1,051 primitive cells stayed green, then the new text cell failed loudly at
its exact numeric-domain contract. Restoring the italic mapping returned every
primitive, text, geometry, and refusal gate to green.

Workflow review

This environment exposes no Workflow runner for
.agents/workflows/verify-rung.js. I therefore reproduced its two independent
roles by hand as separate passes:

  • TICK/LAW: reread the checklist law and all six descriptor rows; confirmed
    zero tick flips; audited every count and measured-not-celled claim; verified
    that the typed producer owns only exact face selection, the consumer uses the
    one Stylo cascade, rframe is unchanged, and both admissions name every
    retained boundary.
  • REPRO: reran all five scratch Chromium probes, the primitive, animation,
    text, and geometry bakers, the strict CLI pixel comparison, fixture closure,
    manifest provenance/order, all four stable refusal paths, status freshness,
    and the deliberate sensitivity failure/restoration.

The SDK seam discipline was also applied explicitly: the consumer contract was
written first in the ignored textlayout-face-selection.plan.md; an independent
producer maintainer implemented crates/textlayout/**; the consumer then
integrated only the published typed contract.

Verification

  • just bake
  • just text-bake
  • just text-geometry-bake
  • animation Chromium bake (16 sampled frames)
  • just gate
  • just status
  • cargo test --locked -p textlayout -p csscascade -p websem -p n0 -p n0_cli
  • cargo test --quiet --workspace --exclude grida-canvas-wasm
  • cargo fmt --all -- --check
  • cargo clippy --workspace --exclude grida-canvas-wasm --no-deps -- -D warnings
  • Cargo.lock gate controls and branch gate
  • pnpm fmt:check
  • pnpm lint
  • website type-check and production build
  • reftest type-check, build, and 51-test suite
  • git diff --check, added-link build check, and pre-PR OSS diff audit

No conformance score was produced or inspected. FLIP and its record, rule, and
baseline are unchanged.

Refs #43.
Refs #69.

@vercel

vercel Bot commented Sep 3, 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 3, 2026 10:59am UTC

Request Review

@coderabbitai

coderabbitai Bot commented Sep 3, 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: c4b596f8-30cd-4fac-a3c6-4c9cc6476f13

📥 Commits

Reviewing files that changed from the base of the PR and between 73083a4 and 5cc6acc.

⛔ Files ignored due to path filters (6)
  • fixtures/web-first/text/chromium/svg-text-face-descriptor-selection.png is excluded by !**/*.png
  • fixtures/web-first/text/svg-text-face-descriptor-selection.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-text-face-descriptor-fractional-weight.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-text-face-descriptor-oblique.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-text-face-descriptor-source-precision.svg is excluded by !**/*.svg
  • fixtures/web-first/unsupported/svg-text-face-descriptor-unmatched.svg is excluded by !**/*.svg
📒 Files selected for processing (36)
  • AGENTS.md
  • crates/csscascade/src/dom.rs
  • crates/csscascade/tests/svg_presentation_hints.rs
  • crates/n0/src/text_join_spike.rs
  • crates/n0_cli/README.md
  • crates/n0_cli/src/fonts.rs
  • crates/n0_cli/src/main.rs
  • crates/textlayout/Cargo.toml
  • crates/textlayout/src/artifact.rs
  • crates/textlayout/src/environment.rs
  • crates/textlayout/src/face_descriptor.rs
  • crates/textlayout/src/lib.rs
  • crates/textlayout/src/resolve.rs
  • crates/textlayout/tests/oracle_v6.rs
  • crates/textlayout/tests/oracle_v6_face_selection.rs
  • crates/websem/src/svg.rs
  • crates/websem/src/svg_text.rs
  • crates/websem/tests/support/fixture_fonts.rs
  • crates/websem/tests/svg_text.rs
  • crates/websem/tests/svg_text_geometry.rs
  • crates/websem/tests/unsupported_corpus.rs
  • docs/wg/consolidation/index.md
  • docs/wg/consolidation/svg-engine-of-record.md
  • docs/wg/consolidation/text-oracle.md
  • docs/wg/consolidation/web-checklist.md
  • fixtures/web-first/README.md
  • fixtures/web-first/STATUS.md
  • fixtures/web-first/animation/oracle-bake.json
  • fixtures/web-first/chromium_capture.ts
  • fixtures/web-first/oracle-bake.json
  • fixtures/web-first/text/README.md
  • fixtures/web-first/text/bake_chromium.ts
  • fixtures/web-first/text/cases.json
  • fixtures/web-first/text/geometry/oracle-bake.json
  • fixtures/web-first/text/oracle-bake.json
  • 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

Changes

The textlayout oracle advances to v6 with exact static weight, stretch, and style descriptors. Font selection now stops at the first family with resources and requires one exact tuple. SVG cascade, CLI declarations, Chromium fixtures, tests, and documentation carry the new contract.

Exact static face selection

Layer / File(s) Summary
Textlayout descriptor contract and selection
crates/textlayout/..., AGENTS.md, docs/wg/consolidation/...
Adds descriptor types and exact-face matching. Updates typed errors, oracle versioning, tests, and selection documentation.
Cascade and SVG text propagation
crates/csscascade/..., crates/websem/...
Admits SVG font presentation hints. Computes descriptors and passes them through text and tspan layout.
CLI descriptor grammar and environment wiring
crates/n0_cli/..., crates/n0/src/text_join_spike.rs
Parses and validates descriptor suffixes, attaches descriptors to resources and styles, and tests exact rendering.
Fixture baking and oracle records
fixtures/web-first/..., crates/websem/tests/...
Upgrades fixture schemas, adds descriptor font variants and selection coverage, and registers four new refusal cases.

Estimated code review effort: 4 (Complex) | ~60 minutes

Merge Risk: ⚪ Minimal · up to 5cc6a

The exact static face-selection change is covered consistently across descriptor parsing, cascade propagation, resolution, CLI wiring, and fixture/oracle updates. No merge-blocking risk remains.

Sequence Diagram(s)

sequenceDiagram
  participant SVG as SVG text
  participant Cascade as csscascade
  participant Websem as websem
  participant Layout as textlayout
  SVG->>Cascade: font-weight, font-style, font-stretch
  Cascade->>Websem: computed font properties
  Websem->>Layout: StaticFaceDescriptor in Style
  Layout->>Websem: exact face or typed refusal
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.61% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 99 functions across 19 files. (17 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 describes the main change: admitting exact static SVG text face matching.
Description check ✅ Passed The description directly explains the textlayout v6 changes, exact face-selection contract, implementation scope, boundaries, and verification results.
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 60.61% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 99 functions across 19 files. (17 skipped: 16 unsupported, 1 too large.)

  • 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-text-face-descriptors

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 10f94f4 into main Sep 3, 2026
15 checks passed
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