Make the activity tracker derive real value from recorded activities:
Ghost race mode — race yourself against a previously recorded activity (Mario Kart ghost style). Gap metric: time gap at my position (when did the ghost pass the point I'm at now).
Eyes-free audio feedback — press a side button mid-activity → rising/falling chime + spoken delta ("ahead by 12 seconds"). iOS: volume-button capture while recording + Action Button App Intent + optional periodic auto-announce. Works with screen locked.
Route analysis report (mobile + web) — where was I slowest/fastest, where did I rest, walk vs run classification, per-km splits, elevation gain/loss. Computed server-side so all clients share one implementation.
Verified starting state: tracker exists only on iOS (v1 record→upload); Android has no tracker; the web map-tracker is local-only; backend stores routes but computes only distance/duration/avg speed.
Workstream tickets (child issues):
Backend analysis engine + GET /api/recorded-routes/{id}/analysis + additive segment wire field
iOS ghost race + audio + report
Angular web report (first consumer of api/recorded-routes on web)
Android BASE tracker (parity port of iOS v1; ghost mode there is a later follow-up)
Cross-repo contract: backend RouteAnalysisDto is canonical; index ranges are inclusive indices into the upload-order points array; RouteStatsCalculator formulas untouched (3-repo fixture parity); never log coordinates.
Child issues (per-repo, auto-close on merge)
No open child issues were produced by the migration — either this epic's
work was already complete, or its scope needs to be broken down into
per-repo issues before it can progress.
Checklist generated by the umbrella-tracker migration, 2026-08-07 — Opus 5 Agent
Make the activity tracker derive real value from recorded activities:
1. **Ghost race mode** — race yourself against a previously recorded activity (Mario Kart ghost style). Gap metric: time gap at my position (when did the ghost pass the point I'm at now).
2. **Eyes-free audio feedback** — press a side button mid-activity → rising/falling chime + spoken delta ("ahead by 12 seconds"). iOS: volume-button capture while recording + Action Button App Intent + optional periodic auto-announce. Works with screen locked.
3. **Route analysis report** (mobile + web) — where was I slowest/fastest, where did I rest, walk vs run classification, per-km splits, elevation gain/loss. Computed server-side so all clients share one implementation.
Verified starting state: tracker exists only on iOS (v1 record→upload); Android has no tracker; the web map-tracker is local-only; backend stores routes but computes only distance/duration/avg speed.
Workstream tickets (child issues):
- Backend analysis engine + `GET /api/recorded-routes/{id}/analysis` + additive `segment` wire field
- iOS ghost race + audio + report
- Angular web report (first consumer of `api/recorded-routes` on web)
- Android BASE tracker (parity port of iOS v1; ghost mode there is a later follow-up)
Cross-repo contract: backend `RouteAnalysisDto` is canonical; index ranges are inclusive indices into the upload-order points array; `RouteStatsCalculator` formulas untouched (3-repo fixture parity); never log coordinates.
<!-- BEGIN MIGRATED-CHILDREN -->
---
## Child issues (per-repo, auto-close on merge)
_No open child issues were produced by the migration — either this epic's
work was already complete, or its scope needs to be broken down into
per-repo issues before it can progress._
<sub>Checklist generated by the umbrella-tracker migration, 2026-08-07 — Opus 5 Agent</sub>
<!-- END MIGRATED-CHILDREN -->
Dissolved into per-repo issues as part of the umbrella-tracker breakup. This epic held implementation work that could never auto-close from a merge; it now lives where the code is:
Android: spikerj/spikersoft-android#15 — route analysis report screen, consuming GET /api/recorded-routes/{id}/analysis
Android: spikerj/spikersoft-android#18 — decision issue: which eyes-free manual trigger Android uses (iOS's volume-button capture + Action Button have no Android equivalent)
Already shipped, no issue filed — verified 2026-08-07 against synced master and live prod:
Backend analysis engine (was spikerj/spikersoft-issues#984): spikersoft-backend@98102023 — SpikerSoft.Business/Domain/Map/RecordedRoutes/Services/RouteAnalyzer.cs, canonical wire shapes in SpikerSoft.Data/DTOs/RouteAnalysisDtos.cs (totals, walk/run/rest segments, per-km splits, rests, fastest/slowest sections, RouteGhostTrackDto), endpoint RecordedRoutesController.cs:150, cached in RecordedRouteAnalysisEF and correctly invalidated by the trim handler. Live:GET https://api.spikersoft.com/api/recorded-routes/<id>/analysis → 401 (auth) while a bogus sibling path → 404, so the route is registered and deployed; /healthz → Healthy.
iOS ghost race + audio + report (#985): spikersoft-ios@69265254 — Core/Tracking/GhostRaceEngine.swift, Core/Tracking/GhostComparator.swift (time-gap-at-my-position, 75 m corridor, pause-aware), Core/Audio/AudioCueService.swift + VolumeButtonTrigger.swift + GapAnnouncement.swift, Core/Intents/AnnounceGhostGapIntent.swift, auto-announce cadence in GhostRaceSettingsSheet.swift, and Features/Tracker/RouteAnalysisView.swift reachable from RouteDetailView.swift:58.
Android base tracker (#987): spikersoft-android@fbe33d30 — recording service, route DB, sync worker, trim screen, and the additive segment wire field in core/network/TrackerDtos.kt.
What is left is exactly what this epic deferred: "Android BASE tracker (parity port of iOS v1; ghost mode there is a later follow-up)". grep -ri "ghost|analysis|TextToSpeech|SoundPool" over spikersoft-android/app/src/ returns 0 hits, and core/network/SpikerSoftApi.kt has no {id}/analysis call — hence the four Android issues above.
The unit is tracked by the shared [Tracker v2] title prefix and by sibling cross-links in each issue. Closing here — the umbrella tracker is being emptied.
— Opus 5 Agent
Dissolved into per-repo issues as part of the umbrella-tracker breakup. This epic held implementation work that could never auto-close from a merge; it now lives where the code is:
- Android: spikerj/spikersoft-android#15 — route analysis report screen, consuming `GET /api/recorded-routes/{id}/analysis`
- Android: spikerj/spikersoft-android#16 — ghost race mode (port of iOS `GhostComparator`/`GhostRaceEngine`)
- Android: spikerj/spikersoft-android#17 — audio pacing cues (rising/falling chime + spoken gap delta + auto-announce cadence)
- Android: spikerj/spikersoft-android#18 — **decision issue**: which eyes-free manual trigger Android uses (iOS's volume-button capture + Action Button have no Android equivalent)
**Already shipped, no issue filed** — verified 2026-08-07 against synced master and live prod:
- **Backend analysis engine** (was spikerj/spikersoft-issues#984): `spikersoft-backend@98102023` — `SpikerSoft.Business/Domain/Map/RecordedRoutes/Services/RouteAnalyzer.cs`, canonical wire shapes in `SpikerSoft.Data/DTOs/RouteAnalysisDtos.cs` (totals, walk/run/rest segments, per-km splits, rests, fastest/slowest sections, `RouteGhostTrackDto`), endpoint `RecordedRoutesController.cs:150`, cached in `RecordedRouteAnalysisEF` and correctly invalidated by the trim handler. **Live:** `GET https://api.spikersoft.com/api/recorded-routes/<id>/analysis` → 401 (auth) while a bogus sibling path → 404, so the route is registered and deployed; `/healthz` → `Healthy`.
- **iOS ghost race + audio + report** (#985): `spikersoft-ios@69265254` — `Core/Tracking/GhostRaceEngine.swift`, `Core/Tracking/GhostComparator.swift` (time-gap-at-my-position, 75 m corridor, pause-aware), `Core/Audio/AudioCueService.swift` + `VolumeButtonTrigger.swift` + `GapAnnouncement.swift`, `Core/Intents/AnnounceGhostGapIntent.swift`, auto-announce cadence in `GhostRaceSettingsSheet.swift`, and `Features/Tracker/RouteAnalysisView.swift` reachable from `RouteDetailView.swift:58`.
- **Angular web report** (#986): `spikersoft-angular@8e5a4048` — `projects/spikersoft/src/app/_components/activity-report/` (classified path, fastest/slowest underlays, rest markers, splits table). **Live:** `learn.spikersoft.com` main bundle `main-KZKZUOSX.js` contains `tracker/activities`.
- **Android base tracker** (#987): `spikersoft-android@fbe33d30` — recording service, route DB, sync worker, trim screen, and the additive `segment` wire field in `core/network/TrackerDtos.kt`.
What is left is exactly what this epic deferred: "Android BASE tracker (parity port of iOS v1; **ghost mode there is a later follow-up**)". `grep -ri "ghost|analysis|TextToSpeech|SoundPool"` over `spikersoft-android/app/src/` returns **0 hits**, and `core/network/SpikerSoftApi.kt` has no `{id}/analysis` call — hence the four Android issues above.
Not duplicated here (already tracked): spikerj/spikersoft-ios#16 (iOS route trim UI), spikerj/spikersoft-ios#17 (return-to-start prompt), spikerj/spikersoft-infrastructure#166 (terrain tile health canary).
The unit is tracked by the shared `[Tracker v2]` title prefix and by sibling cross-links in each issue. Closing here — the umbrella tracker is being emptied.
— 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.
Make the activity tracker derive real value from recorded activities:
Verified starting state: tracker exists only on iOS (v1 record→upload); Android has no tracker; the web map-tracker is local-only; backend stores routes but computes only distance/duration/avg speed.
Workstream tickets (child issues):
GET /api/recorded-routes/{id}/analysis+ additivesegmentwire fieldapi/recorded-routeson web)Cross-repo contract: backend
RouteAnalysisDtois canonical; index ranges are inclusive indices into the upload-order points array;RouteStatsCalculatorformulas untouched (3-repo fixture parity); never log coordinates.Child issues (per-repo, auto-close on merge)
No open child issues were produced by the migration — either this epic's
work was already complete, or its scope needs to be broken down into
per-repo issues before it can progress.
Checklist generated by the umbrella-tracker migration, 2026-08-07 — Opus 5 Agent
Dissolved into per-repo issues as part of the umbrella-tracker breakup. This epic held implementation work that could never auto-close from a merge; it now lives where the code is:
GET /api/recorded-routes/{id}/analysisGhostComparator/GhostRaceEngine)Already shipped, no issue filed — verified 2026-08-07 against synced master and live prod:
spikersoft-backend@98102023—SpikerSoft.Business/Domain/Map/RecordedRoutes/Services/RouteAnalyzer.cs, canonical wire shapes inSpikerSoft.Data/DTOs/RouteAnalysisDtos.cs(totals, walk/run/rest segments, per-km splits, rests, fastest/slowest sections,RouteGhostTrackDto), endpointRecordedRoutesController.cs:150, cached inRecordedRouteAnalysisEFand correctly invalidated by the trim handler. Live:GET https://api.spikersoft.com/api/recorded-routes/<id>/analysis→ 401 (auth) while a bogus sibling path → 404, so the route is registered and deployed;/healthz→Healthy.spikersoft-ios@69265254—Core/Tracking/GhostRaceEngine.swift,Core/Tracking/GhostComparator.swift(time-gap-at-my-position, 75 m corridor, pause-aware),Core/Audio/AudioCueService.swift+VolumeButtonTrigger.swift+GapAnnouncement.swift,Core/Intents/AnnounceGhostGapIntent.swift, auto-announce cadence inGhostRaceSettingsSheet.swift, andFeatures/Tracker/RouteAnalysisView.swiftreachable fromRouteDetailView.swift:58.spikersoft-angular@8e5a4048—projects/spikersoft/src/app/_components/activity-report/(classified path, fastest/slowest underlays, rest markers, splits table). Live:learn.spikersoft.commain bundlemain-KZKZUOSX.jscontainstracker/activities.spikersoft-android@fbe33d30— recording service, route DB, sync worker, trim screen, and the additivesegmentwire field incore/network/TrackerDtos.kt.What is left is exactly what this epic deferred: "Android BASE tracker (parity port of iOS v1; ghost mode there is a later follow-up)".
grep -ri "ghost|analysis|TextToSpeech|SoundPool"overspikersoft-android/app/src/returns 0 hits, andcore/network/SpikerSoftApi.kthas no{id}/analysiscall — hence the four Android issues above.Not duplicated here (already tracked): spikerj/spikersoft-ios#16 (iOS route trim UI), spikerj/spikersoft-ios#17 (return-to-start prompt), spikerj/spikersoft-infrastructure#166 (terrain tile health canary).
The unit is tracked by the shared
[Tracker v2]title prefix and by sibling cross-links in each issue. Closing here — the umbrella tracker is being emptied.— Opus 5 Agent