Nothing

Paint Vocabulary Conformance Gap Report

Phase 1 evidence: the ratified paint-model laws projected independently over cg and n0-model, with every non-equivalence named for D-C.

Paint Vocabulary Conformance Gap Report

Status: Evidence complete, 2026-07-20. Decision D-C is not taken. The two AMD amendments are drafted and re-pinned, not ratified. The program owner remains the decision-maker for both gates.

This report is for the owner deciding D-C: whether each n0-model paint leaf adopts a shared type or remains a separate type behind a permanent law-equivalence mapping. It records what the ratified paint-model RFD requires, what the two current vocabularies can express, and what neither vocabulary proves. Neither implementation is the oracle.

Evidence boundary

The executable evidence is the test-local PaintVocabulary trait in paint_rfd_conformance.rs. Each binding is checked independently against RFD observations. Native enum matches and struct destructures are exhaustive, so a variant or field-set change is compile-visible. Default and non-default sentinels exercise value preservation. The suite is Skia-free and deterministic; it is a value-law gate, not a pixel reftest.

Four evidence classes keep a green test honest:

ClassMeaning
ObservedThe native value can express the law and the harness executes it.
MappedRepresentations differ, but a lossless projection executes the same law. D-C still owns whether the mapping survives.
GapA required value or grouping is absent or has the wrong shape. It has a stable id below.
External gateA leaf-value test cannot prove the claim. Importer behavior and pixels stay with their independent gates.

No fixture file is appropriate for this suite: the subjects are finite value vocabularies and algebraic laws. Renderer behavior remains subject to the program's Chromium/consensus oracle discipline; this report never substitutes legacy output for an oracle.

Clause census

RFD clausecgn0-modelEvidence or disposition
RGBA8, straight alphaMappedObservedSentinel AARRGGBB words project to the same four channels; solid opacity is alpha.
Packed AARRGGBB canonical identityGapObservedcg stores four channel fields; the projection is bijective but storage is not canonical. P1-CG-COLOR-CANONICAL.
Byte → unit float → rounded byte identityObservedObservedAll 256 alpha values round-trip. The RFD now states recoverability rather than the false claim that every quotient is exactly representable in binary.
Transfer characteristic declaredExternal gateExternal gateThe RFD's linear-vs-display contradiction remains a color-management obligation; neither RGBA8 type carries a declaration.
Six paint variantsObservedObservedSolid, linear, radial, sweep, diamond, image; exhaustive native matches.
Per-paint active, opacity, blendObservedObservedAll six variants retain the state. All sixteen native blend variants are projected one-way, then every normalized blend is independently constructed and read back.
Visible iff active and opacity > 0ObservedObservedPatrol found both implementations used “nonzero”; both helpers now implement the literal law, including negative and NaN probes. Pixel equivalence after removal remains an external render gate.
Ordered stack, entry zero bottommostObservedObservedNative construction order is retained and push appends the topmost entry. Empty remains representable. Actual draw sequence is a renderer gate.
Blend localityStructuralStructuralBlend stays on each paint entry. Actual compositing is a renderer/pixel gate.
Node opacity is isolated, not distributedExternal gateExternal gateNode opacity is deliberately outside these leaves. Isolation and valid opacity-folding optimizations belong to the stroke-fill-opacity render gate.
Unified, repeatable stroke applicationGapObservedOrdered native projections preserve every geometry enum and width payload; n0-model's native default supplies the miter default, one application retains a dash payload, and a node stores two distinct applications. cg exposes the primitives, including its dash wrapper, but no grouped application. P1-CG-STROKE-APPLICATION.
Stroke applications paint after childrenExternal gateExternal gateList shape cannot prove node render order; the display-list/render gates own it.
Legacy flattened stroke maps to one applicationExternal gateExpressibleThe target value is sufficient; the converter must prove the one-element, lossless mapping when it lands.
Run-fill absent / empty / nonemptyObservedObservedBoth retain all three states. Owner ratification remains AMD-RUN-FILL-TRISTATE.
Decoration color valueObservedGapcg carries the optional color; n0-model's paint-only text surface does not. Effective-text-color fallback remains a consumer gate. P1-N0-DECORATION-COLOR.
Text strokes reuse stroke applicationsGapGapcg has a partial text-specific bundle; n0-model has no run-level stroke application. P1-CG-TEXT-STROKE, P1-N0-TEXT-STROKE.
Gradient field matrixObservedObservedExact native destructures, defaults, and non-default sentinels cover endpoints, tile-mode presence, all six transform coefficients, stop values, opacity, active, and blend. All four tile modes are present where allowed.
Gradient intrinsic sampling and transform compositionExternal gateExternal gateField presence cannot prove the normalized-space intrinsics or scale(width, height) × user-transform; analytic/pixel gates own them.
Stop is offset + colorObservedObservedNo parallel stop-opacity field exists. cg's helpers are gated for empty, one-, two-, and three-color ramps, including exact retained order and offsets.
Image field matrixMappedObservedOrdered native projections preserve both resource identities and payloads, all three fit forms (including transform/tile payloads), all four object fits, and all three repeat modes. Exact neutral and non-default image witnesses cover quarter turns, alignment, opacity, blend, and all seven filter scalars.
Image orientation, fitting, tiling, and filter executionExternal gateExternal gateModulo-four orientation, odd-turn intrinsic swaps, fitting/tiling order, filter ranges, and pixel effects require renderer gates.
Diamond beyond-unit behaviorOwner amendmentOwner amendmentBoth renderers clamp today; the contract remains proposed as AMD-DIAMOND-CLAMP.
Stop-opacity folding, focal reporting, pattern rejectionExternal gateExternal gateThese are importer obligations, not properties of the leaf types. No importer conformance is claimed here.

“Structural” is deliberately weaker than pixel conformance. It says the value does not erase the state required to perform the operation; only the proper render gate can establish the operation's result.

Law-equivalent representation differences

These differences do not currently change a harness observation, but they are the concrete cost surface for D-C.

Leafcgn0-modelConsequence
ColorFour u8 channel fields; both RGBA and ARGB constructorsPacked AARRGGBB wordA test mapping is lossless. Adopting cg unchanged would contradict the RFD's canonical identity.
Paint stackPrivate Vec<Paint> with serdePrivate Vec<Paint> without serdeOrder and mutation laws match; serialization policy is a boundary concern.
Gradient transformmath2 row-major 2×3 affine over f32n0-model-local named affine coefficients over f32All six coefficients map exactly; type identity and dependency direction remain distinct.
Run fillsOption<Vec<Paint>>Option<Paints>The three ownership states are identical; wrapper identity differs.
Image alignment fieldPublic field spelled alignementPublic field spelled alignmentSpelling is API debt, not a semantic difference.
Resource referenceUppercase HASH / RID variantsRust-style Hash / Rid variantsThe two-way value set is identical.

Exact gaps

P1-CG-COLOR-CANONICAL

cg's channel struct is losslessly related to AARRGGBB, but the RFD chose a packed word as canonical identity and interchange form. Equality is presently law-equivalent, not representation-identical. D-C must either preserve a mapping deliberately or select a shared packed leaf; the report does not take that decision.

P1-CG-STROKE-APPLICATION

cg owns StrokeWidth, alignment, cap, join, miter-limit, dash, and paint-stack values, but it has no value grouping one geometry with one paint stack and no repeatable application list. The legacy node estate flattens one geometry and one stack. The RFD requires the grouped, repeatable value already present in n0-model.

P1-CG-TEXT-STROKE

cg's styled run carries stroke paints plus optional width and alignment. It does not carry cap, join, miter limit, or dash as one stroke application, and therefore creates a partial text-specific stroke shape which the RFD forbids. This partial coverage is retained as evidence; it must not disappear when the text surface is consolidated.

P1-N0-DECORATION-COLOR

n0-model's current TextStyleRec is deliberately a three-field shaping subset. It has no decoration color even though the paint RFD assigns that paint-only value to this vocabulary. The broader decoration geometry remains owned by the text-layout contract; this gap is only the color value and its fallback to the run's effective text color.

P1-N0-TEXT-STROKE

n0-model can stroke a whole text node through Node::strokes, but a styled run cannot own a stroke application. The paint RFD's text partition therefore is not complete. This gap and the cg partial shape mean that choosing either text record wholesale cannot close the contract.

Declared external obligations

The following findings are real but are not D-C type-choice evidence:

  • Color transfer: the archive's “linear” annotation and both renderers' display-encoded treatment remain contradictory. A later color-management contract must name the transfer characteristic.
  • Radial focal point: neither type carries one. The RFD proposes the extension but explicitly requires declared importer deviation until it is ratified. The earlier sentence calling it ratified was a document defect and is corrected with this report.
  • Importer losses: per-stop opacity must fold into stop alpha; a focal point and unsupported spread/pattern constructs must be reported, never silently dropped or replaced with transparency. Importer conformance belongs to the import-IR and scoreboard gates.
  • Quarter-turn execution and paint-box transforms: the fields exist on both sides, but modulo-four orientation and gradient sampling are renderer behavior. Existing implementation agreement is evidence, not an oracle.
  • Stack and node compositing: pixel-invariant removal of invisible paints, blend locality, first-entry-first drawing, stroke-after-children order, and node-opacity isolation require render/display-list gates. The value suite proves only that the state and canonical order survive to those gates.
  • Text consumers: decoration-color fallback and the rule that ownership is resolved before invisible-paint filtering require targeted consumer tests. The value suite proves only the present/empty/absent states and exact record shapes.

D-C decision surface

D-C remains an owner gate. The evidence supports leaf-by-leaf decisions; it does not support one wholesale type swap.

Leaf groupIf one shared type is selectedIf separate types remain
ColorThe shared leaf must preserve packed AARRGGBB canonical identity.The checked AARRGGBB projection becomes a permanent law gate.
Blend, tile, alignment, paint stackCurrent value sets and laws are equal; dependency and serialization policy still need an explicit home.Exhaustive mappings remain small but permanent.
Gradient and image paintsTransform type, math dependency, serde policy, and the alignement API debt must be settled without changing field laws.The full field-matrix mapping remains a permanent gate.
Stroke applicationA shared surface must express n0-model's grouped, repeatable application without flattening it.cg remains nonconformant until its consumer boundary maps the legacy singleton into the canonical application.
Text paint partitionNeither record is complete; decoration color and full run stroke applications must survive whichever ownership choice is made.Both named gaps remain capability work; mapping alone cannot create absent values.

No production adapter lands with this report. The test-local bindings are evidence for D-C. If D-C chooses shared types, a binding is deleted only after the same RFD assertions run directly on the selected type. If D-C chooses separate types, the corresponding binding becomes the permanent law-equivalence gate. This is the deletion gate for the only mapping introduced by this step.

Patrol and captured-essence ledger

Patrolled estateCaptured essenceDisposition
cg color, paint variants, gradient/image leaves, ordered stackStraight RGBA8, six variants, per-entry state, bottom-to-top order, field matricesExecuted in the trait harness; no drop.
cg gradient color helpersEven stop distribution and retained input orderSingleton NaN was a contract violation; corrected to a finite offset of zero; empty through three-color cases are gated.
Legacy flattened stroke vocabularyOne geometry plus one ordered stack; rich geometry primitivesPreserved as P1-CG-STROKE-APPLICATION, including the future lossless singleton mapping.
cg styled-run paint fieldsTri-state fills, decoration color, partial stroke bundleTri-state and color executed; partial stroke shape preserved as P1-CG-TEXT-STROKE.
n0-model paint leaves and stackPacked color, same six variants and orderExecuted independently; no cg-as-oracle comparison.
n0-model stroke applicationGrouped geometry + paints; repeatable node listExecuted as the RFD-conformant value shape.
n0-model styled-run paint fieldsTri-state fills; sparse paint-only coverageTri-state executed; absent decoration and run strokes named separately.
Both visibility helpersActive plus nonzero-opacity testEtiology traced to a duplicated predicate; corrected to the literal opacity > 0 law and gated for zero, negative, NaN, and positive values.
Both diamond render paths and Draft-0 n0 XMLL1 ramp with clamp at the unit boundaryRe-homed as evidence for proposed AMD-DIAMOND-CLAMP; no ratification claimed.
Importer deviations named by the RFDStop opacity, focal point, spread methods, patternsQuarantined as external gates; no silent claim that a type test covers them.

This step deletes and replaces no engine estate. The ledger nevertheless records every caveat encountered so D-C cannot turn representation cleanup into a silent capability drop.

Gate

The report is current only while all of these hold:

cargo test --locked -p n0-model --test paint_rfd_conformance
cargo test --locked -p cg -p n0-model
cargo test --locked -p grida -p n0
cargo check --locked -p grida -p grida-canvas-wasm -p grida_dev -p n0 -p n0-model
cargo clippy --locked -p cg -p n0-model --no-deps -- -D warnings
cargo fmt --all -- --check

The first command requires every stable gap and pinned amendment id to occur in this report. It does not produce or inspect a scoreboard score.

On this page