The research came first, and it argued against the obvious product. A long study of what a phone camera can honestly be asked to do — rolling shutter skewing a fast ball, automatic exposure and lens switching making a fixed court appear to move, and the plain arithmetic that 4K at 120 frames a second is close to a billion captured pixels every second — did not conclude that any of this was impossible. It concluded that one product promising the same accuracy on every phone and every sport would be a lie.
So the first thing built was the part that can be finished honestly: the scorekeeper. The engine is event-sourced and append-only, undo is implemented as another event rather than a deletion, and the score is always recomputed by folding the whole log. Four rule packs sit on top of it, each shipping with a recorded match that CI replays call by call, so changing a scoring rule breaks a test rather than a game.
The camera does the geometry it can prove, and nothing else. Four-corner calibration is a hand-written direct linear transform, unit-tested against synthetic camera poses, and its entire design argument is the failure path — a bad corner set is rejected with one of seven named reasons, and until the solve succeeds the button that starts scoring is not on the screen.
What is deliberately absent is the detector. There is no machine-learning dependency in the app at all, and the database will not even accept a camera-assisted event. The three-outcome evidence contract — confirmed, probable, not enough evidence — is fully designed and fully tested and connected to nothing, because the honest order is to build the thing that decides before shipping the screen that reports it.
The one live AI surface is the rules companion, and everything expensive about it belongs to the server. The client cannot choose the model, the ceilings, the tools or the prompt; the gateway substitutes its own before it counts a token, every call reserves its worst case before it dispatches, and the whole surface fails closed if a single control document goes missing.