Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion .github/workflows/consolidation-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ jobs:
rust-toolchain.toml \
crates \
fixtures \
packages/grida-reftest/svg-assertions \
packages/grida-reftest/package.json \
packages/grida-reftest/tsconfig.json \
packages/grida-reftest/vitest.config.ts \
package.json \
pnpm-lock.yaml \
pnpm-workspace.yaml \
.nvmrc \
third_party; then
engine=true
fi
Expand Down Expand Up @@ -87,7 +95,11 @@ jobs:
needs: scope
if: needs.scope.outputs.engine == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 45
# Existing architecture budget plus the pilot's bounded cold CLI build.
timeout-minutes: 65
env:
# Reports are immutable observations, not reusable Cargo build outputs.
SVG_ASSERTION_DIR: svg-assertion-pilot-${{ github.run_id }}-${{ github.run_attempt }}
steps:
- name: Checkout head revision
uses: actions/checkout@v4
Expand Down Expand Up @@ -133,6 +145,9 @@ jobs:
uses: Swatinem/rust-cache@v2
with:
shared-key: consolidation-seams
# Seed a cache containing the new dev-profile CLI build, not only
# the prior test-profile artifacts restored by the old immutable key.
key: svg-assertion-pilot-v1
cache-all-crates: true
cache-workspace-crates: true
cache-on-failure: true
Expand All @@ -159,6 +174,40 @@ jobs:
cargo test --locked -p rframe --test architecture
cargo test --locked -p n0 --test architecture

- name: Setup pnpm for the SVG assertion pilot
uses: pnpm/action-setup@v4

- name: Setup Node for the SVG assertion pilot
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: pnpm

- name: Install the pinned assertion-tool dependencies and Chromium
run: |
pnpm install --frozen-lockfile
pnpm -C packages/grida-reftest exec playwright install --with-deps chromium

- name: Verify assertion contracts and the actual n0 CLI pilot
# The registry crate uses its packaged VCS identity for binary downloads.
# FORCE_SKIA_BINARIES_DOWNLOAD selects an upstream-checkout test path
# which instead builds Skia from source when no Git checkout exists.
run: |
pnpm -C packages/grida-reftest exec tsc --noEmit -p svg-assertions/tsconfig.json
pnpm -C packages/grida-reftest exec vitest run svg-assertions --passWithNoTests=false
pnpm -C packages/grida-reftest exec tsx svg-assertions/cli.ts \
--manifest "$GITHUB_WORKSPACE/packages/grida-reftest/svg-assertions/pilot.json" \
--out "$RUNNER_TEMP/$SVG_ASSERTION_DIR"

- name: Upload SVG assertion observations
if: always()
uses: actions/upload-artifact@v4
with:
name: svg-assertion-pilot-${{ github.run_id }}
path: ${{ runner.temp }}/${{ env.SVG_ASSERTION_DIR }}
if-no-files-found: warn
retention-days: 7

legacy_pixel_sweep:
name: legacy pixel sweep
needs: scope
Expand Down
2 changes: 1 addition & 1 deletion crates/n0_cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -607,7 +607,7 @@ cargo run -p n0_cli --bin n0 -- \
The filter estate contains 26 chassis/blur cells, 60 shadow-graph, 28 native
drop-shadow, 27 color-matrix, 34 component-transfer, 38 blend, 37 morphology,
91 turbulence/displacement, 41 convolution-rung, and 71 diffuse-lighting
cells. The complete primitive corpus contains 1,537 Chromium-baked cells plus
cells. The complete primitive corpus contains 1,539 Chromium-baked cells plus
16 sampled frames; the text estate contains sixteen exact text pixel cells and
eight exact-number artifact-geometry witnesses (six Allerta and two
Bungee), and the named refusal register has 351 rows. `feFlood`, `feComposite`,
Expand Down
66 changes: 65 additions & 1 deletion docs/wg/consolidation/svg-engine-of-record.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ from the dated addenda below:
carrying admitted repeating-pattern paint and admitted source/target filter
composition.
`crates/n0_cli/README.md` is the statement of record.
- **The corpus** is 1,537 Chromium-baked primitive cells plus 16 sampled frames,
- **The corpus** is 1,539 Chromium-baked primitive cells plus 16 sampled frames,
with a separate sixteen-cell exact text suite whose current cells select
hash-pinned Ahem and Ahem-derived bytes from explicit family/face
environments, and eight exact-number artifact-geometry
Expand Down Expand Up @@ -6523,3 +6523,67 @@ The reproducer renewed the captures and 284 CLI executions under one fixed
binary, verified old records and oracle bytes, and reran the full gate and
status without further diff. Full relevant tests, trace execution/pixels,
formatting, strict Clippy and link/OSS checks pass.

## 2026-09-09 — assertion-driven SVG harness pilot

The owner-approved [assertion proposal](https://github.com/gridaco/nothing/issues/140)
adds an observation and regression instrument, not a rendering capability or a
new support inventory. Its [contract and setup](../../../packages/grida-reftest/svg-assertions/README.md)
separate input identity, a described claim, renderer observations, the chosen
reference, and a discrete verdict. A named-refusal assertion cannot be read as
rendering support; a required unresolved/missing case cannot become a passing
gate. Image differences remain diagnostic evidence, never a similarity score.

The pilot imports the unchanged resvg-test-suite sharp-rectangle source and a
separate color-control derivative through the existing primitive workflow,
with upstream identity and MIT notice retained. Each is exact to its own
Chromium oracle at a 500×500 initial viewport, in both actual CLI admissions.
Changing only the subject fill changes 160,000 Chromium pixels at maximum
channel delta 255, while the decorative frame and underlay remain unchanged.
The existing geometry-unit refusal witness supplies the separate refusal
assertion; it is not promoted or duplicated in the refusal register.

The complete primitive corpus now contains 1,539 cells. The 351 refusal rows,
16 sampled frames, 16 exact text cells and eight geometry witnesses are
unchanged. No checklist row ticks, existing oracle changes, or new tolerance
accompanies this instrument. The pinned capture remains the single Chromium
module, shared by probes, bakes and this runner. Stored upstream PNGs and fresh
resvg outputs are independent observations, never alternate ways to satisfy a
declared Chromium assertion. FLIP and legacy-tool retirement remain separate.

For sensitivity, temporarily replacing CSS green with blue at the n0 solid
paint boundary fails the existing `just gate` on the new upstream rectangle
with 160,000 differing pixels at maximum delta 255. The assertion pilot also
fails that rectangle while its blue control and expected-refusal case remain
passing. The renderer source is restored exactly; no painter change is part
of the tool. The earlier scratch survey remains **measured, not celled**
outside these two promoted cases and does not establish a corpus-wide verdict.

Independent review caught an image-decoder contract mismatch before landing:
the pinned decoder erases hidden RGB for non-palette `tRNS` and accepts a
replacement PNG header after the initial dimension check. The harness now
validates bounded chunk framing, CRCs and one leading header before allocation,
then strict bounded decompression and the exact scanline extent before pixels;
encodings that cannot preserve this profile's exact RGBA8 meaning explicitly
refuse. Palette transparency remains lossless and tested. Decoded buffers are
case-local, repeats retain hashes, and controls reload one verified pair at a
time. Nonregular file inputs refuse without blocking on a FIFO writer. The
required contract-test invocation fails when no tests are discovered.
These are instrument protections, not changes to engine semantics or oracles.

The independent reproducer renewed the scratch control, all existing fixture
gates and STATUS, then ran the pilot against both admissions with fresh
Chromium and separately pinned resvg/stored observations. Both rendering
assertions and the named-refusal assertion pass, with tool/input identities
unchanged. Full relevant Rust tests, formatting, strict Clippy, 40 tool-contract
tests, typechecks and link/OSS checks pass. No Workflow runner was exposed:
TICK/LAW and REPRO ran as manual independent roles. Two TICK/LAW audits produced
the fixes above; a final audit attempt was blocked by a tool-policy error.
The fixes have local regression checks and independent REPRO evidence,
but no final independent TICK/LAW approval is claimed.

PR review additionally guards partial Chromium output without losing the
report: missing repeat zero keeps its empty slot instead of promoting repeat
one, comparisons check for decoded pixels, and capture failures retain signal
or exit-code causes even with empty stderr. Regressions exercise those branches;
the renewed actual-CLI pilot remains exact after the changes.
5 changes: 5 additions & 0 deletions docs/wg/consolidation/web-checklist.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ in [the statement of record](../../../crates/n0_cli/README.md), rung history
in [the D-N register](./svg-engine-of-record.md), and no score is computed
from this list (FLIP is unratified).

The [SVG assertion harness](../../../packages/grida-reftest/svg-assertions/README.md)
distinguishes described rendering assertions, named refusals, and unresolved
observations. None of those individual results substitutes for this checklist's
full-grammar tick rule.


## HTML

Expand Down
21 changes: 21 additions & 0 deletions fixtures/web-first/LICENSE.resvg
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2018 Reizner Evgeniy

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
12 changes: 11 additions & 1 deletion fixtures/web-first/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Every root primitive here is a closed enumeration in `primitives.json` with a
committed Chromium oracle beside it. Text follows the ratified corpus-growth
law in its own closed [text estate](./text/README.md): sixteen exact text cells and
eight exact-number real-font artifact-geometry witnesses. The current evidence
estate is 1,537 primitive cells plus 16 sampled frames, those twenty-four text
estate is 1,539 primitive cells plus 16 sampled frames, those twenty-four text
witnesses, and 351 named refusal rows. Pixel cells require byte equality, except only
the primitive rows carrying an explicit measured tolerance block. The
real-font witness grades geometry before rasterization and makes no Chromium
Expand All @@ -35,6 +35,7 @@ separates source membership from visible paint and records the bounded profile.

| File | Role |
| --- | --- |
| `svg-upstream-resvg-rect-simple-case.svg` · `svg-upstream-resvg-rect-blue-control.svg` | Assertion-harness pilot: the unchanged upstream sharp rectangle and a separate subject-fill color control, captured at a 500×500 initial viewport. Both are exact in strict and best-effort CLI renders; changing only green to blue changes 160,000 Chromium pixels at maximum channel delta 255. Imported from resvg-test-suite revision `d8e064337faf01bc5a9579187a56dbdbe3eacc72`, `tests/shapes/rect/simple-case.svg`, under [its MIT notice](./LICENSE.resvg). These are scene assertions, not a new feature grant. |
| `svg-group-blend-sibling-{multiply,screen}-{transparent,fill-zero,fill-alpha,empty-server,invalid-fallback}.svg` | Ten selected-paint sibling cells: transparent color, zero fill opacity, zero color alpha, a valid stopless linear server and a missing server with transparent fallback retain source contribution without visible fill. |
| `svg-group-blend-sibling-{multiply,screen}-{stroke-only,stroke-zero,stroke-thin,stroke-px,stroke-percent,stroke-dash,solid-stroke}.svg` | Fourteen decorated-rectangle cells: omitted transparent/zero-alpha solid strokes, width spellings and inert dash/join state retain local source enclosure, including beside a solid-filled sibling. |
| `svg-group-blend-sibling-{multiply,screen}-{boundary,edge,reversed,multiple,two-ramps}.svg` | Ten enclosure and composition controls: fractional boundaries, offscreen edges, sibling order, multiple paintless contributors and two live ramps. |
Expand Down Expand Up @@ -482,3 +483,12 @@ stale one. Probe *matrices* stay scratch and are never committed; a probe is a
question asked once, and what it proves lands as cells and README rows, not as
a shadow corpus. The pre-landing verification ritual is the saved
`verify-rung` workflow (`.agents/workflows/verify-rung.js`).

`assertions-test` checks the separate assertion-tool contracts;
`assertions-gate <new-absolute-output-directory>` runs its small actual-CLI pilot
and fresh Chromium captures. The [SVG assertion tool](../../packages/grida-reftest/svg-assertions/README.md)
records each described claim, reference decision, both admissions and their
diagnostics, independent exact image comparisons, and a discrete verdict. A
verified refusal is not rendering support; unresolved or missing required
cases cannot silently pass. This supplements the existing corpus gates and
uses the same capture module. It does not create a score or a second checklist.
4 changes: 3 additions & 1 deletion fixtures/web-first/STATUS.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Not a conformance claim: no score is computed or implied (FLIP is
unratified), and the corpus enumerates constructs, not the SVG
surface.

## Chromium-baked cells (1537)
## Chromium-baked cells (1539)

Cells are checked against their committed Chromium oracles using
exact bytes unless a manifest entry declares a measured, bounded
Expand Down Expand Up @@ -1490,6 +1490,8 @@ to its fixture source. No new image is committed for this view.
<a href="./svg-transform-no-separator.svg" title="svg-transform-no-separator (standalone-svg)"><img src="./chromium/svg-transform-no-separator.png" width="56" alt="svg-transform-no-separator"></a>
<a href="./svg-transform-runtogether.svg" title="svg-transform-runtogether (standalone-svg)"><img src="./chromium/svg-transform-runtogether.png" width="56" alt="svg-transform-runtogether"></a>
<a href="./svg-translucent-fill-rgba.svg" title="svg-translucent-fill-rgba (standalone-svg)"><img src="./chromium/svg-translucent-fill-rgba.png" width="56" alt="svg-translucent-fill-rgba"></a>
<a href="./svg-upstream-resvg-rect-blue-control.svg" title="svg-upstream-resvg-rect-blue-control (standalone-svg)"><img src="./chromium/svg-upstream-resvg-rect-blue-control.png" width="56" alt="svg-upstream-resvg-rect-blue-control"></a>
<a href="./svg-upstream-resvg-rect-simple-case.svg" title="svg-upstream-resvg-rect-simple-case (standalone-svg)"><img src="./chromium/svg-upstream-resvg-rect-simple-case.png" width="56" alt="svg-upstream-resvg-rect-simple-case"></a>
<a href="./svg-use.svg" title="svg-use (standalone-svg)"><img src="./chromium/svg-use.png" width="56" alt="svg-use"></a>
<a href="./svg-use-ancestor-circle.svg" title="svg-use-ancestor-circle (standalone-svg)"><img src="./chromium/svg-use-ancestor-circle.png" width="56" alt="svg-use-ancestor-circle"></a>
<a href="./svg-use-chain.svg" title="svg-use-chain (standalone-svg)"><img src="./chromium/svg-use-chain.png" width="56" alt="svg-use-chain"></a>
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions fixtures/web-first/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,13 @@ status:
# entry is `standalone-svg` or `html-inline-svg`.
add id source entry="standalone-svg":
python3 {{justfile_directory()}}/add_cell.py {{id}} --source {{source}} --entry {{entry}}

# Assertion-tool contracts and deliberately failing synthetic controls; no scores.
assertions-test:
{{node_env}} pnpm -C {{justfile_directory()}}/../../packages/grida-reftest exec tsc --noEmit -p svg-assertions/tsconfig.json
{{node_env}} pnpm -C {{justfile_directory()}}/../../packages/grida-reftest exec vitest run svg-assertions --passWithNoTests=false

# Actual CLI pilot + fresh pinned Chromium, with a new absolute output directory.
# This supplements, and does not replace, the existing full fixture gate.
assertions-gate out:
{{node_env}} {{cargo_env}} pnpm -C {{justfile_directory()}}/../../packages/grida-reftest exec tsx {{justfile_directory()}}/../../packages/grida-reftest/svg-assertions/cli.ts --manifest {{justfile_directory()}}/../../packages/grida-reftest/svg-assertions/pilot.json --out "{{out}}"
20 changes: 19 additions & 1 deletion fixtures/web-first/oracle-bake.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"bake_script_sha256": "2bdb5f933d072a1e87c9a675c3342fcf506c0955c0f5c26e2988f4e8fa37c4f2",
"capture_module_sha256": "069296201718c43d29efe356fbea893781b73250dca51de3b6d47468d74027b0",
"suite": "primitives.json",
"suite_sha256": "afc67c1f35b4289366d72acd150b813b91e79dc4de9b4aba39dd7fad8286b652",
"suite_sha256": "939969dd01cd520c8f9b41377d11980d5454f6161158a5326bb84c1874ef65dd",
"capture": {
"device_scale_factor": 1,
"omit_background": true,
Expand Down Expand Up @@ -13186,6 +13186,24 @@
"width": 64,
"height": 64
},
{
"id": "svg-upstream-resvg-rect-blue-control",
"source": "svg-upstream-resvg-rect-blue-control.svg",
"source_sha256": "18722a00cf6f1b0bfb417dbca3c4a59237b628150f5bebaff467cde54c386b14",
"oracle": "chromium/svg-upstream-resvg-rect-blue-control.png",
"oracle_sha256": "6bdaceeba4a8327ece87bea27a7819434563957e8cbcdf0d4c93648aee04460a",
"width": 500,
"height": 500
},
{
"id": "svg-upstream-resvg-rect-simple-case",
"source": "svg-upstream-resvg-rect-simple-case.svg",
"source_sha256": "0b487592d89c6e43573eb91eb92cb18b85bd5139c31143f534ba3e43a9dfd0cc",
"oracle": "chromium/svg-upstream-resvg-rect-simple-case.png",
"oracle_sha256": "4fd110181e80bc6c24e6d9cc2d273ad477d3c82c5fb57bef0fb871f4d08a063c",
"width": 500,
"height": 500
},
{
"id": "svg-use",
"source": "svg-use.svg",
Expand Down
16 changes: 16 additions & 0 deletions fixtures/web-first/primitives.json
Original file line number Diff line number Diff line change
Expand Up @@ -11856,6 +11856,22 @@
"width": 64,
"height": 64
},
{
"id": "svg-upstream-resvg-rect-blue-control",
"source": "svg-upstream-resvg-rect-blue-control.svg",
"entry": "standalone-svg",
"oracle": "chromium/svg-upstream-resvg-rect-blue-control.png",
"width": 500,
"height": 500
},
{
"id": "svg-upstream-resvg-rect-simple-case",
"source": "svg-upstream-resvg-rect-simple-case.svg",
"entry": "standalone-svg",
"oracle": "chromium/svg-upstream-resvg-rect-simple-case.png",
"width": 500,
"height": 500
},
{
"id": "svg-use",
"source": "svg-use.svg",
Expand Down
11 changes: 11 additions & 0 deletions fixtures/web-first/svg-upstream-resvg-rect-blue-control.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions fixtures/web-first/svg-upstream-resvg-rect-simple-case.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading