Skip to content

A model and the bytes it reads to, both committed - #336

Merged
CagdasErturk merged 4 commits into
mainfrom
import-golden
Sep 9, 2026
Merged

A model and the bytes it reads to, both committed#336
CagdasErturk merged 4 commits into
mainfrom
import-golden

Conversation

@CagdasErturk

Copy link
Copy Markdown
Member

Every gate beside this crate asks whether a reader answeredOk or a named refusal, no panic, no read past the end. That is the right question for a corpus of hostile inputs, and it is nearly blind to a reader that answers confidently and wrongly. A document whose second primitive is dropped, whose node transform is not applied, or whose texture coordinates are shifted by one vertex answers perfectly well.

So one model is committed beside the exact bytes it reads to, and the comparison is byte for byte.

The model is generated rather than borrowed, and built to reach every layer at once: two primitives in one mesh, so the appending path runs and the second primitive's indices are shifted by the first's vertex count; a node with a translation, so positions arrive somewhere other than where the accessor put them; indices, so the indexed path runs rather than the implicit one; per-corner normals and texture coordinates, so the optional streams are present and the blob's present bitfield is not zero. It also carries a material, a texture and an image, which change no geometry at all — they are there so the golden proves they stay out of the canonical form.

Exact comparison is legitimate here, and the provenance file says why: the canonical form is little-endian f32 and u32 copied out of the document, with no arithmetic on a coordinate beyond the transform the document itself states. Nothing rounds, nothing reorders, and no platform spells an f32 differently in memory. That claim is what the comparison pins, and the day it stops being true — a reader that normalises, or averages, or reorders — is the day this gate earns its keep by failing.

Coordinates are compared by their bits for the same reason. A tolerance would absorb exactly the change this file exists to notice.

Refreshing it is one command rather than a ritual. A rendered golden needs a pinned adapter and candidates adopted by hand, because no two adapters rasterize alike. Any machine that runs cargo run -p renew-mesh --example make_import_golden reproduces these two files, so a diff after running it is a real change to what this crate reads.

Probed before it was called done, since a golden nobody has watched fail is a file rather than a gate: a bit flipped in the committed blob is caught by byte offset; the node transform removed from the source is caught twice, by the byte comparison and by the check that the golden is not vacuous; the second primitive dropped is caught twice, including by length. The tree returns to green after each.

Local gates: cargo fmt --all --check clean, cargo clippy --workspace --all-targets -D warnings zero errors and zero warnings, cargo test --workspace 265 suites with zero failures.

Every gate beside this crate asks whether a reader answered -- `Ok` or a
named refusal, no panic, no read past the end. That is the right question
for a corpus of hostile inputs and it is nearly blind to a reader that
answers confidently and wrongly. A document whose second primitive is
dropped, whose node transform is not applied, or whose texture
coordinates are shifted by one vertex answers perfectly well.

So one model is committed beside the exact bytes it reads to, and the
comparison is byte for byte.

The model is generated rather than borrowed, and built to reach every
layer at once: two primitives in one mesh, so the appending path runs and
the second primitive's indices are shifted by the first's vertex count; a
node with a translation, so positions arrive somewhere other than where
the accessor put them; indices, so the indexed path runs; per-corner
normals and texture coordinates, so the optional streams are present. It
also carries a material, a texture and an image, which change no geometry
at all -- they are there so the golden proves they stay out of the
canonical form.

Exact comparison is legitimate here and the provenance file says why: the
canonical form is little-endian f32 and u32 copied out of the document,
with no arithmetic on a coordinate beyond the transform the document
itself states. Nothing rounds, nothing reorders, and no platform spells
an f32 differently in memory. That claim is what the comparison pins, and
the day it stops being true is the day this gate earns its keep.

Coordinates are compared by their bits for the same reason. A tolerance
would absorb exactly the change this file exists to notice.

Refreshing it is one command rather than a ritual. A rendered golden
needs a pinned adapter and candidates adopted by hand, because no two
adapters rasterize alike; any machine that runs the generator reproduces
these two files, so a diff after running it is a real change to what this
crate reads.
The refresh command could make a broken reader green. Nothing held the
committed bytes to anything independent: the byte comparison held them to
what the reader produces now, and the generator writes the source and the
blob together, so both sides moved in step. A reader that started
attributing texture coordinates to the wrong corners failed, was fixed by
one documented command, and landed as a binary diff nobody can read.

This tree's own rule for its rendered goldens is that a golden can never
enter the tree through a passing run -- they write a candidate and fail
by design so a person looks. That ritual exists partly because no two
adapters rasterize alike, and partly so somebody sees what changed. Only
the first reason is absent here.

So the blob is decoded and every position, normal and texture coordinate
is asserted against values derived from the document by hand, with the
arithmetic written out to be checked rather than trusted.

The fixture could not see three things, and each was its own fault. Its
normals repeated within a primitive, so any permutation of them was a
no-op -- and the rest of the crate is blind the same way, using identical
normals in two other files. Its corner count and its stream bitfield were
both six, and those sit adjacent in the header, so swapping the two
fields left the bytes identical. Its indices were the identity
permutation, so the indexed and unindexed paths produced the same output.
It is now a triangle and a quad: nine corners, a distinct normal at every
one, and indices that reorder and repeat. Every value distinct wherever a
reader could confuse two -- a fixture whose values repeat cannot see a
permutation of them.

A node with only a translation left the inverse transpose at the
identity, so the arithmetic that carries normals was not exercised at
all. The node now scales as well, by exact powers of two.

The document states `min` and `max` on its position accessors because
the format requires them there. This reader ignores both, and a fixture
no independent validator would accept is worth less than one that would.

The sidecar carries a digest of the blob, as the other goldens' sidecars
do, and a test holds one to the other -- without it the sidecar describes
whatever the file used to be. The generator writes it, having previously
claimed to. And a `.gitattributes` rule keeps the committed source out of
line-ending translation, which was rewriting it on checkout.

The model itself moves to a shared file so the gate can hold the
committed document to the code that describes it, and the generator uses
the base64 encoder the other generators share rather than a sixth copy.

Also corrects several claims that were true of this fixture and stated as
facts about the reader: the path does multiply and add, the bytes travel
between machines because the format converts endianness explicitly rather
than because memory layout is universal, and the sibling suites already
assert values -- one of them catches a defect this golden does not.
This suite exercised the inverse transpose on face normals under a scale
and a rotation, and touched corner normals only under a translation --
where leaving them alone is the correct answer. So a reader that
transformed the face normals and copied the corner normals through
unchanged passed every test in the crate.

Three distinct corner normals through a non-uniform scale now, each
asserted: the inverse transpose halves x where the matrix doubles it,
which is the whole difference between transforming a normal and
transforming a direction.

The shared fixture beside it carried three copies of one normal, so any
permutation of them was a no-op. Three different ones, for the same
reason the assertions above exist: a fixture whose values repeat cannot
see a reader that reorders them.
…th artifacts

Three comparisons in this file compared whole values with `assert_eq!`,
which prints both sides. One byte's disagreement in a megabyte artifact
buys nine megabytes of log that says nothing the offset does not -- and
the file's own comment beside the fourth comparison already forbade it.
This crate's tests run in every removability cell that keeps it, so that
log is paid over and over rather than once.

One helper, used by all of them: it names the first byte that differs, or
the two lengths when every shared byte agrees.

Also corrects two sentences that were true of the fixture before it grew
a scale, and are the stated reason the comparison can be exact. The node
states a translation and a scale, both exact powers of two -- the file
contradicted itself about this, since the note beside its coordinate
comparison already said so. And every accessor the document reads a
coordinate through is componentType 5126, but not every accessor: the two
index accessors are 5123, and an index selects rather than computes.
@CagdasErturk
CagdasErturk merged commit 913c885 into main Sep 9, 2026
31 checks passed
@CagdasErturk
CagdasErturk deleted the import-golden branch September 9, 2026 17:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant