Build image / build-and-push (push) Successful in 7s
- hexCenters now derives its exact point count BEFORE building anything and returns it alongside the points, refusing over the cap without allocating. Previously it materialised the whole lattice and fillLoaded checked len() afterwards — so the "too large" path paid for the thing it was rejecting. This also makes the preallocation exact, which subsumes the earlier over-allocation finding I'd declined: staggered rows hold cols-1, so rows*cols over-reserved by ~12%. - Region.empty() names the invariant that clampTo expresses "no overlap" by INVERTING the region rather than zeroing it. A bare `MaxX < MinX` at each call site was spreading a non-obvious convention across three functions. The count is now load-bearing (it gates the cap), so the test asserts it matches what actually gets built. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]> Claude-Session: https://claude.ai/code/session_01H3zbym8Doka2d7D48maSgZ