ProjectionMapper Native 0.96.6 - Built by Instinct =================================================== Capture-hardening hotfix. An independent source review of 0.96.5 found that the scan's "waits for the exact pattern + a fresh frame" claim was only half wired: acks were stamped at composite time (not at real paint), the token and the pixels could update in separate locks, preflight and the phase-refinement pass bypassed the token gate entirely, and scan diagnostics were never saved. 0.96.6 fixes all nine findings. Scans are not worse than 0.96.5 was - they are now actually as good as 0.96.5 claimed. NEW - Atomic pattern tokens: every pattern commit replaces the WHOLE overlay state in one lock - a leftover fiducial, focus pattern, or plane from a previous step can never bleed into the next pattern, and ordinary show pixels never carry a pattern token. - Real paint acks: a pattern counts as shown only when the projector window actually paints it - a checked, successful blit on the projector HWND (a minimized window, an empty frame, or a failed blit means NO ack). A missing or dead projector window now stops the scan honestly instead of feeding stale frames into the decode. - Freshness keyed to paint time: camera frames are judged fresh relative to the confirmed paint, and the camera frame counter at the ack is recorded. - Capped retry, honest abort: each pattern is presented up to 3 times. If it never paints, the scan STOPS with a clear message - nothing is saved and your previous scan and calibration stay untouched. - Phase refinement, preflight, Verify, and dot calibration all go through the same paint-ack gate as the main scan (they bypassed it before). If the projector stops painting, Verify says so and calibration stops with nothing changed. Phase tokens record their true generator frequency and phase. - Scan diagnostics persist: every scan session (preflight, main pass, fine pass; completed, stopped, or camera lost) writes one native-maps/diags/scan-.json with per-pattern paint timing, retries, the camera frames used, and whether exposure had settled; the last 5 are kept. - Preflight: player state is snapshot under lock, a preflight override logs that the scan is an UNVERIFIED experiment until Verify passes, and mask mismatches log loudly instead of being silently dropped. STILL TRUE - Geometry precedence: phone-scan .glb (metric) > Gray-code scan (pixel address) > DA3 monocular prior (relative). Invalid pixels are never smoothed or invented; scan holes show DARK. - Calibration, Verify, adaptive settle, double-pass merge, mirror exclusion from preflight stats, and the 0.96.5 sidebar/dropdown and show-guard fixes are unchanged in behavior. TESTED (linux suite, synthetic harness - 80+ test files; windows build + vet) - Stale, duplicate, and wrong-pattern acks are REJECTED and the scan aborts. - Stale overlay state can never leak into a pattern; abort restores the show. - Minimized/zero-size/failed paints never produce an ack. - Retry-then-succeed completes with per-attempt diagnostics. - A real paint delayed ~80 ms is waited out; freshness keys off the paint time, not the request time. - Zero paints (no projector window) aborts the scan with nothing saved. - A wrong phase step does not satisfy the phase ack gate. - Diagnostics persist for completed and aborted runs. UNTESTED - Real hardware: the whole ack path is exercised against scripted fakes, not yet against your projector + webcam. The first live scan on 0.96.6 is the real test - if a scan stops with a paint-timeout message, that is the new honesty working, not a new bug; check the projector window is open on the projector display and re-run. Run Verify after your first 0.96.6 scan to confirm the geometry on your rig. KNOWN LIMITS (honesty section - follow-ups queued for 0.96.7, none block) - The diagnostics "aborted" flag is inferred from how far the scan got, not the final outcome - a stop after the main pass (cancel, camera lost, failed save) can be labeled "completed". - Diagnostics record the camera frame-counter RANGE used per capture, not an exact list of accepted frames. The camera counter at a paint can reflect a later repaint of the same pattern. - Camera timestamps are host receipt times, not the sensor's exposure times. Exposure/driver-lag validation is an on-rig item; nothing here claims proven exact exposure timing. - Preflight judges the whole view minus exclusions, not the exact target surface; overriding it remains an unverified experiment. - Switching the open project mid-scan is not yet guarded (pre-existing). - Windows vet shows pre-existing unsafe.Pointer notes in camera.go/mfcam.go; 0.96.6 adds no new warnings.