Add Surface Level attack plan (Codex) and Gradle daemon JVM pin
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
# Surface Level — Implementation Attack Plan
|
||||
|
||||
**Status:** Proposed; send to Claude for audit before implementation.
|
||||
**Scope:** Surface Level only. Do not change Angle, Edge, ruler, or billing in this stage.
|
||||
|
||||
## Outcome
|
||||
|
||||
Build a trustworthy two-axis surface-level tool for a phone lying flat,
|
||||
screen-up, on a surface. It must feel like a physical bullseye vial while
|
||||
giving clearer, more actionable information than a physical level.
|
||||
|
||||
The user should be able to answer three questions at a glance or by sound:
|
||||
|
||||
1. Is this surface level?
|
||||
2. How far off is it?
|
||||
3. Which side/corner needs adjustment, and by roughly how much?
|
||||
|
||||
## Existing foundation to preserve
|
||||
|
||||
- Unified device-frame world-up sensor contract.
|
||||
- Raw sensor -> stable measurement -> animated display separation.
|
||||
- Vector-space Surface calibration model and two-sample calibration math.
|
||||
- EMA smoothing, lock hysteresis/dwell/debounce, deadband, and current tests.
|
||||
- The current numeric Surface reading, pitch/roll values, and haptic lock hook.
|
||||
|
||||
## Product decisions to implement
|
||||
|
||||
- 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
|
||||
hint; suppress level-lock feedback rather than replacing the reading with `—`.
|
||||
- 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.
|
||||
- Calibration corrects device/setup bias. It is not "make this desk level."
|
||||
A later relative-reference feature is separate and out of scope here.
|
||||
|
||||
## Work sequence
|
||||
|
||||
### 1. Make measurement behavior honest at every angle
|
||||
|
||||
- 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 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.
|
||||
- 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.
|
||||
|
||||
### 3. Build the tactile bullseye instrument
|
||||
|
||||
- Use Compose Canvas (or an equivalent composable drawing layer) for a scalable
|
||||
circular vial, etched rings, crosshairs, target zone, and bubble.
|
||||
- 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.
|
||||
- Respect disabled system animations and the app's reduced-motion preference by
|
||||
minimizing or removing the display 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.
|
||||
|
||||
### 4. Add actionable adjustment information
|
||||
|
||||
- Derive a screen-relative high/low direction from calibrated Pitch and Roll.
|
||||
Use language such as `High: lower-left`; do not claim a compass direction.
|
||||
- Display slope as both degrees and a useful normalized rise/run value:
|
||||
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.
|
||||
|
||||
### 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.
|
||||
- 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.
|
||||
|
||||
## 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.
|
||||
- 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
|
||||
a large board adjusted by one person.
|
||||
|
||||
## Explicitly deferred
|
||||
|
||||
- Angle-screen redesign and signed relative-angle semantics.
|
||||
- Edge/Plumb visual and geometry changes.
|
||||
- Saved measurements, target-angle alerts, screen ruler, and Play Billing.
|
||||
- Board dimension/shim calculator and automatic flat/edge switching.
|
||||
|
||||
## Questions for Claude's audit
|
||||
|
||||
1. Does the relaxed placement gate preserve truthful full-range Surface numbers
|
||||
while preventing false lock feedback?
|
||||
2. Is the two-sample calibration flow mathematically and UX-wise safe for the
|
||||
stated use case, including phone cases and non-level calibration surfaces?
|
||||
3. Is high/low mapping unambiguous and testable for all pitch/roll quadrants?
|
||||
4. Does the bullseye animation remain derived from measurement truth and respect
|
||||
reduced-motion/system-animation settings?
|
||||
5. Can the audio state machine reuse lock semantics without audio-focus,
|
||||
lifecycle, or repeated-feedback problems?
|
||||
6. Is any proposed work outside this single-stage scope?
|
||||
@@ -0,0 +1,12 @@
|
||||
#This file is generated by updateDaemonJvm
|
||||
toolchainUrl.FREE_BSD.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
|
||||
toolchainUrl.FREE_BSD.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
|
||||
toolchainUrl.LINUX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
|
||||
toolchainUrl.LINUX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
|
||||
toolchainUrl.MAC_OS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/73bcfb608d1fde9fb62e462f834a3299/redirect
|
||||
toolchainUrl.MAC_OS.X86_64=https\://api.foojay.io/disco/v3.0/ids/846ee0d876d26a26f37aa1ce8de73224/redirect
|
||||
toolchainUrl.UNIX.AARCH64=https\://api.foojay.io/disco/v3.0/ids/ec7520a1e057cd116f9544c42142a16b/redirect
|
||||
toolchainUrl.UNIX.X86_64=https\://api.foojay.io/disco/v3.0/ids/4c4f879899012ff0a8b2e2117df03b0e/redirect
|
||||
toolchainUrl.WINDOWS.AARCH64=https\://api.foojay.io/disco/v3.0/ids/9482ddec596298c84656d31d16652665/redirect
|
||||
toolchainUrl.WINDOWS.X86_64=https\://api.foojay.io/disco/v3.0/ids/39701d92e1756bb2f141eb67cd4c660e/redirect
|
||||
toolchainVersion=21
|
||||
Reference in New Issue
Block a user