Benchmarks / CPU and I/O (per commit) (push) Successful in 2m52s
Benchmarks / Frame budget (on demand) (push) Skipped
Build and test / Desktop (Linux) (push) Failing after 56s
Build and test / Layer separation (push) Successful in 37s
🐳 Android image / Build and push (push) Successful in 4s
Build and test / android-image (push) Successful in 4s
Traceability / Requirement traces (push) Failing after 54s
Build and test / Android (aarch64) (push) Successful in 26m29s
A node that has just been declared can be read, reasoned about and tested, and none of that answers the question a photographer asks first: what does moving this do to the picture. Colour grading, dehaze and the range masks were all argued into the tree on their behaviour and none of them had been *looked* at. So two diagnostics. `sweep` walks one operation from its minimum to its maximum and writes a frame per step; `rangesweep` does the same for a mask band, which is not an ordinary parameter — it lives on a layer, is rasterised by its own pass, and only becomes visible through whatever adjustment the layer carries, so it gets two stops down to make the selection legible. `sweep` names no operation. The id arrives as a string and the parameters and their ranges come from the graph's own capabilities, so a node declared yesterday sweeps on the same terms as one that shipped a year ago — the property `ops/README.md` promises, used rather than asserted. Three things it learned the hard way and now records. It renders through `render_detailed` unconditionally, because the fused path refuses a shader composed with a detail stage rather than rendering it wrongly, and that call falls through when there is no such stage. It takes `SWEEP_HOLD`, because a parameter grouped under one widget is not meaningful alone: a hue with no strength behind it renders the same frame every time, which reads as a broken node rather than a correctly declared neutral. And it bounds the output, since a 25 MP frame is a 75 MB PPM and a sweep is hundreds of them. Both read a rendered file as readily as a raw one, so a JPEG can stand in where no raw is to hand — on the terms `from_rgba8` documents, with the controls still working and their neutral being what the camera left rather than what the sensor recorded.