an.bench.contract#
scene_contract_sha256: the fact that decides whether two rows are comparable.
Two ledger rows measured on different scenes are not “one better and one
worse” — every metric in them is uninterpretable relative to the other.
edge_transition_width’s own docstring says so: the absolute value is
scene-dependent, because a deliberately 3px black outline is legitimately
non-flat.
So each row carries a hash of the thing that was actually rendered. Deliberately a hash of the staged compiled scene, not of the project directory: the directory carries scene mtimes and a decisions log that move on every load, and hashing it would make every row incomparable with every other for reasons that never reached a pixel.
Functions
|
Top-level entities under the synthetic root. |
|
Every node in the tree, root included. |
|
|
|
A stable digest of what was rendered. |
|
The contract digest for a whole scene, across every shot in timeline order. |
- an.bench.contract.count_drawable_entities(scene_json)[source]#
Top-level entities under the synthetic root.
Named for what it counts. “n_entities” is ambiguous in this codebase — the IR’s
shot.entitiesincludesvoicerefs that configure the render rather than appearing in it, so the two numbers differ on every scene with dialogue. Both are recorded; only this one is inside the hash.- Return type:
>>> count_drawable_entities({"scene": {"children": [{}, {}]}}) 2
- an.bench.contract.count_nodes(scene_json)[source]#
Every node in the tree, root included.
- Return type:
>>> count_nodes({"scene": {"children": [{"children": [{}]}]}}) 3
- an.bench.contract.frames_sha256(frame_paths)[source]#
sha256over the DECODED pixels of a frame sequence, never file bytes.The gate for
encode_flicker_on_held_pixels: without it, half-res-then- nearest-upscale — the most visible possible flat-art regression — reports a 7.1x improvement, because a flattened render gives x264 large uniform skip regions.Decoded, not file bytes, for the reason the cross-architecture verdict records: Chromium 1187 -> 1223 changes 144/144 PNG files and zero pixels, so a file-byte digest goes red on the first Playwright bump for a reason unrelated to animation quality.
- Return type:
- an.bench.contract.scene_contract_sha256(scene_json)[source]#
A stable digest of what was rendered.
Hashed over a reduced form rather than the whole document, and the reduction is the point: the digest must move when the picture’s contract moves and stay put otherwise. Animation keyframe floats and asset paths are in; nothing time- or machine-dependent is, because the compiled scene is already free of both (every escaping set goes through
sorted(), the palette hash issum(ord(c)) % 5rather than Python’shash(), and the staged JSON is written withsort_keys=True).- Return type:
>>> a = scene_contract_sha256({"meta": {"fps": 24}, "scene": {"children": []}}) >>> a == scene_contract_sha256({"scene": {"children": []}, "meta": {"fps": 24}}) True >>> len(a) 64
- an.bench.contract.scenes_contract_sha256(scene_jsons)[source]#
The contract digest for a whole scene, across every shot in timeline order.
A single-shot scene returns exactly
scene_contract_sha256()of its one staged scene, so every row written before the corpus grew a multi-shot fixture stays comparable —an bench --comparerefuses rows whose contract hash differs, and a gratuitous change here would retire the only committed row as evidence.A multi-shot scene hashes the ordered list of per-shot digests, because hashing only the first shot would let a change to the second one pass as “the same scene” — which is precisely the claim this digest exists to deny.
- Return type:
>>> a = {"scene": {"children": []}} >>> scenes_contract_sha256([a]) == scene_contract_sha256(a) True >>> scenes_contract_sha256([a, a]) == scene_contract_sha256(a) False