Tap anywhere, then tap three dots that appear one after another. The page never knows where they are: the server draws them, times you on its own clock, and signs what it saw.
The earlier gates had two structural holes against a client that reads the page and waits: it could read the dot's position from page state, and it reported its own timestamps. This version closes both without adding any friction. The "server" here is a Web Worker so the whole protocol runs in one file; in deployment it is the download endpoint.
SHA-256(secret ‖ challenge ‖ "dot k" ‖ opener ‖ tap₁ … tap_{k−1}), computed by the server from a secret the client never sees, placed relative to the previous landing. The server draws the dot itself on an OffscreenCanvas it controls. No page-side variable ever holds the real position; the client only learns a dot's position after it has been hit, to draw history.HMAC(secret, transcript ‖ its times), which only it can verify. That is correct: the verifier of a download gate is the server.A client that locates the dot by looking: a screenshot and a centroid, or a vision model, per dot. The "Vision bot" simulation is that client (it asks the server for the position, which is what a screenshot pipeline recovers), waiting a plausible interval with plausible dynamics. It passes the gate. The cost it carries is real seconds per dot on the server's clock, CPU-seconds of work per attempt, and a per-session feature vector the server can compare across sessions: a fleet of such bots is drawn from one generator and clusters, while people do not. For a book download that is the right economics: the scrape costs more than the book.
SHA-256(challenge ‖ opener ‖ taps ‖ contacts) equals the seed, candidate rederives, p and 2p+1 prime, and the gate recomputed against the dots the bundle claims.