Skip to content

📦 WP-149 — test(data): frozen expectations and the augmentation-invariants golden

Engineering log · Phase 13 — Contributor admission, augmentation guard and keypoint parity, v0.6.0

🔗 Depends on WP-148 · Needed by WP-150

⬅️ WP-148 · Roadmap · WP-150 ➡️

WP-149 — what a frozen value is allowed to mean

The guard's third tier is the one that pins rather than proves, and the discipline it needs is entirely about honesty. tests/data/test_aug_frozen.py holds nine cases, each stating explicit parameters, asserting a literal, and naming in its own docstring why no closed form was available. Where a closed form does exist the case is not here — it is in WP-148's contract file, and every case that could be moved there was.

The tier-A/tier-B boundary is a real line, not a filing preference. A rotation is a similarity: it maps a rectangle to a rectangle, so a rotated box re-fits exactly and its expectation is derivable, which is why the quarter-turn rbox case sits in tier A. A shear is not: it maps the rectangle to a parallelogram, and the re-fit is then a choice of enclosing rectangle rather than a recovery of the original. That choice is the implementation's, which makes the sheared case tier B and the rotated case tier A, from what looks like the same operation on the same modality. The letterbox split is the same shape of argument in a different place: the ratio and the padding total are arithmetic, but a leftover of seven and a half rows resolving to an offset of three rather than three and three quarters is a convention, and conventions are pinned rather than derived.

A tier-B docstring that cannot name its reason is a tier-A case in the wrong file. Writing the reasons out caught three candidates and removed them: a mixup blend at a stated factor on constant images is arithmetic, a ring clipped against a canvas edge is a clip, and a mirrored rotated box is a reflection with a negated angle. All three were computed, found derivable, and either moved to tier A or dropped. What survived is a composite affine's boxes and ring, a fused affine-and-letterbox, an off-centre mosaic where the clip meets the instance filter, a hue rotation across an RGB sector boundary, a sheared rbox, keypoints through a flip-pair swap composed with the warp, an odd letterbox split, and a rasterised triangle.

The triangle case carries its own arithmetic as a witness. The ring (2,2)-(10,3)-(6,11) has a shoelace area of exactly 34 and rasterises to 32 pixels. Neither number derives the other — the gap is the boundary rule, resolved one row at a time against the pixel grid — but writing both down means a reader can see the frozen count is close to the area rather than merely take it on trust, and a future failure at, say, 41 is obviously wrong rather than merely different.

goldens/aug_invariants.json takes what a literal would express badly. Fifteen scalar aggregates over the same stated-parameter runs: surviving instance counts and written pixel counts pinned exactly, image means and polygon areas pinned within a band. The split follows what each store is good at — the golden harness compares dict[str, float], so a box array flattened into box_0_x1-style keys would be a worse version of a pytest literal, while an image mean sitting in a test file would be a number with no tolerance and no home. Image expectations stay aggregate on purpose: the upstream engine samples at a different half-pixel convention, may execute through a different backend, and collapses several warps into one resample, so a byte-exact pixel expectation would fail at swap time for a correct implementation and the only escape would be a re-freeze under swap pressure.

Golden discovery was verified positively, not inferred. WP-139's lesson is that the harness globs, so it cannot notice a golden that was never written; a green run therefore proves nothing about a file's presence. check_goldens.py was run directly and printed PASS aug_invariants.json — 15 metric(s) and 31/31, up from 30. That is the check, not the green gate around it.

tests/data/test_aug_seam.py is deleted here as WP-147 said it would be. It existed to witness that __call__ equals sample() then apply() while the frozen tiers did not yet exist; now that tiers A, B and C all call apply with stated parameters, the seam is exercised by every case in all three files, and a witness that outlived its gap would just be a slower way of asserting the same thing.