Skip to content

fix(Where): recognize flights and wait for arrival before GPS corrections - #315

Open
kyleve wants to merge 11 commits into
mainfrom
codex/flight-review-corrections
Open

kyleve wants to merge 11 commits into
mainfrom
codex/flight-review-corrections

Conversation

@kyleve

@kyleve kyleve commented Sep 14, 2026 •

Copy link
Copy Markdown
Owner

Summary

Where could mistake places recorded during a flight for GPS drift and offer a whole-day correction that hid later destinations. This change recognizes sustained flight movement per recording device, waits for GPS evidence of arrival, and reviews exact sample edits while preserving raw observations and later visits.

Locations and correction screens share localized flight status. Pending flights stay accessible without actionable badges or correction notifications, and manual day editing remains available.

Why

Flight classification, arrival confidence, and correction availability need to use the same raw evidence. An elapsed timeout, missing updates, restart, or midnight cannot establish landing. GPS remains the baseline for older recordings; valid speed and altitude measurements add context.

Review focus

  • Later flights, including supported takeoff transitions, keep their observations separate from older pending flights. Missing arrival evidence on an earlier trip cannot block corrections for a later completed trip.
  • Dismissing an actionable GPS suggestion removes its ready review and live notice from the shared scan. Pending and completed informational reviews remain accessible, and dismissal does not revive overlapping whole-day suggestions.
  • The pure trajectory analyzer distinguishes sustained flight, supported approach, ground dwell, and unknown observations without joining devices. Endpoints of disconnected flight segments preserve uncertain layovers. Flight reviews also own overlapping overnight transitions, preventing duplicate whole-day travel suggestions.
  • The correction coordinator re-reads and reassesses reviewed evidence inside the guarded store transaction. Changed evidence refreshes the review instead of silently expanding edits. Identical synced rows produce one edit per sample ID; conflicting representations across the evidence snapshot remain uncorrected.
  • Generation-scoped sample revision registers retain exclusions, replacements, and reset tombstones. All effective-location consumers use the named projection; analysis and backups retain original samples.
  • One revisioned scan drives the banner, review list, badge, and open detail. Foreground deadlines update freshness without background polling.
  • Commits separate persistence/projections, analysis/corrections, and presentation/refresh.

⚠️ Breaking changes

Backup format advances from v5 to v6 for optional motion and correction history. Legacy whole-day flight/drift resolution APIs are replaced by sample correction proposals.

Compatibility

The offline upgrader converts v1–v5 archives to v6 with unknown motion and empty correction history. Export preserves raw samples and revision identities/timestamps, including tombstones; Merge and Replace restore correction history with their generation semantics. Existing authoritative day overrides remain unchanged, and Reset to GPS atomically clears the override and writes fresh tombstones for every affected GPS sample, including samples with no known correction or an existing reset.

Older app builds do not consume sample correction revisions and can report different attribution until updated. The added SwiftData/CloudKit fields and revision entity require the normal CloudKit schema rollout; local tests do not verify live CloudKit deployment or mixed-build behavior.

Thresholds are conservative initial policy. Sparse observations or slower aircraft may remain pending; uncertainty preserves evidence and manual editing. Connectivity inference and new background sensors are outside this change.

Testing

  • September 25 follow-up fixes (a43ff246, bb254608): ./test --no-generate --only WhereCoreTests/FlightTrajectoryAnalyzerTests --only WhereCoreTests/SampleCorrectionAssessmentTests --only WhereCoreTests/SampleCorrectionCoordinatorTests --only WhereCoreTests/DataIssueScannerTests passed 51 tests. New regressions cover separate later trips starting during cruise or takeoff, dismissed flight and border-drift reviews, and retained informational reviews. Architecture validation and 16 rule tests, backup-upgrader 10 tests / 30 assertions, and ./swiftformat --lint passed. No UI layout or snapshot references changed, so image tests were not repeated.
  • Review fixes: ./test WhereCoreTests passed 639 tests, followed by 28 assessment/coordinator/scanner tests after extending duplicate detection across days. New regressions cover duplicate synced rows through Apply, conflicting identities across days, sparse layover preservation, repeated resets, and delayed corrections after reset or clear. Architecture checks (16 rules), backup-upgrader tests (10 tests / 30 assertions), formatting, symbols, and catalog lint passed. No UI code or references changed in these fixes, so snapshots were not repeated.
  • A local replay of the original September 13 trace matched the pre-fix analyzer at all 82 observation checkpoints: recognition at 10:25:02 EDT and arrival confirmation at 15:05:45 EDT. Private samples remain outside the checkout.
  • ./test --all: 2,087 unit tests passed after merging origin/main on Xcode build 27A266a.
  • Original September 13 archive verified locally through the production decoder, analyzer, and correction coordinator: recognition around 10:25 EDT, arrival around 15:05 EDT, resulting regions California and New York, all 4,256 raw samples retained. No private GPS data is committed.
  • Deterministic synthetic coverage includes dense/duplicate fixes, poor accuracy, teleports, long gaps, turning approaches, ground travel, layovers, device separation, date boundaries, stale Apply, sync ordering, generations, outbox replay, and both backup import strategies.
  • Architecture validation: 16 rule tests and lint passed. A repeated run reached the default 60-second evaluation timeout; the retry passed with a 180-second budget.
  • Backup upgrader: 10 tests / 30 assertions passed.
  • Six targeted WhereUI snapshot suites passed after the merge: MainTabs, LocationsView, RootView, FlightStatusBanner, FlightDayDetailView, and ResolutionView. No reference changes were required.
  • Formatting, string-catalog serialization, and SF Symbol lint passed.

Resolve the Where backlog conflict by keeping updated main citations and the flight snapshot evidence.

Validation: ./swiftformat --lint; ./test --all; ./test --only WhereUISnapshotTests/FlightStatusBannerSnapshotTests --only WhereUISnapshotTests/LocationsViewSnapshotTests.
Resolve the Where backlog and UI-agent guidance conflicts, retaining the flight-review invariants alongside the new Elsewhere card rules.

Refresh the branch-only flight Locations snapshots for the redesigned Elsewhere card. The merged root stylesheet context also resolves the MainTabs settling timeout seen on CI.

Validation: ./swiftformat --lint; ./test --all (2,094 tests); ./test --only WhereUISnapshotTests/MainTabsSnapshotTests --review; ./test --only WhereUISnapshotTests/FlightStatusBannerSnapshotTests --only WhereUISnapshotTests/FlightDayDetailViewSnapshotTests --only WhereUISnapshotTests/LocationsViewSnapshotTests --review; ./test --only WhereUISnapshotTests/LocationsViewSnapshotTests.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant