Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
6bdcc14
feat(model-v2): anchor — the v2 node model workspace (textbook snapshot)
softmarshmallow Jul 7, 2026
0a5446d
docs(model-v2): link tracking issue gridaco/grida#957 in the branch note
softmarshmallow Jul 7, 2026
ee35ec4
docs(model-v2): sync a/README to DEC-0 second lock (visual-only, 114 …
softmarshmallow Jul 7, 2026
36515de
docs(model-v2): ENGINE.md — the phase-4 layer programs, day-1 major c…
softmarshmallow Jul 7, 2026
5161825
feat(model-v2/lab): engine seams + visual-only exploration corpus (si…
softmarshmallow Jul 8, 2026
c820e3f
feat(model-v2/engine): phase-4 engine skeleton — pipeline + sockets, …
softmarshmallow Jul 8, 2026
cdfb717
docs(model-v2/engine): MEASURE doctrine + the perf harness it describes
softmarshmallow Jul 8, 2026
c9fa672
feat(model-v2): numeric Color + dense-index resolve caches, DATA-MODE…
softmarshmallow Jul 9, 2026
7617b58
docs(format): specify Grida XML Draft 0
softmarshmallow Jul 10, 2026
a4a110d
feat(model-v2): ingest and render Grida XML
softmarshmallow Jul 10, 2026
200e0f4
test(model-v2): add canonical Grida XML showcase
softmarshmallow Jul 10, 2026
ce481d9
docs(model-v2): frame animation model and prior art
softmarshmallow Jul 11, 2026
5b50eb1
feat(model-v2): materialize Grida XML geometry and rich text
softmarshmallow Jul 11, 2026
0e2aa63
test(model-v2): add Grida XML showcase corpus
softmarshmallow Jul 11, 2026
4150b8f
docs(model-v2): normalize markdown formatting
softmarshmallow Jul 11, 2026
b1c8725
docs(wg): specify universal shaped text layout
softmarshmallow Jul 11, 2026
2f1c0b3
feat(model-v2/lab): add resolved text layout oracle
softmarshmallow Jul 11, 2026
9dce258
feat(model-v2/engine): shape and replay resolved text
softmarshmallow Jul 11, 2026
af031b2
docs(model-v2): record shaped text pipeline and limits
softmarshmallow Jul 11, 2026
9e62230
docs(wg): specify boxed Grida XML paths
softmarshmallow Jul 11, 2026
a06173e
feat(model-v2/lab): materialize boxed XML paths
softmarshmallow Jul 11, 2026
621f207
feat(model-v2/engine): render Grida XML paths
softmarshmallow Jul 11, 2026
2938425
docs(wg): specify versioned Grida XML components
softmarshmallow Jul 12, 2026
1c49c26
feat(model-v2): materialize versioned Grida XML sources
softmarshmallow Jul 12, 2026
1aaed3a
feat(model-v2): bind Grida XML roots to the viewport
softmarshmallow Jul 12, 2026
1577e2e
feat(model-v2): render linked Grida XML programs
softmarshmallow Jul 12, 2026
e6a6176
feat(model-v2): establish durable effective-value frames
softmarshmallow Jul 13, 2026
b15ec13
test(model-v2): add effective-value visual proof
softmarshmallow Jul 13, 2026
90391cd
docs(model-v2): specify the pre-animation value contract
softmarshmallow Jul 13, 2026
1d4b9b0
docs(svg): define explicit-time animation profiles
softmarshmallow Jul 13, 2026
3dd6e6a
feat(model-v2): prove explicit-time SVG animation
softmarshmallow Jul 13, 2026
24e0ae4
docs(svg): specify cumulative animation profiles
softmarshmallow Jul 14, 2026
57434fd
feat(model-v2): extend typed SVG animation profiles
softmarshmallow Jul 14, 2026
80c60ad
Merge main into model-v2-anchor (pre-landing sync)
softmarshmallow Jul 19, 2026
a8338a0
chore(n0): promote the anchor stack — pure move
softmarshmallow Jul 19, 2026
2184d11
chore(n0): wire the promoted crates into the workspace
softmarshmallow Jul 19, 2026
f3d1eb9
chore(n0-model): shed the one-shot workbench bins at promotion
softmarshmallow Jul 19, 2026
e5bfc18
style: rustfmt the promoted crates after the rename
softmarshmallow Jul 19, 2026
24cfd0e
chore(n0): pass the workspace clippy/fmt gates
softmarshmallow Jul 19, 2026
ed01867
docs: tombstone the model-v2 archive + land the n0 family in repo docs
softmarshmallow Jul 19, 2026
7c101b9
chore(n0_dev): re-bless the gate shot goldens (environment drift, not…
softmarshmallow Jul 19, 2026
a8ea218
fix(n0): platform-stable pixel readback + oxfmt conformance
softmarshmallow Jul 19, 2026
abe0305
chore(n0): canonical names for the promoted surfaces — no plan codes
softmarshmallow Jul 19, 2026
425c258
chore(model-v2): canonical names for the archive — end-state, not pla…
softmarshmallow Jul 19, 2026
56b709d
rename: Grida XML -> n0 XML (.n0.xml) across code, docs, and fixtures
softmarshmallow Jul 19, 2026
3de12c9
chore(fixtures): relocate the v2 corpus to repo-root fixtures/ per co…
softmarshmallow Jul 19, 2026
afc5342
docs(wg): persist the consolidation program charter
softmarshmallow Jul 19, 2026
979d43d
chore(archive): file the model-v2 record under repo-root archive/
softmarshmallow Jul 19, 2026
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
2 changes: 2 additions & 0 deletions .oxfmtrc.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
"fixtures/",
"target/",
"third_party/",
// The frozen v2 workbench archive — kept verbatim (see archive/model-v2/README.md).
"archive/",
// Generated Emscripten glue and binaries.
"crates/grida-canvas-wasm/lib/bin/",
"crates/grida-canvas-wasm/dist/",
Expand Down
8 changes: 5 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,11 @@ brew install ninja # macOS

```sh
# check (each crate must pass independently)
cargo check -p grida -p grida-canvas-wasm -p grida_dev
cargo check -p grida -p grida-canvas-wasm -p grida_dev -p n0 -p n0-model

# tests
cargo test -p grida # engine tests
cargo test -p grida # legacy engine tests
cargo test -p n0-model -p n0 # v2 engine tests (model is skia-free, fast)
cargo test # all

# lint / format (enforced)
Expand All @@ -53,7 +54,8 @@ python3 bin/activate-flatc -- --rust -o crates/grida/src/io/generated format/gri
| `crates/math2` · `csscascade` · `fonts` | foundations |
| `crates/grida_dev` | dev CLI, benchmarks, reftest tooling |
| `crates/grida_wpt` | web-platform-tests harness |
| `crates/n0` | the reserved public `n0` crate (future topology — a separate, deliberate task) |
| `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) |
| `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 |
| `format/` | the FlatBuffers schema (`grida.fbs`) — **source of truth**; see `format/AGENTS.md` |
| `docs/wg/` | the engine's normative working-group specs (canvas, format, research, feat-*) — same-repo |
| `fixtures/` | test corpora (see the `fixtures` skill); **`fixtures/local/` is untracked** — large suites (resvg, W3C SVG 1.1, oxygen-icons, perf, refig) are downloaded per-machine |
Expand Down
100 changes: 100 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ members = [
"crates/csscascade",
"crates/math2",
"crates/n0",
"crates/n0-model",
"crates/n0_dev",
]

# Inherited only by crates that opt in via `.workspace = true` (currently n0).
Expand Down
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,11 @@ The graphics engine lives here. It migrated from the
(2025→) carried over; Grida remains the service/editor monorepo and consumes
the engine only through published artifacts.

The `n0` crate name stays reserved: the migrated crates keep their working
names, and the nothing-local topology (what becomes `n0`) is a separate,
deliberate task.
Two engines live side by side while the topology converges: the migrated
production engine (`crates/grida`, shipping as `@grida/canvas-wasm`) and
the v2 `n0` engine family (`crates/n0`), promoted from the
`model-v2-anchor` research branch. The v2 model program is tracked in
[gridaco/nothing#9](https://github.com/gridaco/nothing/issues/9).

## Workspace

Expand All @@ -26,7 +28,9 @@ deliberate task.
- [`crates/grida-canvas-wasm`](./crates/grida-canvas-wasm) — WASM bindings (`@grida/canvas-wasm`)
- [`crates/math2`](./crates/math2) · [`crates/csscascade`](./crates/csscascade) · [`crates/fonts`](./crates/fonts) — foundations
- [`crates/grida_dev`](./crates/grida_dev) · [`crates/grida_wpt`](./crates/grida_wpt) — dev tools, benchmarks, reftests
- [`crates/n0`](./crates/n0) — the reserved public `n0` crate
- [`crates/n0`](./crates/n0) — the `n0` engine (v2): resolve → drawlist → paint
- [`crates/n0-model`](./crates/n0-model) · [`crates/n0_dev`](./crates/n0_dev) — the skia-free `anchor` model · the v2 dev shell
- [`archive/model-v2/`](./model-v2) — the frozen v2 workbench archive (decision record)
- [`format/`](./format) — the FlatBuffers schema (source of truth)
- [`docs/wg/`](./docs/wg) — the engine's normative working-group specs

Expand Down
12 changes: 12 additions & 0 deletions archive/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# archive/

Frozen records of concluded programs — decision papers, experiment
verdicts, demo pages, and format drafts, kept as the historical record
after their living outcomes were promoted elsewhere. Content here is
verbatim history: it is not maintained, its internal relative paths may
describe pre-promotion layouts (each program's README carries the map),
and nothing builds from it.

| program | record |
| ------- | ------ |
| [`model-v2/`](./model-v2/) — the v2 node-model redesign ("anchor"), promoted to the `crates/n0` family at [gridaco/nothing#5](https://github.com/gridaco/nothing/pull/5) | phase papers, experiment ledger E1–E10 with verdicts, DEC-0 decision record, demo pages, `anchor.fbs` drafts |
1 change: 1 addition & 0 deletions archive/model-v2/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
target/
155 changes: 155 additions & 0 deletions archive/model-v2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
# model-v2 — node geometry / layout / transform model redesign

Workbench for the fundamental redesign of the Grida node model: how a node's
geometry, position, size, rotation/transform, and layout participation are
represented — in the **Rust engine** (`crates/grida`) and the **format spec**
(`format/grida.fbs`). The proving stack has since grown source-format, engine,
and host harnesses needed to test that model end to end, including n0 XML
ingestion and explicit-time SVG animation. Those remain contained proofs;
production TS/editor, WASM, importer, renderer, and runtime migration are still
out of scope here.

> **Archive note (2026-07-19).** This directory is the **frozen workbench
> archive** of the v2 model program, filed under the repo's
> [`archive/`](../README.md) home for concluded-program records (it lived
> at the repo root as `model-v2/` during the program). Its proving stack
> was promoted into the workspace at the landing of
> [gridaco/nothing#5](https://github.com/gridaco/nothing/pull/5):
> `a/lab` → [`crates/n0-model`](../crates/n0-model), `engine/` →
> [`crates/n0`](../crates/n0), `a/spike-canvas` →
> [`crates/n0_dev`](../crates/n0_dev). What remains here — the phase
> papers, the experiment dirs with their frozen outputs and verdicts, the
> demo pages, and the format drafts — is the decision record, kept
> verbatim apart from two repo-wide canonicalizations applied at
> landing: names (below) and the format term rename ("Grida XML" →
> "n0 XML", `.grida.xml` → `.n0.xml`; the Draft-0 root element
> `<grida version="0">` is unchanged). File and directory names were
> canonicalized at landing (the
> workbench dir `a/` is now [`anchor/`](./anchor/); the experiment dirs
> dropped their `eN-` ledger prefixes; the candidate models dropped
> their letter slots — the ledger ids remain as the register keys in
> prose and in [`anchor/README.md`](./anchor/README.md)'s table).
> **Relative paths inside the frozen papers refer to the pre-promotion
> layout** (`a/lab`, `engine/`, `a/spike-canvas`); follow the map
> above. Tracking issue:
> [gridaco/nothing#9](https://github.com/gridaco/nothing/issues/9)
> (formerly gridaco/grida#957, transferred at the engine split).
> Implementation status and module boundaries live with the engine:
> [`crates/n0/ANIMATION.md`](../crates/n0/ANIMATION.md).

## Run

```sh
# the model crate (formerly a/lab) — full conformance suite
cargo test -p n0-model

# the dev shell (formerly a/spike-canvas) — native skia window on the model
cargo run --release -p n0_dev

# the demo pages (proof, model walkthrough, edge cases, DEC-0 fork, free editing)
python3 -m http.server 4173 --directory archive/model-v2/anchor/.preview
```

## Why this exists

The current system answers the same question three different ways:

- leaf nodes: baked `AffineTransform` + `size`
- containers: `position` enum + `rotation: f32` scalar + `layout_dimensions`
- format spec (`LayerTrait`): `layout` + `post_layout_transform` (unimplemented, self-flagged provisional)

reconciled at runtime by a lossy, branchy resolver. This was never reconciled
because the underlying questions were never decided. This directory decides
them — problems first, then candidates, then spec.

## Phase discipline

| phase | artifact | status |
| ----------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1. Problems & harnesses | `problems.md`, `harnesses.md`, `study.md` | stable draft |
| 2. Candidate models | `paradigm.md`, `axes.md`, `models/*`, `finale.md`, `triage.md` | **DECIDED — `anchor`** (+5 triage amendments) |
| 3. Spec | normative doc + `grida.fbs` draft | **experiments RUN, model PROVEN** — E1–E10 complete with verdicts; **DEC-0 decided: VISUAL-ONLY rotation (the CSS framing), CSS-pure sizing** ([`anchor/dec0-visual-only.md`](./anchor/dec0-visual-only.md)); flips built (E-A14, cross-zero resize); conformance lab; native interactive spike (now [`crates/n0_dev`](../crates/n0_dev)); open calls parked in [`anchor/DECISIONS.md`](./anchor/DECISIONS.md). Remaining: fold deltas into a normative rewrite of `models/anchor.md` + WG graduation |
| 4. Runtime | `crates/grida` implementation | **proving engine BUILT and PROMOTED** — [`crates/n0`](../crates/n0) (formerly `engine/`, `anchor-engine`): the `resolve → drawlist → paint` pipeline + query/journal/replay/damage sockets, spike re-hosted onto it, gate green (shots byte-identical, replay deterministic, budgets baselined). The bounded explicit-time SVG animation checkpoint adds pure sampling, Base/Sample frame integration, exact-time rendering, a caller-owned playback clock, and a controlled native host; see [`crates/n0/ANIMATION.md`](../crates/n0/ANIMATION.md). Production migration remains separate |

Ground rules:

- **Problems before solutions.** When a new unclear part arises, it becomes a
catalog entry — not an inline patch to a proposal.
- **Every claim is evidence-linked** to current code, the format spec, or a
studied peer system.
- **No candidate survives without a harness run.** `harnesses.md` is the test
suite for designs.
- An earlier in-chat probe sketched one candidate (scalars-canonical + per-axis
anchors + layout-visible rotation + a transform-quarantine node). It is
deliberately **not recorded here as a decision** — it re-enters in phase 2 as
one candidate among others, subject to the harnesses.

## Files

- [`problems.md`](./problems.md) — the problem catalog (P1–P11): each unclear
part stated precisely, with its tension, option space, and evidence.
- [`harnesses.md`](./harnesses.md) — the constraints (H1–H10) any candidate
must pass, each with a concrete pass/fail probe, plus the tension map
between harnesses.
- [`study.md`](./study.md) — comparative study of peer systems (CSS, SVG,
Flutter, SwiftUI, Figma, tldraw): facts we reason with, not designs we copy.
- [`paradigm.md`](./paradigm.md) — phase-2 **candidate** paradigm
("one box, one way"): nouns, laws, how each problem lands, trades declared,
falsification criteria. Not ratified.
- [`finale.md`](./finale.md) — the phase-2 finale, **decided: `anchor`**;
preserved with the pre-decision concession bill and deciding question.
- [`survey.md`](./survey.md) — the 32-question instrument itself, saved
clean (no answers, no verdict): administration rules, all questions with
options, and scoring guidance. Reusable for future re-runs or other
respondents.
- [`triage.md`](./triage.md) — the 2026-07-07 run of the survey: answers,
scoring key, verdict, the five amendments, and the one open (tilted)
fork.
- [`editor.md`](./editor.md) — the editor-experience operation catalog:
every gesture as **gesture → writes → effect → ripple** with stable
`OP-*` ids, the six operation laws (incl. the three sanctioned
state→intent bake moments), and per-op FORK marks.
- [`conformance.md`](./conformance.md) — the model-agnostic test corpus:
metamorphic laws, per-area invariants + edge registries, the executable
merge matrix, and the compatibility checklist (CSS/Figma/SVG/current
engine) with Y / N-deviation / spectrum verdicts. FORK rows are the
finale's probes.
- [`axes.md`](./axes.md) — the decision-space factoring: **Axis 1 = semantic
model** (`anchor` vs `bake` — decide first), **Axis 2 = representation &
mutation protocol** (struct vs sheet, key granularity — tunable after,
bounded by the atom rule). Re-scopes `sheet`; source of harnesses H11/H12.
- [`anchor/`](./anchor/) — **the winner's workbench**: the experiment ledger E1–E10
(each with verdicts and lab tests), the decision register
([`anchor/DECISIONS.md`](./anchor/DECISIONS.md)), the DEC-0 normative rules, the
ship-readiness census ([`anchor/LIMITS.md`](./anchor/LIMITS.md)), the peer-compat
matrix, the phase-4 engine layer programs with day-1 contracts
([`anchor/ENGINE.md`](./anchor/ENGINE.md)), the Rust conformance lab (now
[`crates/n0-model`](../crates/n0-model)), and the native interactive
spike (now [`crates/n0_dev`](../crates/n0_dev)).
- [`models/`](./models/) — concrete candidate models, one file each,
harness-scored, best-faith. Files carry their working identifiers
(renamed from letter slots at landing);
the names are the working identifiers:
- [`models/anchor.md`](./models/anchor.md) — **`anchor`** (the anchored box model):
intent-canonical scalars, per-axis bindings, lens quarantine. Proposed
best fit.
- [`models/sheet.md`](./models/sheet.md) — **`sheet`** (the property sheet model):
CSS-faithful flat registry, rulebook conflicts, post-layout transforms.
- [`models/bake.md`](./models/bake.md) — **`bake`** (the materialized matrix
model): Figma-faithful matrix + state canonicalism, edit-time layout.
- [`models/wire.md`](./models/wire.md) — **`wire`** (the wired geometry model):
relational archetype — referent-general bindings, dataflow DAG, the WG
Level-4 destination. Priced and deferred; `anchor` grows into it
additively.

## Relationship to existing docs

- [`docs/wg/feat-layout/index.md`](../docs/wg/feat-layout/index.md) — the
anchor+flex+grid positioning vision (draft, gridaco/grida#437). It covers positioning
intent only and is **silent on rotation/transform and their layout
coupling** — that gap is a large part of this catalog. When phase 3 produces
a spec, it graduates into `docs/wg/` under WG doctrine (code-agnostic) and
this directory's evidence links stay behind as the working record.
- [`format/grida.fbs`](../format/grida.fbs) — the current archive draft; its
header rules (unset-vs-default, tables-over-structs, additive evolution) are
binding harnesses on whatever phase 3 encodes (see H9).
Loading
Loading