Open product questions
Questions found while consolidating the specs (2026-10-11). The specs describe what the code does today. Where the code looks wrong, the spec lists it under Known deviations. These questions need a product decision first.
When a question is decided: change the code and the spec (/spec-update, /port-change), then delete the row. This file lists only open decisions, not finished work.
Security and data (decide first)
| # |
Question |
Spec |
| S1 |
Pairing takeover: anyone who knows a paired device's device_uid gets a working token on the next poll, without a code. Fix: a new pairing request makes the device pending until the code is entered. |
device-api |
| S3 |
Unpair on the watch is local only. The watch side is settled (privacy.md): tracks stay on the watch and nothing is sent after unpair (only after a new consent and pairing). Open: should the watch call POST /devices/unpair on the server (relevant for the SDK)? |
sync-and-pairing |
| S4 |
/api/v1/tracks/upload is used by no client, has no size or rate limit and returns internal errors. Remove it, or harden it? |
api |
| S5 |
Privacy page claims Google Analytics (there is none yet; kept until analytics is added). |
public-site |
| # |
Question |
Spec |
| W1 |
One action menu / Controls order for all platforms? Proposal: Pause, Stop, Stats, Vessel state, [Touch lock], Discard (destructive last). |
menus, parity P5 |
| W2 |
Nautical-mile unit: nM (dashboard), nm (menus, tile) or NM (stats, web)? One spelling everywhere. |
visual-system |
| W3 |
Clock format: Dashboard 9:05, Environment 09:05; neither honours the 12 h setting (nor does the Wear OS ambient clock); the Garmin pause view does. |
dashboard, environment |
| W4 |
Track line colour: drawn in the current vessel state's colour. Keep the colour each stretch was recorded in? Mark the turn where it happened instead of the newest two segments? |
track-view |
| W5 |
Float alert repeats every 15 s while it holds and fires in Adrift. Once per state? Exclude Adrift? |
alerts |
| W6 |
Baro alert window compares the oldest and newest buffered sample (30 min – 6 h), but says "3 h". Use a true 3 h window like the server? |
alerts, calculations |
| W7 |
State period: duration counts paused time and restarts after an app restart; the average is a mean of SOG samples, not distance / time. Align with the other values? |
recording |
| W8 |
Day totals are computed and stored but shown nowhere. Show them on the stats screen, or remove them? |
recording |
| W9 |
Position without a fix shows 0°00.000'N 0°00.000'E. Use a placeholder? Passed tides stay visible: hide them? Persist tides across restarts? |
environment |
| W10 |
Pairing code expiry (410) and the server's poll interval are ignored; polling every 5 s never stops. Honour both? |
sync-and-pairing |
| W11 |
A file that always gets 400 / 413 blocks the queue for good. Delete it or move it aside? |
track-sync |
| W12 |
app_version is sent as the fixed value 2. Send the real release version? In what format? |
track-sync |
| W13 |
Discarding a trip's only track leaves an empty trip ("Continue trip — 0 tracks"). Drop the trip too? |
lifecycle |
| W14 |
Battery gauge on the dashboard is empty below about 15 %. Make it proportional and add a low colour? |
dashboard |
Garmin
| # |
Question |
Spec |
| G2 |
Closing the app while recording ends and books the track silently, with no upload. Treat it like a pause? |
lifecycle |
| G3 |
PAUSED on the dashboard timer shows boxes, because the numerals font has no letters. Add the glyphs, use a system font, or drop the branch? |
dashboard |
Wear OS
| # |
Question |
Spec |
| A2 |
Watches without a barometer show -- hPa. Hide the row and the baro alert instead? |
environment |
| A3 |
Alerts in ambient (Wear OS system ambient mode only): they vibrate, but the overlay isn't drawn. The app's own low-power layout already wakes for alerts. Wake the screen from system ambient too? |
live-surfaces |
| A4 |
Backup recording (Health Services exercise) for when the SLTB queue is full: needed? |
parity P7 |
| A5 |
device_uid changes on reinstall, so the server counts the same watch twice. Accept? |
device-api |
DataField
| # |
Question |
Spec |
| D1 |
Storm warning: the website, store copy and films promise one; the code only has a trend arrow, which also turns red for a strong rise. Add the 1.5 hPa / 3 h rule, or change the copy? |
datafield screen |
| D2 |
Speed curve covers 160 s, the copy says 3 minutes. Change the code or the copy? |
datafield screen |
| D3 |
Smaller slots don't work (1-field layout only), but the website says "works next to your other data fields". Support them, or change the copy? |
datafield screen |
| D4 |
Honour the activity's dark background and the 12 h clock? |
datafield screen |
| D5 |
Is the published 1.2.1 build the one with GPS-only COG and 5 s smoothing (committed after the release commit)? If not, release 1.2.2. |
datafield |
Server
| # |
Question |
Spec |
| R1 |
Sailing time and distance include stationary states (anchor, adrift) on the server, unlike the watch and the glossary. Exclude them? |
calculations, ingestion |
| R3 |
Email links expire after 30 min (new-trip email, beta invitation), because they use the sign-in token. Use a longer-lived link? |
emails |
| R4 |
Average and max speed are defined differently on the watch, the DataField and the logbook. Align them? |
calculations |
| R5 |
Empty trips: a discarded watch track, or deleting a trip's last track on the web, leaves an empty trip (moving a track away deletes it). Delete empty trips consistently? Device deletion drops raw segments, so its tracks can't be rebuilt. Keep the segments? |
ingestion, data-model |
| R6 |
Public site says SailEver is Garmin-only and promises trip sharing (link / QR); sharing doesn't work yet and Wear OS exists. Update the copy, or build sharing? |
public-site |
Phone apps
The phone app questions (live link from the watch, user API, sign-in, sharing, purchases, offline use, Health integration, …) are listed in mobile/README.md under Open questions, since all of the phone app is still ⏳.