Core/Tracking/ReturnToStartDetector.swift — pure struct per epic spec (Config/Event, process/reset), TrackStats.haversineKm, start passed per call from points.first.
ActivityRecorder.swift — the one recorder change: var onRawFix: (@MainActor (CLLocation) -> Void)? invoked in ingest after the accuracy sanity line, before the 2 s/5 m gates.
Core/Notifications/LocalNotificationService.swift (greenfield UserNotifications): auth at recording start (.alert/.sound), category RETURN_TO_START with background actions STOP_AND_SAVE + KEEP_RECORDING, post/clear prompt (no notification sound — chime is the sound), delegate willPresent → banner, didReceive routes stop action. Delegate wired in AppDependencies.
Core/Tracking/ReturnToStartMonitor.swift — GhostRaceEngine-shaped consumer + raw-fix hook; on fire: AudioCueService.play(GapAnnouncement(chime: .ahead, phrase: "You're back at your start. Stop recording?")) + notification + promptActive. stopAndSave() = recorder.stop → auto-save "Untitled activity" → routeSync.syncNow().
TrackerView — notification auth after start/resumeRecovered; in-app banner (Stop & save / Keep recording, proximity-capsule pattern); toolbar gear → new TrackerSettingsSheet (tracker.returnPrompt.enabled, default true).
SpikerSoftTests/ReturnToStartDetectorTests.swift — full epic test matrix. xcodegen generate.
Part of epic #997.
- `Core/Tracking/ReturnToStartDetector.swift` — pure struct per epic spec (Config/Event, process/reset), `TrackStats.haversineKm`, start passed per call from `points.first`.
- `ActivityRecorder.swift` — the one recorder change: `var onRawFix: (@MainActor (CLLocation) -> Void)?` invoked in `ingest` after the accuracy sanity line, before the 2 s/5 m gates.
- `Core/Notifications/LocalNotificationService.swift` (greenfield UserNotifications): auth at recording start (.alert/.sound), category `RETURN_TO_START` with background actions `STOP_AND_SAVE` + `KEEP_RECORDING`, post/clear prompt (no notification sound — chime is the sound), delegate willPresent → banner, didReceive routes stop action. Delegate wired in `AppDependencies`.
- `Core/Tracking/ReturnToStartMonitor.swift` — GhostRaceEngine-shaped consumer + raw-fix hook; on fire: `AudioCueService.play(GapAnnouncement(chime: .ahead, phrase: "You're back at your start. Stop recording?"))` + notification + `promptActive`. `stopAndSave()` = recorder.stop → auto-save "Untitled activity" → `routeSync.syncNow()`.
- `TrackerView` — notification auth after start/resumeRecovered; in-app banner (Stop & save / Keep recording, proximity-capsule pattern); toolbar gear → new `TrackerSettingsSheet` (`tracker.returnPrompt.enabled`, default true).
- `SpikerSoftTests/ReturnToStartDetectorTests.swift` — full epic test matrix. `xcodegen generate`.
Verified 2026-08-07 against spikersoft-ios@6926525 (main). Status: not started. No Core/Tracking/ReturnToStartDetector.swift, no ReturnToStartMonitor.swift, no Core/Notifications/LocalNotificationService.swift (SpikerSoft/Features/Notifications/ is still just a .gitkeep), no TrackerSettingsSheet, no onRawFix hook in ActivityRecorder.swift, and no ReturnToStartDetectorTests.swift.
The Android twin (#999) shipped at spikersoft-android@04d9c7b and is the reference for the detector semantics and the shared test matrix. AudioCueService is now safe to touch from the unit-test host — its AVSpeechSynthesizer became lazy in #1001 (AudioCueService.swift:27).
Closing here. Work now lives in the repo that holds the fix, so fixes #17 in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.
— Opus 5 Agent
Migrated to **spikerj/spikersoft-ios#17** as part of the umbrella-tracker breakup.
Verified 2026-08-07 against `spikersoft-ios@6926525` (main). Status: **not started.** No `Core/Tracking/ReturnToStartDetector.swift`, no `ReturnToStartMonitor.swift`, no `Core/Notifications/LocalNotificationService.swift` (`SpikerSoft/Features/Notifications/` is still just a `.gitkeep`), no `TrackerSettingsSheet`, no `onRawFix` hook in `ActivityRecorder.swift`, and no `ReturnToStartDetectorTests.swift`.
The Android twin (#999) shipped at `spikersoft-android@04d9c7b` and is the reference for the detector semantics and the shared test matrix. `AudioCueService` is now safe to touch from the unit-test host — its `AVSpeechSynthesizer` became lazy in #1001 (`AudioCueService.swift:27`).
Closing here. Work now lives in the repo that holds the fix, so `fixes #17` in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.
— Opus 5 Agent
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Part of epic #997.
Core/Tracking/ReturnToStartDetector.swift— pure struct per epic spec (Config/Event, process/reset),TrackStats.haversineKm, start passed per call frompoints.first.ActivityRecorder.swift— the one recorder change:var onRawFix: (@MainActor (CLLocation) -> Void)?invoked iningestafter the accuracy sanity line, before the 2 s/5 m gates.Core/Notifications/LocalNotificationService.swift(greenfield UserNotifications): auth at recording start (.alert/.sound), categoryRETURN_TO_STARTwith background actionsSTOP_AND_SAVE+KEEP_RECORDING, post/clear prompt (no notification sound — chime is the sound), delegate willPresent → banner, didReceive routes stop action. Delegate wired inAppDependencies.Core/Tracking/ReturnToStartMonitor.swift— GhostRaceEngine-shaped consumer + raw-fix hook; on fire:AudioCueService.play(GapAnnouncement(chime: .ahead, phrase: "You're back at your start. Stop recording?"))+ notification +promptActive.stopAndSave()= recorder.stop → auto-save "Untitled activity" →routeSync.syncNow().TrackerView— notification auth after start/resumeRecovered; in-app banner (Stop & save / Keep recording, proximity-capsule pattern); toolbar gear → newTrackerSettingsSheet(tracker.returnPrompt.enabled, default true).SpikerSoftTests/ReturnToStartDetectorTests.swift— full epic test matrix.xcodegen generate.Migrated to spikerj/spikersoft-ios#17 as part of the umbrella-tracker breakup.
Verified 2026-08-07 against
spikersoft-ios@6926525(main). Status: not started. NoCore/Tracking/ReturnToStartDetector.swift, noReturnToStartMonitor.swift, noCore/Notifications/LocalNotificationService.swift(SpikerSoft/Features/Notifications/is still just a.gitkeep), noTrackerSettingsSheet, noonRawFixhook inActivityRecorder.swift, and noReturnToStartDetectorTests.swift.The Android twin (#999) shipped at
spikersoft-android@04d9c7band is the reference for the detector semantics and the shared test matrix.AudioCueServiceis now safe to touch from the unit-test host — itsAVSpeechSynthesizerbecame lazy in #1001 (AudioCueService.swift:27).Closing here. Work now lives in the repo that holds the fix, so
fixes #17in a PR will auto-close it on merge. The umbrella tracker keeps cross-repo epics only.— Opus 5 Agent