Skip to content

Commit ae50a86

Browse files
Merge pull request #61 from gridaco/chore/consolidation-web-first
feat(consolidation): the n0 path becomes the SVG engine of record
2 parents 58902b2 + bab3ad9 commit ae50a86

403 files changed

Lines changed: 31768 additions & 6165 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.agents/skills/dev-render-htmlcss-feature/SKILL.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ over `/research`, `/fixtures`, and `/render-reftest` — those auto-trigger
1515
on their own for narrower work.
1616

1717
**Sibling skill.** For features in the SVG path
18-
(`crates/grida/src/htmlcss/svg/`, `resvg-test-suite` corpus,
18+
(`crates/htmlcss/src/svg/`, `resvg-test-suite` corpus,
1919
multi-oracle scoring against expected.png + baked Chrome PNG), use
2020
[`dev-render-htmlcss-svg-feature`](../dev-render-htmlcss-svg-feature/SKILL.md)
2121
instead. Same five-phase shape, different tooling.
@@ -50,7 +50,7 @@ coincidentally-correctly but by the wrong path?
5050

5151
**Actions.**
5252

53-
- Scan `crates/grida/src/htmlcss/` for the property name in
53+
- Scan `crates/htmlcss/src/` for the property name in
5454
stylo enum mapping, paint emit, layout feed. A property can be
5555
parsed-but-dropped, emitted-but-wrong, or unhandled — each has a
5656
different fix shape.
@@ -147,7 +147,7 @@ the suite config is wrong and the score will be zero.
147147
### 4. Implement — "what code change realizes the behavior?"
148148

149149
**Question.** What is the minimum set of edits in
150-
`crates/grida/src/htmlcss/` to make the fixture match?
150+
`crates/htmlcss/src/` to make the fixture match?
151151

152152
**Actions.**
153153

@@ -232,7 +232,7 @@ pick up, and no context is lost. The durable artifacts:
232232
| Audit | Current-state note, priority bucket | PR description / task prompt |
233233
| Ground | Research note (spec + engine cross-ref) | PR description or `docs/wg/feat-2d/` |
234234
| Fixture | `.html` fixture(s), suite entries, viewport measurement | `fixtures/test-html/L0/`, `fixtures/test-html/suites/` |
235-
| Implement | Code change, data tests, behavior summary | `crates/grida/src/htmlcss/` |
235+
| Implement | Code change, data tests, behavior summary | `crates/htmlcss/src/` |
236236
| Verify | Before/after scores, diff PNG review, divergence surface | PR description |
237237

238238
If a phase's artifact is missing, the phase isn't done — even if

.agents/skills/dev-render-htmlcss-svg-feature/SKILL.md

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ description: >
1111

1212
# grida-htmlcss::svg — feature loop
1313

14+
> **Status (2026-07-24): the target module is a frozen donor.** Per
15+
> [D-N, the SVG engine of record](../../../docs/wg/consolidation/svg-engine-of-record.md),
16+
> no new behavior lands in `htmlcss::svg`; SVG capability evolves as rungs
17+
> on the engine of record (`websem → rframe → n0`), Chromium-baked under
18+
> `fixtures/web-first/`. Use this loop only for owner-directed wire-back or
19+
> donor study — not for new feature work.
20+
1421
**What this is.** A heavy, manually-invoked loop for driving a single
15-
SVG feature forward in `crates/grida/src/htmlcss/svg/`. Do not
22+
SVG feature forward in `crates/htmlcss/src/svg/`. Do not
1623
auto-trigger; load only when the user explicitly runs it.
1724

1825
**Sister skill.** [`dev-render-htmlcss-feature`](../dev-render-htmlcss-feature/SKILL.md)
@@ -22,7 +29,7 @@ shape, but different corpus and different scoring policy.
2229

2330
| Aspect | HTML/CSS sister skill | This (SVG) skill |
2431
| --------------- | -------------------------------------------- | ------------------------------------------------------------------- |
25-
| Renderer module | `crates/grida/src/htmlcss/` (excl. `svg/`) | `crates/grida/src/htmlcss/svg/` |
32+
| Renderer module | `crates/htmlcss/src/` (excl. `svg/`) | `crates/htmlcss/src/svg/` |
2633
| Corpus | `fixtures/test-html/L0/` (we author) | `fixtures/local/resvg-test-suite/` (vendored, 1679 fixtures) |
2734
| Oracle | Playwright Chromium (refbrowser, on-the-fly) | `expected.png` (suite author) **+** baked Chrome PNG |
2835
| Scoring | Single oracle, gate=`L0.exact` floor 1.0 | Multi-oracle: consensus / disputed / UB; gate = consensus pass-rate |
@@ -73,7 +80,7 @@ oracle buckets?
7380

7481
**Actions.**
7582

76-
- Scan `crates/grida/src/htmlcss/svg/` for the property/element name
83+
- Scan `crates/htmlcss/src/svg/` for the property/element name
7784
in dom/parse, style/cascade, layout, paint. SVG features can be
7885
parsed-but-dropped, computed-but-misrouted, or just unhandled —
7986
each has a different fix shape.
@@ -97,7 +104,7 @@ oracle buckets?
97104
--renderer htmlcss --threshold 0.1 \
98105
--filter 'filters_feSpecularLighting'
99106
```
100-
- Cross-reference [`crates/grida/src/htmlcss/svg/README.md`](../../../crates/grida/src/htmlcss/svg/README.md)
107+
- Cross-reference [`crates/htmlcss/src/svg/README.md`](../../../crates/htmlcss/src/svg/README.md)
101108
for the Blink module map and any prior decision.
102109

103110
**Deliverable.** A short audit note (PR draft / task prompt):
@@ -189,7 +196,7 @@ known starting score against the chosen oracle.
189196
### 4. Implement — "what code change realizes the behavior?"
190197

191198
**Question.** What is the minimum diff in
192-
`crates/grida/src/htmlcss/svg/` to make the targets pass?
199+
`crates/htmlcss/src/svg/` to make the targets pass?
193200

194201
**Actions.**
195202

@@ -285,7 +292,7 @@ moved against, and whether anything regressed.
285292
| Audit | Current-state note, oracle-partitioned fixture list | PR description / task prompt |
286293
| Ground | Research note (spec + Blink/resvg cross-ref) | PR description or `docs/wg/feat-2d/` |
287294
| Fixture | Target fixture list with oracle status; baked chrome.png | `fixtures/local/resvg-test-suite/chrome-baseline/` (gitignored) |
288-
| Implement | Code change, data tests, spec-language behavior summary | `crates/grida/src/htmlcss/svg/` |
295+
| Implement | Code change, data tests, spec-language behavior summary | `crates/htmlcss/src/svg/` |
289296
| Verify | Before/after summary, per-fixture scores, diff PNG review | PR description |
290297

291298
---
@@ -466,7 +473,7 @@ Produce, in order:
466473
different — explain which oracle the implementation targets).
467474
3. Fixture list: 1-3 target fixtures with rel paths, oracle status,
468475
baked chrome.png present (yes/no).
469-
4. Implementation: minimal diff in crates/grida/src/htmlcss/svg/.
476+
4. Implementation: minimal diff in crates/htmlcss/src/svg/.
470477
Data tests where assertable.
471478
5. Verify report:
472479
- before/after consensus pass-rate (from `reftest summary`)
@@ -500,5 +507,5 @@ Use /research for phase 2.
500507
| `reftest view <result-dir>` | Serve the dashboard. |
501508

502509
See [`crates/grida_dev/AGENTS.md`](../../../crates/grida_dev/AGENTS.md) and
503-
[`crates/grida/src/htmlcss/svg/README.md`](../../../crates/grida/src/htmlcss/svg/README.md)
510+
[`crates/htmlcss/src/svg/README.md`](../../../crates/htmlcss/src/svg/README.md)
504511
for the underlying contracts.

.agents/skills/render-reftest/SKILL.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -339,12 +339,12 @@ Everything is driven by **suite JSON files** at
339339
`fixtures/test-html/suites/`. A suite enumerates fixtures, their
340340
per-fixture render config, and the gate policy.
341341

342-
| Suite | What it contains | Gate |
343-
| ------------------ | --------------------------------------------------------------------------------------------- | -------------------------- |
344-
| `L0.exact.json` | Fixtures currently at 100.00% byte-exact parity with Chromium. Any drop is a real regression. | `floor: 1.0`, strict diff. |
345-
| `L0.coverage.json` | All aspirational L0 fixtures — the full backlog. Scores land wherever they land. | Informational only. |
342+
| Suite | What it contains | Gate |
343+
| ------------------ | ---------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
344+
| `L0.exact.json` | Fixtures currently at 1.0 configured Chromium similarity. Any scored-pixel drop is a real regression. | `floor: 1.0`, threshold 0, AA exclusion active |
345+
| `L0.coverage.json` | All aspirational L0 fixtures — the full backlog. Scores land wherever they land. | Informational only |
346346

347-
**Promoting a fixture to `exact`** — once a fixture reaches 100.00%
347+
**Promoting a fixture to `exact`** — once a fixture reaches 1.0
348348
against the current suite config, move its entry from `coverage`
349349
`exact`. Do **not** lower the exact suite's floor to fit new entries;
350350
the bar exists so regressions are loud.
@@ -357,7 +357,7 @@ per-fixture `.reftest.json` sidecars.
357357
```json
358358
{
359359
"name": "L0.exact",
360-
"description": "Byte-exact fixtures; any drop = regression.",
360+
"description": "Configured-exact fixtures; any scored-pixel drop = regression.",
361361
"gate": { "threshold": 0, "aa": true, "floor": 1.0 },
362362
"defaults": {
363363
"wait_for": ["fonts", "networkidle"],
@@ -374,7 +374,7 @@ per-fixture `.reftest.json` sidecars.
374374
- `defaults` — applied to every fixture. Each fixture entry can override any field.
375375
- `fixtures[].path` and every `extra_css[]` path resolve **relative to the suite file**.
376376
- `gate.threshold` / `gate.aa` are inputs to the pixelmatch diff; `gate.floor` is the aggregate pass bar on similarity.
377-
- **`aa: true` (default)** → pixelmatch `includeAA: false`. Pixelmatch's AA detector fires and excludes anti-aliased edge pixels from the diff count, separating rasterizer edge noise (Skia vs. Blink) from real divergence. Set `aa: false` for strict byte-exact accounting (e.g. probing an AA-class regression).
377+
- **`aa: true` (default)** → pixelmatch `includeAA: false`. Pixelmatch's AA detector fires and excludes anti-aliased edge pixels from the diff count, separating rasterizer edge noise (Skia vs. Blink) from real divergence. Set `aa: false` for strict AA-inclusive accounting inside the scoring mask (e.g. probing an AA-class regression).
378378

379379
#### The three-step pipeline
380380

@@ -419,9 +419,9 @@ Default refbrowser diff: **`--threshold 0`** (pixelmatch's tightest
419419
color-delta) with **AA-ignore mode on by default** (`aa: true`
420420
`includeAA: false`; pixelmatch's Vysniauskas AA detector fires and
421421
excludes edge AA pixels from the diff count). Pass `--no-aa` to flip
422-
to strict byte-exact accounting. Pass each fixture's similarity
423-
against the suite's `gate.floor` — for `L0.exact`, that's `1.0`
424-
(100.00% similarity with AA detection active).
422+
to strict AA-inclusive accounting inside the scoring mask. Pass each
423+
fixture's similarity against the suite's `gate.floor` — for
424+
`L0.exact`, that's `1.0` (100.00% similarity with AA detection active).
425425

426426
```sh
427427
pnpm -C packages/grida-reftest exec reftest \
@@ -545,10 +545,12 @@ diff image, not the numeric score.
545545
5. Run the refbrowser producer + diff against the same suite. Review
546546
the diff PNG — if the diff is dominated by a known divergence zone
547547
(see below), record it in the PR description, don't suppress it.
548-
6. If the fixture reaches 100.00% byte-exact, move its entry from
549-
`L0.coverage.json` to `L0.exact.json`.
548+
6. If the fixture reaches 1.0 under the exact suite's configured
549+
threshold, AA-exclusion, and content-mask policy, move its entry
550+
from `L0.coverage.json` to `L0.exact.json`.
550551

551-
**Known divergence surfaces** — areas where grida is not yet Blink-exact.
552+
**Known divergence surfaces** — areas where grida does not yet meet the
553+
configured Blink bar.
552554
These are **backlog items, not tolerance excuses**. Do not tune
553555
thresholds to suppress them. Document the specific divergence in the
554556
PR description; let the score carry the truth.

.github/workflows/consolidation-gates.yml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ jobs:
7373
fetch-depth: 0
7474
ref: ${{ needs.scope.outputs.head }}
7575

76+
- name: Check the gate still refuses what it must
77+
run: python3 bin/test-check-cargo-lock-additions-only
78+
7679
- name: Gate workspace crate cuts
7780
run: >-
7881
python3 bin/check-cargo-lock-additions-only
@@ -134,16 +137,19 @@ jobs:
134137
cache-workspace-crates: true
135138
cache-on-failure: true
136139

137-
- name: Run the five legacy seam locks
140+
- name: Run the legacy and extracted Web seam locks
138141
env:
139142
FORCE_SKIA_BINARIES_DOWNLOAD: "1"
140143
run: |
141144
cargo test --locked -p grida \
142145
--test cg_architecture \
143146
--test svg_import_architecture \
144147
--test html_import_architecture \
145-
--test htmlcss_svg_architecture \
146148
--test painter_architecture
149+
cargo test --locked -p htmlcss \
150+
--test architecture \
151+
--test svg_architecture
152+
cargo test --locked -p n0_cli --test architecture
147153
148154
legacy_pixel_sweep:
149155
name: legacy pixel sweep

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,3 +126,4 @@ docs/_build/
126126
*.plan.md
127127
*.todo.md
128128
.claude/launch.json
129+
.DS_Store

AGENTS.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,14 @@ brew install ninja # macOS
2525

2626
```sh
2727
# check (each crate must pass independently)
28-
cargo check -p grida -p grida-canvas-wasm -p grida_dev -p n0 -p n0-model
28+
cargo check -p htmlcss -p grida -p grida-canvas-wasm -p grida_dev -p n0 -p n0-model \
29+
-p websem -p rframe -p animation-sampling -p n0_cli
2930

3031
# tests
3132
cargo test -p grida # legacy engine tests
33+
cargo test -p htmlcss # extracted Web renderer tests
3234
cargo test -p n0-model -p n0 # v2 engine tests (model is skia-free, fast)
35+
cargo test -p n0_cli # thin product command host + HTML/SVG render probes
3336
cargo test # all
3437

3538
# lint / format (enforced)
@@ -48,14 +51,19 @@ python3 bin/activate-flatc -- --rust -o crates/grida/src/io/generated format/gri
4851

4952
| directory | notes |
5053
| --------------------------- | ------------------------------------------------------------------------------------------ |
51-
| `crates/grida` | the engine core (rendering, node model, io, text, svg/html import) |
54+
| `crates/grida` | legacy engine compatibility consumer (node model, io, text, import/export, editor-era runtime) |
5255
| `crates/cg` | the backend-neutral canvas-graphics vocabulary |
56+
| `crates/htmlcss` | extracted mature static HTML/CSS/SVG renderer; transitional direct-Skia Web implementation |
5357
| `crates/grida_editor` | editor core — document working copy, invertible mutations, history, commands |
5458
| `crates/grida-canvas-wasm` | WASM bindings + the `@grida/canvas-wasm` npm package (see its `PUBLISHING.md`) |
5559
| `crates/math2` · `csscascade` · `fonts` | foundations |
5660
| `crates/grida_dev` | dev CLI, benchmarks, reftest tooling |
5761
| `crates/grida_wpt` | web-platform-tests harness |
5862
| `crates/n0` · `n0-model` · `n0_dev` | the v2 engine family (the `anchor` model): skia-free model crate, resolve→drawlist→paint engine, winit/egui dev shell — promoted from the `model-v2-anchor` branch (gridaco/nothing#9) |
63+
| `crates/websem` | the Web semantic compiler: an SVG or HTML source → one namespace-aware document → one Stylo cascade → `rframe::Frame`. Owns no parser and no painter; decides what the engine will and will not render |
64+
| `crates/rframe` | the resolved render contract (`Frame`): the visual facts a producer states after resolving its source. Contract-only and backend-free — no document, no cascade, no paint call |
65+
| `crates/animation-sampling` | the time axis: Base or one exact signed-nanosecond Sample, with no ambient clock |
66+
| `crates/n0_cli` | thin `n0` file-render command on the SVG engine of record (`websem → rframe → n0`): Base and exact-time SVG/HTML renders at WxH-as-initial-viewport — best-effort by default (constructs outside the admitted slice declared on stderr), `--strict` refuses loudly. Its README is the statement of record for that slice |
5967
| `archive/model-v2/` | the frozen v2 workbench archive (phase papers, experiment verdicts, demo pages); paths inside the frozen papers refer to the pre-promotion layout — see its README's map |
6068
| `format/` | the FlatBuffers schema (`grida.fbs`) — **source of truth**; see `format/AGENTS.md` |
6169
| `docs/wg/` | the engine's normative working-group specs (canvas, format, research, feat-*) — same-repo |

0 commit comments

Comments
 (0)