wai-vector: WOS1 and WVG1 with the refusal order, the interval check and the cost (D7-2; stacked on #215) #216

Merged
dcharlot merged 2 commits from wai/d7-2-vector-formats into main 2026-10-11 06:09:26 -04:00
Owner

Adds wai/wai-vector, the reference crate of wai.graphics.vector, with the corpus wai/vector-conformance/ and the workflow wai-vector.yml. This is phase D7-2 of D7: the formats, the order in which a sink refuses them, and the arithmetic a sink loads with (the clock, track evaluation, the load-time interval check and the per-frame cost). The raster (RS1–RS9) and the frames follow in D7-3, #217, which is stacked on this branch.

Stacked on #215 (wai/d7-1-graphics-text, head f66c09ed). The branch starts at #215's head, so until #215 merges this diff also shows the extension text. Merge #215 first. Nothing is registered.

What lands

  • wai/wai-vector. It is no_std with alloc and has no dependencies. SHA-256 is wai-ops's, included by #[path] (src/sha256.rs), so the tree keeps one. The crate's files:

    • refuse.rs: the codes of §2.1 and §2.7, and the request errors;
    • bounds.rs: every cap of §2.6 and every bound this PR relies on, with compile-time assertions;
    • arith.rs: R_rat, R_half_up, div255, both quantisers, and the straight-alpha channel;
    • wos1.rs: §2.1's eleven load checks in order, and the writer;
    • wvg1.rs:
      • steps 1–3 (split), with nothing allocated until the exact length holds;
      • the record pass (step 4) and the cross-record checks 5(a)–(h);
      • the sets by digest, reading at most length + 1 bytes and hashing before parsing (step 6);
      • glyphs (step 7);
      • the canonical writer;
    • clock.rs: the frame range by division;
    • track.rs: §3.2;
    • place.rs: placement (§3.3), the interval check (§3.4(a), step 8) and the cost (§3.4(b), step 9);
    • form.rs: the JSON authoring form (§2.12). It has one member per field, zero fields included, and packs back to the same bytes;
    • scene.rs: a builder that writes canonical payloads (authoring);
    • vectors.rs and vectors/: the generator and the recomputation.
  • The CLI (--features std): check, cost, pack, unpack, vectors gen and vectors verify.

  • wasm/: a wasm32-unknown-unknown module with a C ABI and no bindings generator. Its verify.mjs recomputes every expected file, and every authoring form, under Node.

  • fuzz/seeds/: seeds for the deterministic fuzz: a payload that uses every table, and a set with every point tag. The fuzz itself is tests/fuzz_smoke.rs. There is no cargo-fuzz target, because it would bring a third-party dependency.

  • wai/vector-conformance/: 268 vectors, written by wai-vector vectors gen and verified by vectors verify.

    • The README has its **Provenance.** line. Every payload, set and string is written here from formulas, with no media and no font.
    • sha256.json starts with the div255 table entry that §22.6 asks for, so every_decoded_output_states_a_sha256 checks it. No exclusion row is needed.
    group vectors outcomes
    arith 6 div255 over every input, both quantisers over [−2^18, 2^18], the straight-alpha channel over every c ≤ A, R_rat and R_half_up at ties and at the driver's widths, and track evaluation at the extremes
    canonical 31 9 accepted structures; 22 refusals, one per canonical rule (first use, duplicates and unreferenced entries in each pool, group numbering and contiguity, ruby, clusters, and a decorative path alternative)
    refusals 207 (173 payloads, 34 outline sets) each code and check of §2.7 and §2.1, and pairs of faults that pin the order
    geometry 13 the interval check at 2^22 − 1 and 2^22 on each axis; at a second size; for an inactive item, a clip, enclosing groups and a glyph with no points; and the true-range case
    cost 11 exactly 2^32 − 1 (accepted) and 2^32; stated costs off by one; a reused path; touching windows; a group; review A's shapes
  • .github/workflows/wai-vector.yml:

    • native (linux, linux-arm64, macos; debug and release tests, then vectors verify);
    • wasip2 (the tests and vectors verify under wasmtime 38.0.3);
    • node (verify.mjs under Node 22);
    • fuzz (2,000 mutations per seed, the peak-allocation test, the comparison count, and check-workflow-concurrency.sh).
    • It has a concurrency block. Its filters are §11.5's base set: wai/wai-vector/**, wai/wai-ops/src/sha256.rs, wai/vector-conformance/**, wai/tools/wai_vector_*.py, wai/extensions/graphics-vector.md and the workflow. Adding wai/vector-conformance/ also fires wai-conformance.yml through its wai/*-conformance/** filter.

Tests, and the falsification of each

Each test was committed first. Then the code it guards was broken, the named test was shown to fail, the code was restored through git, and the test was shown to pass. Each row is one run, on the dev Mac, debug unless marked. The whole table was run again on this PR's final head (5b0f2abd), with the same results.

test what it pins the break red after restore
arith::div255_over_every_input (and R_rat, R_half_up, the straight-alpha channel, against exact rationals) §3.0, §3.9, §2.9 pre-bias 128 → 127 div255(128) is the half-up rounding of x/255 green
refusal_order::wos1_load_check_order (each code; five fault pairs) §2.1 check 5 run before check 4 check 4 before check 5 green
refusal_order::record_pass_reports_field_range_before_any_cross_table_check (kind = 4, ref = 0 and interp = 2 + j, j ≥ n_tables, each beside a 5(a) fault) §2.7 step 4 the record pass moved after the sum rules payload_malformed where field_range was expected green
refusal_order::the_four_new_sum_rules (one vector each for path contours, path points, strings, glyphs and clusters) §2.7 step 5(a) the n_clusters sum dropped refusals/s5a-clusters-sum was accepted green
refusal_order::exact_length_and_trailing_bytes §2.0 one trailing byte accepted unwrap_err() on an Ok green
canonical::canonical_round_trip_on_every_vector (parse then write, and form then pack) §2.5 the paint pool written in reverse every-table: form round trip green
canonical::duplicates_by_sorting_comparison_count (review A's F10 shape at n = 65,535: 1,152,100 comparisons, against the bound 2·n·⌈log2 n⌉ = 2,097,120 and 2,147,385,345 pairs) §2.5 rule 3 a pairwise loop more than 2097120 comparisons green
clock_track::frame_range_by_division (g up to u64::MAX at P = 2^40) §2.7 g·P formed in i64 debug: attempt to multiply with overflow; release: frame 16777216 is out of range (the product wraps to 0) green, both
clock_track::integer_speed_roll_lands_on_the_grid (M2's 750-frame roll at four rates) and values_stay_between_their_keys (M5) §3.2 linear keys routed through Q16 25/1, k = 1, 750 frames, frame 1 green
geometry_cost::interval_check_boundary and interval_not_true_range §3.4(a) the true range, evaluated at every tick, in place of the interval unwrap_err() on an Ok: the document was accepted green
geometry_cost::cost_counts_a_reused_path_per_use, cost_ceiling_boundary §3.4(b) (1) the bw·bh term dropped; (2) a reused path counted once assertion left == right at lines 70 and 71 green, both
held_sets::a_counting_resolver_sees_at_most_length_plus_one_bytes §2.7 step 6 read to the end of the stream the sink read 1048950 bytes of a set of length 374 green
fuzz_smoke::fuzz_smoke (no panic; every accepted input writes back to its bytes) §2.0, §2.7 the exact-length check removed index out of bounds (debug and release) green, both
peak_alloc::peak_allocation_is_linear_in_the_input (≤ 6·input + 64 KiB over the corpus; worst 5.33×; nothing reserved for a header that claims the caps) §2.0 2^22 keys and 2^16 items reserved before the length check a header claiming the caps made the parser reserve 53477376 bytes green

Also:

  • refusal_order::steps_in_order covers 14 pairs across steps 1–7.
  • refusal_order::every_vector_has_the_code_its_note_names, corpus::* and geometry_cost::review_a_attack_payloads_are_refused (below).

Review A's attack payloads

shape here code
A: fills reusing a full-canvas 4-point path, at 4096 × 4096 260 items too_large (step 9)
B: fills reusing a path of 16,381 points (5,460 cubics spanning the canvas) 26 items too_large (step 9); one item alone is accepted
C: full-canvas glyph records one run of 256 too_large (step 9)
D: held sets at the largest WOS1 64 sets, and 3 sets of 2^25 bytes too_large (step 2, held_len); 2 sets of 2^25 bytes stay within 2^26 and are outline_not_held
E: tracks equal but for the last key, two equal 512 tracks payload_malformed (5(g)), found by sorting

At full scale, built in memory (geometry_cost::review_a_full_scale_costs), the cost reproduces RC2's figures exactly:

  • A (65,536 fills): 1,101,944,324,096.
  • C (2^20 glyph records in 256 runs, with each run's hull term): 17,635,152,494,592, the figure #215's body derives.
  • B: RC2 counted 5,460 cubics as 16,380 points (10,992,717,135,872, reproduced from the formula). The path also stores its start point, so it costs 2^24 + 65,536 · c(16,381).

Cross-checks

  • Review A's core.py and the design's prototypes. A scratch script reads the committed bytes with struct, sharing no code with the crate. Using core.r_rat, core.rhu, merged_checks.hull_mul and review_checks.cost_fill, it recomputes:

    • every arith table and case (div255, both quantisers, the straight-alpha channel, R_rat, R_half_up, and track evaluation through merged_checks.eval_track);
    • every contour of the accepted outline sets, through core.contour_curves;
    • the §3.4(a) verdict and the §3.4(b) cost of the 35 payloads that reach steps 8 and 9.

    Agreement on all of it, with one difference, from the text (below). With a cost, an interpolated value and a geometry verdict planted wrong, the script reports all three.

  • The tree-wide tests:

    • corpus_provenance, int_kernels_vectors::every_decoded_output_states_a_sha256 and signer_ids_are_labels: green.
    • With the README's **Provenance.** label changed, corpus_provenance fails and names vector-conformance/README.md. With sha256.json removed, the sidecar test fails on it. So both read this corpus.

Where the text, the design and the prototypes differ (the text is followed)

  1. A one-point contour whose point is a control.
    • §2.1 says P_0 MUST be on-curve, in every contour.
    • core.py and review_checks.py return early for a one-point contour and accept a control there.
    • The crate follows the text. refusals/wos1-grammar-one-point-control is outline_malformed, the one contour on which the cross-check and the crate disagree.
  2. Clusters' within-record rules. glyph_count = 0 only with byte_len ≥ 1, and the converse, read only their own record.
    • §2.7 places them at 5(g), with rule 5. The crate follows that.
    • #215 moved ruby_len ≥ 1 into the record pass for that reason. By the same reasoning these would be field_range at step 4. The text could choose either way.
  3. A payload shorter than its 80-byte header (a set shorter than 32 bytes). No step names it. The crate reports it at step 1 (payload_malformed; outline_malformed for a set), because the magic cannot be read. A sentence in §2.7 step 1 and §2.1 check 1 would settle it.
  4. Naming and layout, against the design:
    • The generator is wai-vector vectors gen (§22.6's src/bin/wai-vector.rs), not §9.1's wai_vector_vectors gen.
    • Refusal vectors live in vectors/refusals/ with expected/refusals/ (§22.6), not in refusals/ with refusals.json (§9.1).
    • The writers and the scene builder are in the default library, not behind §11.2's author feature, because the verifier's round trip (§2.5) needs the writer. author can arrive with D7-5's WSF1.
  5. RC2's attack B counts 16,380 points. The path that 5,460 cubics need stores 16,381.

Legs and gate

  • Locally, on the dev Mac, every vector is identical on three engines:

    • native macOS arm64, debug and release: every test, and vectors verify (268 vectors, 775 generated files);
    • wasm32-wasip2 under wasmtime 49.0.2: every test, and vectors verify;
    • wasm32-unknown-unknown under Node 26.11.1: verify.mjs (268 vectors, 228 authoring forms).

    CI pins wasmtime 38.0.3 and Node 22.

  • A second instruction-set architecture (SPEC §7 asks it of frozen digests): a static x86_64-unknown-linux-musl build of the tool ran vectors verify on an x86_64 Linux host. All 268 vectors and 775 generated files are identical.

  • Fuzz at depth: 520,000 inputs from 260 seeds; no panic; 1,214 accepted inputs, each written back to its bytes.

  • Clippy: clean on every target with --features std, except one lint in wai-ops's sha256.rs, which this crate includes by path and does not edit.

  • The wai-rs gate (gate.sh d7-2): build, lib tests, carriage, the corpus loop (21 of 21), fast kernels, byte-exact, wai-web wasm32 and the neural gates are all GREEN.

  • Public text:

    • check-public-names.sh with the private list: clean on each of the 544 changed files, one per invocation, and at CI scope (1,818 files);
    • check-comparative-prose.sh and check-no-vanity-metrics.sh: clean;
    • check-wai-section-refs.py: clean;
    • check-workflow-concurrency.sh: clean.

Merge notes

  • It touches no file #201 or #199 edits. It adds new files only, under wai/wai-vector/, wai/vector-conformance/ and .github/workflows/.
  • Legs for the merge: wai-vector.yml (native ×3, wasip2, node, fuzz); wai-conformance.yml (corpus_provenance, every_decoded_output_states_a_sha256); no-vanity-metrics.yml.

🤖 Generated with Claude Code

Adds `wai/wai-vector`, the reference crate of `wai.graphics.vector`, with the corpus `wai/vector-conformance/` and the workflow `wai-vector.yml`. This is phase D7-2 of D7: the formats, the order in which a sink refuses them, and the arithmetic a sink loads with (the clock, track evaluation, the load-time interval check and the per-frame cost). The raster (RS1–RS9) and the frames follow in D7-3, #217, which is stacked on this branch. **Stacked on #215** (`wai/d7-1-graphics-text`, head `f66c09ed`). The branch starts at #215's head, so until #215 merges this diff also shows the extension text. Merge #215 first. Nothing is registered. ## What lands - **`wai/wai-vector`.** It is `no_std` with `alloc` and has no dependencies. SHA-256 is `wai-ops`'s, included by `#[path]` (`src/sha256.rs`), so the tree keeps one. The crate's files: - `refuse.rs`: the codes of §2.1 and §2.7, and the request errors; - `bounds.rs`: every cap of §2.6 and every bound this PR relies on, with compile-time assertions; - `arith.rs`: `R_rat`, `R_half_up`, `div255`, both quantisers, and the straight-alpha channel; - `wos1.rs`: §2.1's eleven load checks in order, and the writer; - `wvg1.rs`: - steps 1–3 (`split`), with nothing allocated until the exact length holds; - the record pass (step 4) and the cross-record checks 5(a)–(h); - the sets by digest, reading at most `length + 1` bytes and hashing before parsing (step 6); - glyphs (step 7); - the canonical writer; - `clock.rs`: the frame range by division; - `track.rs`: §3.2; - `place.rs`: placement (§3.3), the interval check (§3.4(a), step 8) and the cost (§3.4(b), step 9); - `form.rs`: the JSON authoring form (§2.12). It has one member per field, zero fields included, and packs back to the same bytes; - `scene.rs`: a builder that writes canonical payloads (authoring); - `vectors.rs` and `vectors/`: the generator and the recomputation. - **The CLI** (`--features std`): `check`, `cost`, `pack`, `unpack`, `vectors gen` and `vectors verify`. - **`wasm/`:** a `wasm32-unknown-unknown` module with a C ABI and no bindings generator. Its `verify.mjs` recomputes every expected file, and every authoring form, under Node. - **`fuzz/seeds/`:** seeds for the deterministic fuzz: a payload that uses every table, and a set with every point tag. The fuzz itself is `tests/fuzz_smoke.rs`. There is no `cargo-fuzz` target, because it would bring a third-party dependency. - **`wai/vector-conformance/`:** 268 vectors, written by `wai-vector vectors gen` and verified by `vectors verify`. - The README has its `**Provenance.**` line. Every payload, set and string is written here from formulas, with no media and no font. - `sha256.json` starts with the `div255` table entry that §22.6 asks for, so `every_decoded_output_states_a_sha256` checks it. No exclusion row is needed. | group | vectors | outcomes | |---|---|---| | `arith` | 6 | `div255` over every input, both quantisers over `[−2^18, 2^18]`, the straight-alpha channel over every `c ≤ A`, `R_rat` and `R_half_up` at ties and at the driver's widths, and track evaluation at the extremes | | `canonical` | 31 | 9 accepted structures; 22 refusals, one per canonical rule (first use, duplicates and unreferenced entries in each pool, group numbering and contiguity, ruby, clusters, and a decorative path alternative) | | `refusals` | 207 (173 payloads, 34 outline sets) | each code and check of §2.7 and §2.1, and pairs of faults that pin the order | | `geometry` | 13 | the interval check at `2^22 − 1` and `2^22` on each axis; at a second size; for an inactive item, a clip, enclosing groups and a glyph with no points; and the true-range case | | `cost` | 11 | exactly `2^32 − 1` (accepted) and `2^32`; stated costs off by one; a reused path; touching windows; a group; review A's shapes | - **`.github/workflows/wai-vector.yml`:** - `native` (linux, linux-arm64, macos; debug and release tests, then `vectors verify`); - `wasip2` (the tests and `vectors verify` under wasmtime 38.0.3); - `node` (`verify.mjs` under Node 22); - `fuzz` (2,000 mutations per seed, the peak-allocation test, the comparison count, and `check-workflow-concurrency.sh`). - It has a `concurrency` block. Its filters are §11.5's base set: `wai/wai-vector/**`, `wai/wai-ops/src/sha256.rs`, `wai/vector-conformance/**`, `wai/tools/wai_vector_*.py`, `wai/extensions/graphics-vector.md` and the workflow. Adding `wai/vector-conformance/` also fires `wai-conformance.yml` through its `wai/*-conformance/**` filter. ## Tests, and the falsification of each Each test was committed first. Then the code it guards was broken, the named test was shown to fail, the code was restored through git, and the test was shown to pass. Each row is one run, on the dev Mac, debug unless marked. The whole table was run again on this PR's final head (`5b0f2abd`), with the same results. | test | what it pins | the break | red | after restore | |---|---|---|---|---| | `arith::div255_over_every_input` (and `R_rat`, `R_half_up`, the straight-alpha channel, against exact rationals) | §3.0, §3.9, §2.9 | pre-bias 128 → 127 | `div255(128) is the half-up rounding of x/255` | green | | `refusal_order::wos1_load_check_order` (each code; five fault pairs) | §2.1 | check 5 run before check 4 | `check 4 before check 5` | green | | `refusal_order::record_pass_reports_field_range_before_any_cross_table_check` (`kind = 4, ref = 0` and `interp = 2 + j`, `j ≥ n_tables`, each beside a 5(a) fault) | §2.7 step 4 | the record pass moved after the sum rules | `payload_malformed` where `field_range` was expected | green | | `refusal_order::the_four_new_sum_rules` (one vector each for path contours, path points, strings, glyphs and clusters) | §2.7 step 5(a) | the `n_clusters` sum dropped | `refusals/s5a-clusters-sum was accepted` | green | | `refusal_order::exact_length_and_trailing_bytes` | §2.0 | one trailing byte accepted | `unwrap_err()` on an `Ok` | green | | `canonical::canonical_round_trip_on_every_vector` (parse then write, and form then pack) | §2.5 | the paint pool written in reverse | `every-table: form round trip` | green | | `canonical::duplicates_by_sorting_comparison_count` (review A's F10 shape at n = 65,535: 1,152,100 comparisons, against the bound 2·n·⌈log2 n⌉ = 2,097,120 and 2,147,385,345 pairs) | §2.5 rule 3 | a pairwise loop | `more than 2097120 comparisons` | green | | `clock_track::frame_range_by_division` (`g` up to `u64::MAX` at `P = 2^40`) | §2.7 | `g·P` formed in `i64` | debug: `attempt to multiply with overflow`; release: `frame 16777216 is out of range` (the product wraps to 0) | green, both | | `clock_track::integer_speed_roll_lands_on_the_grid` (M2's 750-frame roll at four rates) and `values_stay_between_their_keys` (M5) | §3.2 | linear keys routed through Q16 | `25/1, k = 1, 750 frames, frame 1` | green | | `geometry_cost::interval_check_boundary` and `interval_not_true_range` | §3.4(a) | the true range, evaluated at every tick, in place of the interval | `unwrap_err()` on an `Ok`: the document was accepted | green | | `geometry_cost::cost_counts_a_reused_path_per_use`, `cost_ceiling_boundary` | §3.4(b) | (1) the `bw·bh` term dropped; (2) a reused path counted once | `assertion left == right` at lines 70 and 71 | green, both | | `held_sets::a_counting_resolver_sees_at_most_length_plus_one_bytes` | §2.7 step 6 | read to the end of the stream | `the sink read 1048950 bytes of a set of length 374` | green | | `fuzz_smoke::fuzz_smoke` (no panic; every accepted input writes back to its bytes) | §2.0, §2.7 | the exact-length check removed | `index out of bounds` (debug and release) | green, both | | `peak_alloc::peak_allocation_is_linear_in_the_input` (≤ 6·input + 64 KiB over the corpus; worst 5.33×; nothing reserved for a header that claims the caps) | §2.0 | 2^22 keys and 2^16 items reserved before the length check | `a header claiming the caps made the parser reserve 53477376 bytes` | green | Also: - `refusal_order::steps_in_order` covers 14 pairs across steps 1–7. - `refusal_order::every_vector_has_the_code_its_note_names`, `corpus::*` and `geometry_cost::review_a_attack_payloads_are_refused` (below). ## Review A's attack payloads | shape | here | code | |---|---|---| | A: fills reusing a full-canvas 4-point path, at 4096 × 4096 | 260 items | `too_large` (step 9) | | B: fills reusing a path of 16,381 points (5,460 cubics spanning the canvas) | 26 items | `too_large` (step 9); one item alone is accepted | | C: full-canvas glyph records | one run of 256 | `too_large` (step 9) | | D: held sets at the largest `WOS1` | 64 sets, and 3 sets of 2^25 bytes | `too_large` (step 2, `held_len`); 2 sets of 2^25 bytes stay within `2^26` and are `outline_not_held` | | E: tracks equal but for the last key, two equal | 512 tracks | `payload_malformed` (5(g)), found by sorting | At full scale, built in memory (`geometry_cost::review_a_full_scale_costs`), the cost reproduces RC2's figures exactly: - A (65,536 fills): 1,101,944,324,096. - C (2^20 glyph records in 256 runs, with each run's hull term): 17,635,152,494,592, the figure #215's body derives. - B: RC2 counted 5,460 cubics as 16,380 points (10,992,717,135,872, reproduced from the formula). The path also stores its start point, so it costs `2^24 + 65,536 · c(16,381)`. ## Cross-checks - **Review A's `core.py` and the design's prototypes.** A scratch script reads the committed bytes with `struct`, sharing no code with the crate. Using `core.r_rat`, `core.rhu`, `merged_checks.hull_mul` and `review_checks.cost_fill`, it recomputes: - every `arith` table and case (`div255`, both quantisers, the straight-alpha channel, `R_rat`, `R_half_up`, and track evaluation through `merged_checks.eval_track`); - every contour of the accepted outline sets, through `core.contour_curves`; - the §3.4(a) verdict and the §3.4(b) cost of the 35 payloads that reach steps 8 and 9. **Agreement on all of it,** with one difference, from the text (below). With a cost, an interpolated value and a geometry verdict planted wrong, the script reports all three. - **The tree-wide tests:** - `corpus_provenance`, `int_kernels_vectors::every_decoded_output_states_a_sha256` and `signer_ids_are_labels`: green. - With the README's `**Provenance.**` label changed, `corpus_provenance` fails and names `vector-conformance/README.md`. With `sha256.json` removed, the sidecar test fails on it. So both read this corpus. ## Where the text, the design and the prototypes differ (the text is followed) 1. **A one-point contour whose point is a control.** - §2.1 says `P_0` MUST be on-curve, in every contour. - `core.py` and `review_checks.py` return early for a one-point contour and accept a control there. - The crate follows the text. `refusals/wos1-grammar-one-point-control` is `outline_malformed`, the one contour on which the cross-check and the crate disagree. 2. **Clusters' within-record rules.** `glyph_count = 0` only with `byte_len ≥ 1`, and the converse, read only their own record. - §2.7 places them at 5(g), with rule 5. The crate follows that. - #215 moved `ruby_len ≥ 1` into the record pass for that reason. By the same reasoning these would be `field_range` at step 4. The text could choose either way. 3. **A payload shorter than its 80-byte header** (a set shorter than 32 bytes). No step names it. The crate reports it at step 1 (`payload_malformed`; `outline_malformed` for a set), because the magic cannot be read. A sentence in §2.7 step 1 and §2.1 check 1 would settle it. 4. **Naming and layout, against the design:** - The generator is `wai-vector vectors gen` (§22.6's `src/bin/wai-vector.rs`), not §9.1's `wai_vector_vectors gen`. - Refusal vectors live in `vectors/refusals/` with `expected/refusals/` (§22.6), not in `refusals/` with `refusals.json` (§9.1). - The writers and the scene builder are in the default library, not behind §11.2's `author` feature, because the verifier's round trip (§2.5) needs the writer. `author` can arrive with D7-5's `WSF1`. 5. **RC2's attack B** counts 16,380 points. The path that 5,460 cubics need stores 16,381. ## Legs and gate - **Locally, on the dev Mac, every vector is identical on three engines:** - native macOS arm64, debug and release: every test, and `vectors verify` (268 vectors, 775 generated files); - `wasm32-wasip2` under wasmtime 49.0.2: every test, and `vectors verify`; - `wasm32-unknown-unknown` under Node 26.11.1: `verify.mjs` (268 vectors, 228 authoring forms). CI pins wasmtime 38.0.3 and Node 22. - **A second instruction-set architecture** (SPEC §7 asks it of frozen digests): a static `x86_64-unknown-linux-musl` build of the tool ran `vectors verify` on an x86_64 Linux host. All 268 vectors and 775 generated files are identical. - **Fuzz at depth:** 520,000 inputs from 260 seeds; no panic; 1,214 accepted inputs, each written back to its bytes. - **Clippy:** clean on every target with `--features std`, except one lint in `wai-ops`'s `sha256.rs`, which this crate includes by path and does not edit. - **The wai-rs gate** (`gate.sh d7-2`): build, lib tests, carriage, the corpus loop (21 of 21), fast kernels, byte-exact, wai-web wasm32 and the neural gates are all **GREEN**. - **Public text:** - `check-public-names.sh` with the private list: clean on each of the 544 changed files, one per invocation, and at CI scope (1,818 files); - `check-comparative-prose.sh` and `check-no-vanity-metrics.sh`: clean; - `check-wai-section-refs.py`: clean; - `check-workflow-concurrency.sh`: clean. ## Merge notes - **It touches no file #201 or #199 edits.** It adds new files only, under `wai/wai-vector/`, `wai/vector-conformance/` and `.github/workflows/`. - **Legs for the merge:** `wai-vector.yml` (`native` ×3, `wasip2`, `node`, `fuzz`); `wai-conformance.yml` (`corpus_provenance`, `every_decoded_output_states_a_sha256`); `no-vanity-metrics.yml`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
The model and conformance (overlay-equivalence and text-equivalence over
the overlay layer only), the WOS1 and WVG1 formats with their canonical
rules, caps and refusal order, the digest sidecar and text digests, and
the arithmetic: clock, tracks, placement, the load-time interval check
and per-frame cost, flattening, row and cell split, accumulation,
coverage and compositing, as the stage family RS1–RS9. Sections 4–6 and
the annexes are headings that later revisions of this Draft fill.

Nothing is registered.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
- WOS1 load check 2 names its counts, and check 7 states what a
  glyph's contour ends must satisfy;
- groups: each end closes the innermost open begin, none is left open;
- the probe set gives each candidate frame as a formula;
- the interval check names O's interval per axis.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai: README and CHANGELOG name the graphics-vector Draft
All checks were successful
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 2m3s
standards workspaces build + test / aac-rs (pull_request) Successful in 1m31s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 48s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 34s
standards workspaces build + test / map-rs (pull_request) Successful in 26s
standards workspaces build + test / mesh-rs (pull_request) Successful in 27s
standards workspaces build + test / openpay (pull_request) Successful in 1m21s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 1m45s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m59s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 6m21s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 3m17s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 6s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 6s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 4s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m12s
standards workspaces build + test / eoc-rs (pull_request) Successful in 2m5s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m38s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m15s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m15s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m23s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m12s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m22s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 2m31s
WAI section references / cited sections exist (pull_request) Successful in 12s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 4m18s
f66c09ede1
Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-vector: WOS1 and WVG1 with the refusal order of §2.7, the clock, tracks, the interval check and the cost (D7-2)
Some checks failed
standards workspaces build + test / jouledesk-rs (pull_request) Has been cancelled
standards workspaces build + test / joulehook-rs (pull_request) Has been cancelled
standards workspaces build + test / proof-rs (pull_request) Has been cancelled
standards workspaces build + test / sandbox-rs (pull_request) Has been cancelled
standards workspaces build + test / sense-rs (pull_request) Has been cancelled
standards workspaces build + test / smart-byte-rs (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cargo-class corpora · macos (pull_request) Has been cancelled
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Has been cancelled
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Has been cancelled
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Has been cancelled
WAI conformance / cross-arch byte-equality · macos (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux (pull_request) Has been cancelled
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Has been cancelled
WAI energy receipts / energy receipts · macos (pull_request) Has been cancelled
WAI section references / cited sections exist (pull_request) Has been cancelled
wai-vector vector graphics / linux-aarch64 (pull_request) Has been cancelled
wai-vector vector graphics / linux-x86_64 (pull_request) Has been cancelled
wai-vector vector graphics / macos-arm64 (pull_request) Has been cancelled
wai-vector vector graphics / wasm32-wasip2 (wasmtime) (pull_request) Has been cancelled
wai-vector vector graphics / wasm32 under Node (pull_request) Has been cancelled
wai-vector vector graphics / fuzz, peak allocation, comparison count (pull_request) Has been cancelled
workflow hygiene / every workflow supersedes its own queue (pull_request) Has been cancelled
standards workspaces build + test / openpay (pull_request) Has been cancelled
2f147d2a30
The reference crate of wai.graphics.vector (no_std + alloc, no
dependencies; SHA-256 is wai-ops's, by #[path]):
- WOS1 parsed with §2.1's load checks in order, and written;
- WVG1 split (steps 1-3, nothing allocated before the exact length),
  the record pass (step 4), the cross-record checks (step 5(a)-(h)),
  the sets by digest with at most length + 1 bytes read (step 6), the
  glyphs (7), the interval check (8) and the per-frame cost (9);
- the clock with the frame range by division, track evaluation, and
  placement;
- the JSON authoring form, one member per field, packing back to the
  same bytes;
- the CLI: check, cost, pack, unpack, vectors gen and verify;
- a wasm32 module and verify.mjs for Node.

The corpus wai/vector-conformance/ (arith, canonical, refusals,
geometry, cost) with its README's provenance line and a sha256.json
sidecar naming the div255 table; wai-vector.yml with native, wasip2,
node and fuzz jobs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-vector: clippy-clean, the empty frame range built without a reversed literal; no generated byte changes
All checks were successful
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 12m12s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 34s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 4m9s
wai-vector vector graphics / macos-arm64 (pull_request) Successful in 31s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 6s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 5s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 5s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m15s
standards workspaces build + test / eoc-rs (pull_request) Successful in 2m6s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m35s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m15s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m16s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m22s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m19s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m26s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 4m14s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 1m24s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 16s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 8m43s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 10s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 31s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 54s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 2m3s
WAI section references / cited sections exist (pull_request) Successful in 10s
wai-vector vector graphics / linux-x86_64 (pull_request) Successful in 24s
wai-vector vector graphics / wasm32-wasip2 (wasmtime) (pull_request) Successful in 21s
wai-vector vector graphics / wasm32 under Node (pull_request) Successful in 19s
wai-vector vector graphics / fuzz, peak allocation, comparison count (pull_request) Successful in 14s
workflow hygiene / every workflow supersedes its own queue (pull_request) Successful in 4s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 16m51s
5b0f2abde0
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!216
No description provided.