wai.splat.exact: Gaussian splats in glTF as an exact WAI object, an integer renderer whose frames are the same everywhere (CPU = GPU), commitments and view statements (SPLAT) #431

Closed
dcharlot wants to merge 0 commits from wai/splat-exact into main
Owner

What this adds (SPLAT)

Gaussian splats as an exchangeable compressed form in glTF, and a renderer whose frames are the same bytes everywhere, so a frame can be committed to and signed.

  • extensions/splat-exact.md registers the record wai.splat.exact:
    • Carriage in glTF (§3). A wai.splat.int_codec object travels in a glTF 2.0 asset (ISO/IEC 12113:2022) as the draft compression extension EXT_gaussian_splatting_compression_wai, nested in a mesh primitive's KHR_gaussian_splatting object (the base extension's own extensions). A buffer view holds the object's WAI1 envelope; the extension states its content hash (jwp-receipts §2.1), its parameter set (carried in the asset, or held by digest) and, in another buffer view, the origin's commitment as JCS text (read byte for byte, whatever a glTF reader does with numbers). The five accessors carry no data, so both extensions are required; POSITION's min/max must be the decode's own. Draft JSON Schema: extensions/gltf/EXT_gaussian_splatting_compression_wai.schema.json. Nothing is submitted to the glTF registry.
    • Attributes (§4). The 14 planes of wai.splat.int_codec, dequantized at 2^16 from the payload's binary32 ranges (rounded half up, exactly), and their mapping onto POSITION, ROTATION, SCALE, OPACITY, SH_DEGREE_0_COEF_0.
    • The renderer wai-splat-render:i1 (§5). Fixed-point camera from integer eye/target/up; fixed-point EWA projection (0.3 px² low pass, 1.3× Jacobian clamp); stated culls; order by squared camera distance (the base extension's cameraDistance), the Gaussian's index breaking every tie; per-pixel integer alpha compositing with every rounding stated (exp_neg_q16 of integer-operators §2, 3σ cut-off, alpha in [1/255, 0.99], stop below 0.0001); 16 × 16 tiles in raster order, which cannot change the frame (pixels are independent). Every value compositing reads fits 32 bits; only e1, e2 need 64.
    • Commitment (§6) signed by the origin: object, set, attribute digest, renderer, class, origin claim, and the frame digest at each canonical (pinned, integer) pose. View statement (§7) signed by a sink under a session key: pose, canonical index or null, frame digest, class — C3's presentation-statement pattern (#408), for one frame.
    • Provenance (§8). A rendered view is a convert of the splat set under synthesis §3.2: class = max(reconstructed, the splat set's class). synthesis.md §3.1 now admits media volumetric for origin claims (a splat set, mesh, point cloud); synthesis.rs and synthesis_verify.py follow (ORIGIN_MEDIA).
    • Verification (§9), 19 reasons (§10), conformance (§11), measured quality cost (§12), security/privacy (§13).
  • wai-rs splat_exact (feature splat_exact = ["splat_int", "synthesis"], no new dependency): asset reading, the decode through the envelope's pin, the renderer, a tile-by-tile composite (tested equal), the identity set (a one-layer WHM1 that carries attribute bytes as they are, for authored scenes), records, verification, and float (an f32/f64 renderer of the same model, for measurement only). Bins wai_splat_exact_vectors gen|verify, wai_splat_exact_measure. Tests: unit tests, tests/splat_exact.rs.
  • GPU (wai-ops-gpu): wgsl/splat.wgsl + splat.rs, one invocation per pixel, one workgroup per tile, e1/e2 through G1's probed mul_i32/w_add. splat_exact::gpu (features splat_exact, ops_gpu); tests/splat_exact_gpu.rs holds every view to the CPU frame and requires three edited kernels caught.
  • Corpus live-conformance/splat/ (33 cases): the learned cloud of tests/vectors/int_splat/ (set held by digest), two authored scenes through the identity set (set inline), every reason of §10, and the asked-for negative controls: cluster_reordered (reordered sort → frame_mismatch), statement_frame (a frame that doesn't recompute → frame_mismatch), cluster_wrong_splats (commitment over the wrong splats → attributes_mismatch), statement_pose (a pose outside the pinned set claimed canonical → pose_not_canonical).
  • Second implementation live-conformance/splat_exact_verify.py (python3 -I, stdlib): decodes WIS1 via int_payload_verify.py (parse, rANS) and tools/wai_ops_check.py (whm1/1 lowering + interpreter), renders with its own integer renderer, strict Ed25519 + BLAKE3 from claim-conformance, reads §10 from the text.
  • CI: wai-conformance.yml step + paths; wai-ops-gpu.yml macos step (REQUIRE'd), linux --no-run, paths.
  • Registry: wai.splat.exact (record), wai-splat-commitment, wai-splat-view (document kinds), wai-splat-render:i1 (scheme), EXT_gaussian_splatting_compression_wai (proposed) under a new wire-identifier kind gltf-extension (enum, schema, REGISTRY prose); export regenerated. SPEC §5 paragraph, CHANGELOG.

State of the glTF splat extensions (as read 2026-10-22, cited by name and PR in the extension)

  • KHR_gaussian_splatting: its text states complete/ratified; added by #2490 (merged 2026-01-27), last changed by #2677 (2026-10-13, component types). Object on a mesh primitive: kernel (ellipse), colorSpace, projection (perspective), sortingMethod (cameraDistance); compression extensions nest in its extensions and should be required when there is no fallback.
  • Under review: KHR_gaussian_splatting_compression_spz_2 (#2531), KHR_gaussian_splatting_lgsc (#2551), KHR_gaussian_splatting_compression_EGSC (#2605); superseded draft KHR_spz_gaussian_splats_compression (#2486, closed); KHR_meshopt_compression (#2517, merged).

Design decisions, and why

  • The buffer view holds a whole WAI1 envelope, not the bare WIS1 payload. The envelope carries the capability and the parameter-set pin, and gives the object a content hash, so receipts and synthesis origin claims name the splat set directly.
  • Extension name EXT_gaussian_splatting_compression_wai, with a capability member (this revision admits only wai.splat.int_codec). The capability string fixes its payload format forever (SPEC §8), which is what the _2 suffix of the spz proposal does for its format.
  • The commitment rides as text in a buffer view, not as inline JSON, so it is read and verified byte for byte (strict JSON, signature over JCS) regardless of the glTF reader.
  • Sort by squared Euclidean camera distance (the base extension's cameraDistance), ties by index; front-to-back with transmittance (the same blend as back-to-front in exact arithmetic; here the transmittance falls by exactly what each Gaussian adds and a pixel can stop).
  • Whitened coordinates (k1, k2, k3) instead of the conic for the per-pixel distance: they stay bounded for elongated splats, so per-pixel work is 32-bit apart from two 64-bit products — which is what made the GPU kernel a direct port onto G1's probed arithmetic.
  • The renderer is not a wai-ops/1 graph (sort and rectangles are not graph operators); it uses integer-operators §2's functions (exp_neg_q16, R_half_up, isqrt). So the GPU path is a dedicated kernel on G1's device layer and arithmetic, not the graph executor.
  • Signed integers in poses are strings ("-196608"), because jwp-receipts §2.4.3 integers are unsigned.
  • The identity set lets the corpus author scenes as exact bytes (ties, zero quaternion, near-plane and rectangle culls) and still carry them as real WIS1 payloads decoded by both implementations; stated as a conformance device, not a codec.
  • New wire-identifier kind gltf-extension. None of the existing kinds describes a glTF extension name; the schema enum and the registry test were extended.

Rate and quality — measured

wai_splat_exact_measure (release, build host), integer frame vs the same model in f64; f32 vs f64 bytes differing:

scene size PSNR int vs f64 max byte diff int vs f64 bytes f32 ≠ f64 per frame
learned cloud (shell, 1024 Gaussians) 96×96, 80×64 62.29–64.45 dB 2 0–2 of 27648
learned cloud 384×384, 320×256 (4×) 62.29–64.78 dB 4 7–24
authored cluster 80×60 59.40–61.53 dB 2 0–2 of 14400
authored cluster 320×240 (4×) 59.43–61.73 dB 3 3–17
authored tiny 40×30 63.24–67.16 dB 1 0
authored tiny 160×120 (4×) 64.45–66.89 dB 3 0–1

Command: wai_splat_exact_measure 1 and wai_splat_exact_measure 4 (release, on the build host). The cost includes §4.2's fixed-point dequantization (the float renderer decodes attributes in float). The measurement is the arithmetic cost under the same model; the model itself (EWA, 0.3 px² low pass, 3σ, alpha limits, stop) is the conventional one.

The integer renderer is within 59.4–67.2 dB of f64 (no byte off by more than 4); the float renderer itself is not one renderer (f32 ≠ f64 on some views at the corpus's sizes, nearly all at 4×).

Checks

check command result
module unit tests cargo test --locked --no-default-features --features splat_exact --lib splat_exact:: (rb) 5 passed
corpus + reasons + tiles + schema cargo test --locked --no-default-features --features splat_exact --test splat_exact (rb) 4 passed
corpus regenerates wai_splat_exact_vectors verify ../live-conformance/splat (rb, release) PASS byte for byte; PASS every case
GPU = CPU WAI_OPS_GPU_REQUIRE=1 WAI_OPS_GPU_EXPECT=gpu-metal-0 cargo test --locked --release --no-default-features --features splat_exact,ops_gpu --test splat_exact_gpu (rb, Metal) views=13 differ=0 mutants_survived=0
wai-ops-gpu suite (crate touched) WAI_OPS_GPU_REQUIRE=1 cargo test --locked --release -- --test-threads=1 in wai-ops-gpu (rb) 6 tests passed (1+2+2+1), as CI counts
synthesis (ORIGIN_MEDIA) --features synthesis --lib synthesis::; --test synthesis; --features contribution --test contribution (rb) 17, 4, 4 passed
registry cargo test --locked --no-default-features --lib codecs::registry (wire ids in their sections, schema enum = labels) 14 passed
digests test (description changed) --features neural_int,video_int,audio_int,world_int,splat_int --test int_kernels_vectors 8 passed
registry export cargo run -q --no-default-features --bin wai -- registry export then --check (rb, pulled) up to date, exit 0
clippy cargo clippy --locked --no-default-features --features splat_exact --all-targets, splat_exact,ops_gpu, synthesis; cargo clippy --locked --all-targets in wai-ops-gpu no note in any touched file (wai-rs 120 = the pre-existing count for these features, all in jpegai_synthesis.rs etc.; wai-ops-gpu 0)
lockfiles cargo metadata --locked --offline --format-version 1 in wai-rs and wai-ops-gpu ok; no dependency added
second implementation python3 -I live-conformance/splat_exact_verify.py live-conformance/splat (local) PASS: 33 cases, reasons, 11 corpus mutations, 25 dropped checks, 11 renderer-rule changes all caught
other verifiers reading synthesis text synthesis_verify.py, contribution_verify.py, synthesis_mark_verify.py PASS
repo checks check-tests-in-ci.py, check-workflow-concurrency.sh, check-spec-refs.py, check-wai-section-refs.py, check-no-vanity-metrics.sh, test-public-text-checks.sh, check-comparative-prose.sh, check-orphan-sources.py all exit 0
public names scripts/check-public-names.sh on the 72 changed files (incl. .gltf, .wgsl, .yml); commit messages and this body with grep -E -f clean

Falsifications

  • Rust renderer rule broken (T_MIN 7 → 8, uncommitted): wai_splat_exact_vectors verify exit 1 (files don't regenerate; shell and shell_origin_class not their stated outcome); --test splat_exact exit 101. Restored.
  • Spec reason table broken (pose_not_canonical renamed in §10): the_reason_table_is_the_reference_codes panics; splat_exact_verify.py exit 1 (reason table ≠ corpus codes). Restored.
  • Corpus byte flipped (tiny.bin byte 700): splat_exact_verify.py exit 1 (tiny, statement_class → object_mismatch). Restored.
  • Built into the second implementation (run every time): 11 corpus mutations each fail; each of 25 checks dropped in turn is caught by some case (this first found 7 checks no case separated — unrequired extension, a buffer view past the envelope, set bytes vs pin, commitment object/set, statement object/renderer, a canonical pose with another pose's frame — and the corpus gained a case for each); each of 11 renderer-rule changes (tie order, sort by depth, low pass, rdiv rounding, float exp, contribution rounding, stop rule, alpha ceiling, cut-off, rectangle rounding, near plane) changes a committed frame.
  • GPU: three edited kernels (contribution rounded down, alpha ceiling raised, cut-off doubled) are each caught by the views on Metal (mutants_survived=0).
  • Float non-determinism shown: the f32 and f64 builds of the same float renderer disagree on bytes of 4 of 13 views at the corpus's sizes and 11 of 13 at 4×.

Not done

  • GPU on other adapters: run on Metal (the build host's integrated GPU, arm64) only; Vulkan/DX12 and browser WebGPU legs not run for the splat kernel (the browser module was not extended).
  • No forge CI run yet of the new steps (they run on this PR).
  • Spherical harmonics above degree 0, view-dependent colour, the glTF node transform: out of scope by the text (wai.splat.int_codec's layout has none).
  • The renderer is not a wai-ops/1 graph (sort and rectangles are not graph operators); the GPU path is a dedicated kernel on G1's device layer and probed arithmetic, not the graph executor.
  • wai-presentation of #408 is not referenced normatively (not merged); the view statement follows its pattern. When #408 lands, a view could appear as a transmitted/derived entry there — a follow-up.
  • Scale: the corpus scenes are small (≤ 1024 Gaussians, ≤ 384² frames); quality figures are for these scenes only, as §12 says.
  • Nothing submitted to the glTF registry (owner decision); the extension name is registered as proposed.

🤖 Generated with Claude Code


Closed: landed on main through merge train C (#461, e0ac15f5); this PR's head is an ancestor of main.

## What this adds (SPLAT) Gaussian splats as an exchangeable compressed form in glTF, and a renderer whose frames are the same bytes everywhere, so a frame can be committed to and signed. - **`extensions/splat-exact.md`** registers the record `wai.splat.exact`: - **Carriage in glTF (§3).** A `wai.splat.int_codec` object travels in a glTF 2.0 asset (ISO/IEC 12113:2022) as the draft compression extension `EXT_gaussian_splatting_compression_wai`, nested in a mesh primitive's `KHR_gaussian_splatting` object (the base extension's own `extensions`). A buffer view holds the object's `WAI1` envelope; the extension states its content hash (jwp-receipts §2.1), its parameter set (carried in the asset, or held by digest) and, in another buffer view, the origin's commitment as JCS text (read byte for byte, whatever a glTF reader does with numbers). The five accessors carry no data, so both extensions are required; `POSITION`'s `min`/`max` must be the decode's own. Draft JSON Schema: `extensions/gltf/EXT_gaussian_splatting_compression_wai.schema.json`. Nothing is submitted to the glTF registry. - **Attributes (§4).** The 14 planes of `wai.splat.int_codec`, dequantized at 2^16 from the payload's binary32 ranges (rounded half up, exactly), and their mapping onto `POSITION`, `ROTATION`, `SCALE`, `OPACITY`, `SH_DEGREE_0_COEF_0`. - **The renderer `wai-splat-render:i1` (§5).** Fixed-point camera from integer eye/target/up; fixed-point EWA projection (0.3 px² low pass, 1.3× Jacobian clamp); stated culls; order by squared camera distance (the base extension's `cameraDistance`), the Gaussian's index breaking every tie; per-pixel integer alpha compositing with every rounding stated (`exp_neg_q16` of integer-operators §2, 3σ cut-off, alpha in [1/255, 0.99], stop below 0.0001); 16 × 16 tiles in raster order, which cannot change the frame (pixels are independent). Every value compositing reads fits 32 bits; only `e1`, `e2` need 64. - **Commitment (§6)** signed by the origin: object, set, attribute digest, renderer, class, origin claim, and the frame digest at each canonical (pinned, integer) pose. **View statement (§7)** signed by a sink under a session key: pose, canonical index or `null`, frame digest, class — C3's presentation-statement pattern (#408), for one frame. - **Provenance (§8).** A rendered view is a `convert` of the splat set under synthesis §3.2: class = max(`reconstructed`, the splat set's class). `synthesis.md` §3.1 now admits `media` `volumetric` for origin claims (a splat set, mesh, point cloud); `synthesis.rs` and `synthesis_verify.py` follow (`ORIGIN_MEDIA`). - **Verification (§9), 19 reasons (§10), conformance (§11), measured quality cost (§12), security/privacy (§13).** - **wai-rs** `splat_exact` (feature `splat_exact = ["splat_int", "synthesis"]`, no new dependency): asset reading, the decode through the envelope's pin, the renderer, a tile-by-tile composite (tested equal), the identity set (a one-layer `WHM1` that carries attribute bytes as they are, for authored scenes), records, verification, and `float` (an f32/f64 renderer of the same model, for measurement only). Bins `wai_splat_exact_vectors gen|verify`, `wai_splat_exact_measure`. Tests: unit tests, `tests/splat_exact.rs`. - **GPU** (`wai-ops-gpu`): `wgsl/splat.wgsl` + `splat.rs`, one invocation per pixel, one workgroup per tile, `e1`/`e2` through G1's probed `mul_i32`/`w_add`. `splat_exact::gpu` (features `splat_exact`, `ops_gpu`); `tests/splat_exact_gpu.rs` holds every view to the CPU frame and requires three edited kernels caught. - **Corpus `live-conformance/splat/`** (33 cases): the learned cloud of `tests/vectors/int_splat/` (set held by digest), two authored scenes through the identity set (set inline), every reason of §10, and the asked-for negative controls: `cluster_reordered` (reordered sort → `frame_mismatch`), `statement_frame` (a frame that doesn't recompute → `frame_mismatch`), `cluster_wrong_splats` (commitment over the wrong splats → `attributes_mismatch`), `statement_pose` (a pose outside the pinned set claimed canonical → `pose_not_canonical`). - **Second implementation** `live-conformance/splat_exact_verify.py` (`python3 -I`, stdlib): decodes WIS1 via `int_payload_verify.py` (parse, rANS) and `tools/wai_ops_check.py` (`whm1/1` lowering + interpreter), renders with its own integer renderer, strict Ed25519 + BLAKE3 from claim-conformance, reads §10 from the text. - **CI**: `wai-conformance.yml` step + paths; `wai-ops-gpu.yml` macos step (REQUIRE'd), linux `--no-run`, paths. - **Registry**: `wai.splat.exact` (record), `wai-splat-commitment`, `wai-splat-view` (document kinds), `wai-splat-render:i1` (scheme), `EXT_gaussian_splatting_compression_wai` (proposed) under a new wire-identifier kind `gltf-extension` (enum, schema, REGISTRY prose); export regenerated. SPEC §5 paragraph, CHANGELOG. ## State of the glTF splat extensions (as read 2026-10-22, cited by name and PR in the extension) - `KHR_gaussian_splatting`: its text states complete/ratified; added by #2490 (merged 2026-01-27), last changed by #2677 (2026-10-13, component types). Object on a mesh primitive: `kernel` (`ellipse`), `colorSpace`, `projection` (`perspective`), `sortingMethod` (`cameraDistance`); compression extensions nest in its `extensions` and should be required when there is no fallback. - Under review: `KHR_gaussian_splatting_compression_spz_2` (#2531), `KHR_gaussian_splatting_lgsc` (#2551), `KHR_gaussian_splatting_compression_EGSC` (#2605); superseded draft `KHR_spz_gaussian_splats_compression` (#2486, closed); `KHR_meshopt_compression` (#2517, merged). ## Design decisions, and why - **The buffer view holds a whole `WAI1` envelope, not the bare `WIS1` payload.** The envelope carries the capability and the parameter-set pin, and gives the object a content hash, so receipts and synthesis origin claims name the splat set directly. - **Extension name `EXT_gaussian_splatting_compression_wai`, with a `capability` member** (this revision admits only `wai.splat.int_codec`). The capability string fixes its payload format forever (SPEC §8), which is what the `_2` suffix of the spz proposal does for its format. - **The commitment rides as text in a buffer view**, not as inline JSON, so it is read and verified byte for byte (strict JSON, signature over JCS) regardless of the glTF reader. - **Sort by squared Euclidean camera distance** (the base extension's `cameraDistance`), ties by index; front-to-back with transmittance (the same blend as back-to-front in exact arithmetic; here the transmittance falls by exactly what each Gaussian adds and a pixel can stop). - **Whitened coordinates (`k1`, `k2`, `k3`) instead of the conic** for the per-pixel distance: they stay bounded for elongated splats, so per-pixel work is 32-bit apart from two 64-bit products — which is what made the GPU kernel a direct port onto G1's probed arithmetic. - **The renderer is not a `wai-ops/1` graph** (sort and rectangles are not graph operators); it uses integer-operators §2's functions (`exp_neg_q16`, `R_half_up`, `isqrt`). So the GPU path is a dedicated kernel on G1's device layer and arithmetic, not the graph executor. - **Signed integers in poses are strings** (`"-196608"`), because jwp-receipts §2.4.3 integers are unsigned. - **The identity set** lets the corpus author scenes as exact bytes (ties, zero quaternion, near-plane and rectangle culls) and still carry them as real `WIS1` payloads decoded by both implementations; stated as a conformance device, not a codec. - **New wire-identifier kind `gltf-extension`.** None of the existing kinds describes a glTF extension name; the schema enum and the registry test were extended. ## Rate and quality — measured `wai_splat_exact_measure` (release, build host), integer frame vs the same model in f64; f32 vs f64 bytes differing: | scene | size | PSNR int vs f64 | max byte diff int vs f64 | bytes f32 ≠ f64 per frame | |---|---|---|---|---| | learned cloud (`shell`, 1024 Gaussians) | 96×96, 80×64 | 62.29–64.45 dB | 2 | 0–2 of 27648 | | learned cloud | 384×384, 320×256 (4×) | 62.29–64.78 dB | 4 | 7–24 | | authored `cluster` | 80×60 | 59.40–61.53 dB | 2 | 0–2 of 14400 | | authored `cluster` | 320×240 (4×) | 59.43–61.73 dB | 3 | 3–17 | | authored `tiny` | 40×30 | 63.24–67.16 dB | 1 | 0 | | authored `tiny` | 160×120 (4×) | 64.45–66.89 dB | 3 | 0–1 | Command: `wai_splat_exact_measure 1` and `wai_splat_exact_measure 4` (release, on the build host). The cost includes §4.2's fixed-point dequantization (the float renderer decodes attributes in float). The measurement is the arithmetic cost under the same model; the model itself (EWA, 0.3 px² low pass, 3σ, alpha limits, stop) is the conventional one. The integer renderer is within 59.4–67.2 dB of f64 (no byte off by more than 4); the float renderer itself is not one renderer (f32 ≠ f64 on some views at the corpus's sizes, nearly all at 4×). ## Checks | check | command | result | |---|---|---| | module unit tests | `cargo test --locked --no-default-features --features splat_exact --lib splat_exact::` (rb) | 5 passed | | corpus + reasons + tiles + schema | `cargo test --locked --no-default-features --features splat_exact --test splat_exact` (rb) | 4 passed | | corpus regenerates | `wai_splat_exact_vectors verify ../live-conformance/splat` (rb, release) | PASS byte for byte; PASS every case | | GPU = CPU | `WAI_OPS_GPU_REQUIRE=1 WAI_OPS_GPU_EXPECT=gpu-metal-0 cargo test --locked --release --no-default-features --features splat_exact,ops_gpu --test splat_exact_gpu` (rb, Metal) | `views=13 differ=0 mutants_survived=0` | | wai-ops-gpu suite (crate touched) | `WAI_OPS_GPU_REQUIRE=1 cargo test --locked --release -- --test-threads=1` in `wai-ops-gpu` (rb) | 6 tests passed (1+2+2+1), as CI counts | | synthesis (ORIGIN_MEDIA) | `--features synthesis --lib synthesis::`; `--test synthesis`; `--features contribution --test contribution` (rb) | 17, 4, 4 passed | | registry | `cargo test --locked --no-default-features --lib codecs::registry` (wire ids in their sections, schema enum = labels) | 14 passed | | digests test (description changed) | `--features neural_int,video_int,audio_int,world_int,splat_int --test int_kernels_vectors` | 8 passed | | registry export | `cargo run -q --no-default-features --bin wai -- registry export` then `--check` (rb, pulled) | up to date, exit 0 | | clippy | `cargo clippy --locked --no-default-features --features splat_exact --all-targets`, `splat_exact,ops_gpu`, `synthesis`; `cargo clippy --locked --all-targets` in wai-ops-gpu | no note in any touched file (wai-rs 120 = the pre-existing count for these features, all in `jpegai_synthesis.rs` etc.; wai-ops-gpu 0) | | lockfiles | `cargo metadata --locked --offline --format-version 1` in wai-rs and wai-ops-gpu | ok; no dependency added | | second implementation | `python3 -I live-conformance/splat_exact_verify.py live-conformance/splat` (local) | PASS: 33 cases, reasons, 11 corpus mutations, 25 dropped checks, 11 renderer-rule changes all caught | | other verifiers reading synthesis text | `synthesis_verify.py`, `contribution_verify.py`, `synthesis_mark_verify.py` | PASS | | repo checks | `check-tests-in-ci.py`, `check-workflow-concurrency.sh`, `check-spec-refs.py`, `check-wai-section-refs.py`, `check-no-vanity-metrics.sh`, `test-public-text-checks.sh`, `check-comparative-prose.sh`, `check-orphan-sources.py` | all exit 0 | | public names | `scripts/check-public-names.sh` on the 72 changed files (incl. .gltf, .wgsl, .yml); commit messages and this body with `grep -E -f` | clean | ## Falsifications - **Rust renderer rule broken** (`T_MIN` 7 → 8, uncommitted): `wai_splat_exact_vectors verify` exit 1 (files don't regenerate; `shell` and `shell_origin_class` not their stated outcome); `--test splat_exact` exit 101. Restored. - **Spec reason table broken** (`pose_not_canonical` renamed in §10): `the_reason_table_is_the_reference_codes` panics; `splat_exact_verify.py` exit 1 (reason table ≠ corpus codes). Restored. - **Corpus byte flipped** (`tiny.bin` byte 700): `splat_exact_verify.py` exit 1 (`tiny`, `statement_class` → `object_mismatch`). Restored. - **Built into the second implementation** (run every time): 11 corpus mutations each fail; each of 25 checks dropped in turn is caught by some case (this first found 7 checks no case separated — unrequired extension, a buffer view past the envelope, set bytes vs pin, commitment object/set, statement object/renderer, a canonical pose with another pose's frame — and the corpus gained a case for each); each of 11 renderer-rule changes (tie order, sort by depth, low pass, `rdiv` rounding, float exp, contribution rounding, stop rule, alpha ceiling, cut-off, rectangle rounding, near plane) changes a committed frame. - **GPU**: three edited kernels (contribution rounded down, alpha ceiling raised, cut-off doubled) are each caught by the views on Metal (`mutants_survived=0`). - **Float non-determinism shown**: the f32 and f64 builds of the same float renderer disagree on bytes of 4 of 13 views at the corpus's sizes and 11 of 13 at 4×. ## Not done - **GPU on other adapters**: run on Metal (the build host's integrated GPU, arm64) only; Vulkan/DX12 and browser WebGPU legs not run for the splat kernel (the browser module was not extended). - **No forge CI run yet** of the new steps (they run on this PR). - **Spherical harmonics above degree 0, view-dependent colour, the glTF node transform**: out of scope by the text (`wai.splat.int_codec`'s layout has none). - **The renderer is not a `wai-ops/1` graph** (sort and rectangles are not graph operators); the GPU path is a dedicated kernel on G1's device layer and probed arithmetic, not the graph executor. - **`wai-presentation` of #408** is not referenced normatively (not merged); the view statement follows its pattern. When #408 lands, a view could appear as a `transmitted`/`derived` entry there — a follow-up. - **Scale**: the corpus scenes are small (≤ 1024 Gaussians, ≤ 384² frames); quality figures are for these scenes only, as §12 says. - **Nothing submitted to the glTF registry** (owner decision); the extension name is registered as `proposed`. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- **Closed:** landed on main through merge train C (#461, e0ac15f5); this PR's head is an ancestor of main.
The wai-rs module behind the feature splat_exact: the asset read as a
compression extension of KHR_gaussian_splatting, the decode through the
envelope's pin, the fixed-point camera, projection, order and integer
compositing, the identity set the corpus carries authored scenes with,
the commitment and view statement records, and a float renderer of the
same model for measurement. The corpus live-conformance/splat/ written by
wai_splat_exact_vectors gen, and its second implementation
splat_exact_verify.py with its own integer renderer. Synthesis origin
claims may now name volumetric media.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
extensions/splat-exact.md registers wai.splat.exact: carriage in glTF as
EXT_gaussian_splatting_compression_wai under KHR_gaussian_splatting, the
attribute layout and its dequantization, the renderer wai-splat-render:i1,
the commitment, the view statement, provenance, verification, reasons and
the measured quality cost. The draft JSON Schema of the extension object is
extensions/gltf/. The corpus gains cases the second implementation's
self-falsification showed were missing: an unrequired extension, a buffer
view past the envelope, a set whose bytes or pin alone disagree, a
commitment naming another object or set, and statements naming another
object or renderer or another pose's frame.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
wai-ops-gpu gains the kernel wgsl/splat.wgsl, one invocation a pixel and
one workgroup a 16 x 16 tile, over the operator set's probed 64-bit
products; the host projects, culls and orders. wai-rs's splat_exact::gpu
(features splat_exact, ops_gpu) composes on every adapter found, and
tests/splat_exact_gpu.rs holds every canonical and own-pose view of the
splat corpus to the CPU's frame byte for byte and requires three edited
kernels to be caught. The macos job of wai-ops-gpu.yml runs it under
WAI_OPS_GPU_REQUIRE; the linux job builds it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
The record wai.splat.exact; the document kinds wai-splat-commitment and
wai-splat-view, the scheme wai-splat-render:i1, and the proposed glTF
extension name EXT_gaussian_splatting_compression_wai under a new wire
identifier kind, gltf-extension (schema enum, REGISTRY.md prose). The
wai-conformance.yml step runs the module's tests and splat_exact_verify.py,
and its paths take the extension, its schema and wai_ops_check.py. The
extension's §11 records the GPU run.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Co-Authored-By: Claude Opus 5.5 <[email protected]>
splat_exact: clippy's range loops, partial order, slice and as_chunks notes
Some checks failed
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (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 conformance / does this change touch it (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 / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled
3ec983a533
Co-Authored-By: Claude Opus 5.5 <[email protected]>
dcharlot closed this pull request 2026-10-25 23:51:27 -04:00
Some checks failed
wai-web wasm32 / does this change touch it (pull_request) Has been cancelled
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been cancelled
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Has been cancelled
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Has been cancelled
wai-quantum studio and desktop / does this change touch it (pull_request) Has been cancelled
wai-quantum studio and desktop / studio · browser (pull_request) Has been cancelled
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been cancelled
wai-pack / wai-pack · does this change touch it (pull_request) Has been cancelled
wai-pack / wai-pack · linux (pull_request) Has been cancelled
wai-pack / wai-pack · linux-arm64 (pull_request) Has been cancelled
wai-pack / wai-pack · macos (pull_request) Has been cancelled
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been cancelled
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been cancelled
wai-pack / wai-pack · dependency licences (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / does this change touch it (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / builds · no adapter is not a pass (linux) (pull_request) Has been cancelled
wai-ops-gpu integer operators on GPUs / Metal GPU and browser WebGPU (macos) (pull_request) Has been cancelled
WAI energy receipts / does this change touch it (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 conformance / does this change touch it (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 / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Has been cancelled
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Has been cancelled
standards workspaces build + test / which workspaces this change touches (pull_request) Has been cancelled
standards workspaces build + test / macOS energy backends (pull_request) Has been cancelled
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Has been cancelled
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Has been cancelled
joule-moq-room room service / joule-moq-room, every target (pull_request) Has been cancelled

Pull request closed

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!431
No description provided.