Revise Surface plan per audit: near-vertical spec, calibration guards, shared settling, pure guidance mapping (Codex)

This commit is contained in:
Jay
2026-07-13 11:52:52 -04:00
parent abff397364
commit 0c197894ff
+60 -26
View File
@@ -1,6 +1,6 @@
# Surface Level — Implementation Attack Plan
**Status:** Proposed; send to Claude for audit before implementation.
**Status:** Audited; ready for implementation after this revision.
**Scope:** Surface Level only. Do not change Angle, Edge, ruler, or billing in this stage.
## Outcome
@@ -28,8 +28,13 @@ The user should be able to answer three questions at a glance or by sound:
- Surface means the phone is intended to lie flat, screen-up, on the plane being
measured. Its level-lock behavior is valid only in that geometry.
- Numeric measurements are never hidden because the phone is steeply oriented.
Outside the ideal Surface geometry, show the actual angle and a quiet placement
Surface tilt magnitude remains authoritative from 0 to 180 degrees. Outside
the ideal face-up geometry, show the actual magnitude and a quiet placement
hint; suppress level-lock feedback rather than replacing the reading with `—`.
- Above 80 degrees of tilt, de-emphasize/suppress Pitch and Roll because their
off-axis parameterization becomes noisy near vertical. Above 90 degrees,
identify the screen-down-side state rather than pretending the bullseye is a
useful placement tool. The magnitude remains visible in both cases.
- The central visualization is a bullseye vial. It has a finite visual range:
beyond that range the bubble rests at the rim, while numeric information remains
full-range and authoritative.
@@ -42,20 +47,30 @@ The user should be able to answer three questions at a glance or by sound:
- Refactor Surface placement gating so it only controls the level-lock state,
lock haptic, and geometry-specific guidance.
- Keep primary angle, pitch, and roll visible at 0-90 degrees.
- Add tests at flat, near level, 30 degrees, and near vertical proving numeric
readings remain present and correct; verify invalid placement never locks.
- Keep the primary tilt magnitude visible from 0-180 degrees. Keep Pitch and
Roll visible only where their meaning is stable (below 80 degrees tilt).
- Add tests at flat, near level, 30 degrees, 80 degrees, near vertical, and
screen-down. Verify magnitude stays correct, off-axis values are suppressed
in their ambiguous range, and invalid placement never locks.
- Keep the existing lock tolerance semantics: a lock label states the tolerance
rather than pretending any non-zero value is exactly flat.
### 2. Add the guided Surface calibration flow
- Add a Surface Calibration route from the Level header.
- Explain that the phone may be calibrated on any firm, stable surface; the
surface itself does not need to be level.
- Step 1: settle, sample for a short stable window, capture.
- Step 2: rotate the phone exactly 180 degrees in the same plane, settle, capture.
- Reject/retry if readings indicate motion or inconsistent placement.
- Explain that the phone may be calibrated on any firm, stable, *roughly level*
surface; it need not be perfectly level. Warn and ask for a flatter surface
when the measured tilt exceeds 5 degrees.
- Capture the two samples from the uncalibrated sensor path. Never derive a new
calibration from readings that an existing calibration has already corrected.
- Step 1: settle, collect a 1.5-second stable window, capture.
- Step 2: rotate the phone exactly 180 degrees in the same plane, settle, then
collect and capture another 1.5-second stable window.
- Use the shared settling detector: enter Settling above 1.0 degrees/second of
two-axis plane movement; leave it only after movement is at or below 0.3
degrees/second for 500 ms. Reject/retry windows that are not settled.
- Reject/retry a derived calibration bias above 3 degrees as evidence that the
device, setup, or turn was inconsistent. Suppress lock feedback during the flow.
- Persist only the resulting Surface calibration; never alter Edge calibration.
- State that the calibration applies to the current phone/case/contact setup.
- On completion, show a concise success result and a way to clear/re-run it.
@@ -67,10 +82,19 @@ The user should be able to answer three questions at a glance or by sound:
- Glass, fluid, and meniscus effects must improve depth/readability; avoid a
decorative or excessively glossy treatment.
- Bubble target position derives directly from stable calibrated pitch/roll.
- Bubble movement uses a critically damped animation toward that real target:
no random drift, autonomous wobble, or animation that contradicts the number.
- Derive bubble target, high/low instruction, and rise/run direction from one
pure SurfaceGuidance function. Its hysteretic next-state input must prevent
quadrant labels from flapping at an axis boundary. Use an edge label when the
minor axis is under 25% of the dominant axis; otherwise use a corner label.
- Bubble movement uses a critically damped spring (damping ratio >= 1) toward
that real target: no overshoot, random drift, autonomous wobble, or animation
that contradicts the number. Clamp the target to the vial's visual range before
applying the spring so the bubble settles at the rim.
- Etched rings are real visual calibration marks, not decoration: map them to
explicit degree values (initially 1, 2, and 5 degrees) using the same pure
measurement-to-position mapping as the bubble.
- Respect disabled system animations and the app's reduced-motion preference by
minimizing or removing the display spring.
direct-positioning the deadbanded bubble value instead of running the spring.
- Show a large total tilt beside/below the vial, then Pitch and Roll below it.
- At level lock, use the restrained lime state and an explicit text label.
@@ -82,32 +106,42 @@ The user should be able to answer three questions at a glance or by sound:
millimetres per metre and/or inches per foot based on the selected unit system.
- Treat exact board/counter dimensions and calculated shim/foot height as a later
Adjustment Assist feature, not a requirement of this stage.
- When the reading is moving, show a subtle `Settling` state and defer strong
correction guidance until the stable measurement is trustworthy.
- Use the shared settling detector from calibration. When it is settling, show a
subtle `Settling` state and defer strong correction guidance until the stable
measurement is trustworthy.
- Add a persisted units preference in core/settings for rise/run formatting;
the Tools settings UI remains deferred.
### 5. Add optional hands-free Audio Level Assist
- Surface-only, off by default, explicitly user-enabled.
- Use a soft sonar-like pulse with a gentle attack and naturally fading tail;
never a harsh alarm or rapid smoke-detector cadence.
- Silent while settling or materially outside the usable placement geometry.
- Near level: occasional low-key proximity pulses.
- Silent while the shared settling detector is active or materially outside the
usable placement geometry.
- Near level: occasional low-key proximity pulses with hysteresis between audio
proximity bands, so band changes cannot chatter.
- Locked: one distinct soft lock ping; optionally provide a sparse repeat-while-
locked preference so a user adjusting a large plank can hear that it remains level.
- Reuse the existing lock dwell/hysteresis/debounce so sound cannot chatter.
- Respect media volume, audio focus, system sound settings, app lifecycle, and
the user's Audio Assist preference.
- Use SoundPool with `USAGE_ASSISTANCE_SONIFICATION`; mix with media rather than
taking audio focus for intermittent pulses. Respect media volume, system sound
settings, app lifecycle, and the user's Audio Assist preference. Release audio
resources with the tool composable/flow collection.
## Surface acceptance criteria
- A stable phone on a known level plane achieves lock without repeated feedback.
- A 180-degree calibration on a stable but non-level plane improves repeatability
without zeroing that plane's real slope.
- A screen-up phone at 30 and near 90 degrees still shows meaningful numbers;
it does not falsely claim Surface lock.
- Bubble direction agrees with Pitch/Roll and with the high/low instruction.
- Bubble visual remains physically believable but never leads or disagrees with
the stable numeric reading.
- A 180-degree calibration from uncalibrated stable samples on a stable,
roughly-level plane improves repeatability without zeroing that plane's real
slope; inconsistent/moving captures are rejected.
- A screen-up phone at 30, 80, near 90, and screen-down angles always shows a
correct magnitude. Pitch/Roll are suppressed at their documented ambiguous
range, and the Surface tool never falsely claims a lock.
- Bubble direction, high/low instruction, and rise/run direction agree in all
four quadrants through one pure, unit-tested guidance function.
- Bubble position is a pure mapping of stable measurement plus a no-overshoot
spring. Its etched rings match that mapping's documented degree marks.
- Audio can guide a user to lock without viewing the screen and stays quiet when
disabled, settling, backgrounded, or outside the Surface geometry.
- Manual checks cover phone-with-case, phone-without-case, a firm tabletop, and