From a82808d1caebdeda5539d8c743ac572f9988db9e Mon Sep 17 00:00:00 2001 From: James Rich Date: Thu, 21 May 2026 17:04:46 -0500 Subject: [PATCH] fix(specs): remove 23 stale map/POI references after deferral Clean up references to MapScreen, PlaceListMapTemplate, POI category, and related models across all spec artifacts following the map strategy deferral decision. All map-related items are now properly marked as DEFERRED or N/A. Affected artifacts: - contracts/car-app-service.md: screen hierarchy, tabs, template section - contracts/manifest-declarations.md: POI category removed - plan.md: file tree cleaned - spec.md: component table, assumptions, clarification Q2 - data-model.md: MapUiState/NodePlace/LatLngWrapper commented out - research.md: R6 marked UNDER REVIEW with options table - tasks.md: T005, T014, delivery strategy - checklists/car-integration.md: CHK020/030/038/043 marked N/A Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../checklists/car-integration.md | 8 ++--- .../contracts/car-app-service.md | 33 ++++--------------- .../contracts/manifest-declarations.md | 2 +- .../data-model.md | 6 ++-- .../plan.md | 6 ++-- .../research.md | 30 +++++++++-------- .../spec.md | 8 ++--- .../tasks.md | 10 +++--- 8 files changed, 44 insertions(+), 59 deletions(-) diff --git a/specs/20260521-153452-car-app-library-integration/checklists/car-integration.md b/specs/20260521-153452-car-app-library-integration/checklists/car-integration.md index ab95f2d83..81e1e2b34 100644 --- a/specs/20260521-153452-car-app-library-integration/checklists/car-integration.md +++ b/specs/20260521-153452-car-app-library-integration/checklists/car-integration.md @@ -31,7 +31,7 @@ ## Requirement Consistency -- [ ] CHK020 — Do FR-009 (PlaceListMapTemplate under POI) and Non-Goals (NAVIGATION deferred to v2) consistently align with map update latency requirement SC-009 (< 5s)? [Consistency, Spec §FR-009, §SC-009] +- [x] CHK020 — ~~Do FR-009 (PlaceListMapTemplate under POI) and Non-Goals (NAVIGATION deferred to v2) consistently align with map update latency requirement SC-009 (< 5s)?~~ N/A — FR-009 and SC-009 deferred with map feature [Consistency] - [ ] CHK021 — Are voice input requirements consistent between US-1 (reply), US-7 (in-context), and FR-003 (primary method)? [Consistency] - [ ] CHK022 — Does "no parked-mode differentiation" (Clarifications) conflict with any acceptance scenario implying driving-only behavior? [Consistency, Spec §Edge Cases] - [ ] CHK023 — Are emergency handling requirements consistent between FR-005 (banner), FR-006 (spotlight), and US-2 (all scenarios)? [Consistency] @@ -44,7 +44,7 @@ - [ ] CHK027 — Is SC-010 ("zero crashes in 2-hour session") sufficient as a release gate — what about ANRs, OOM, or session drops? [Measurability, Spec §SC-010] - [ ] CHK028 — Is SC-007 ("passes Android Auto App Quality review") measurable before actual store submission? [Measurability, Spec §SC-007] - [ ] CHK029 — Is SC-001 ("15 seconds total interaction time") measured from notification appearance or screen wake? [Measurability, Spec §SC-001] -- [ ] CHK030 — Are acceptance scenarios for US-5 (map) testable on DHU given DHU's limited map rendering capabilities? [Measurability, Spec §US-5] +- [x] CHK030 — ~~Are acceptance scenarios for US-5 (map) testable on DHU?~~ N/A — US-5 deferred [Measurability] ## Scenario Coverage @@ -58,12 +58,12 @@ ## Edge Case Coverage -- [ ] CHK038 — Is behavior defined when PlaceListMapTemplate's item limit is reached (max 6 items per CAL docs)? [Edge Case, Spec §FR-009] +- [x] CHK038 — ~~Is behavior defined when PlaceListMapTemplate's item limit is reached?~~ N/A — map deferred [Edge Case] - [ ] CHK039 — Is behavior defined when a channel has zero messages (empty state for messaging screen per channel)? [Edge Case, Gap] - [ ] CHK040 — Are requirements defined for handling very long node names that exceed Condensed Item text bounds? [Edge Case, Spec §FR-007] - [ ] CHK041 — Is behavior defined when voice recognition returns empty/null result or times out? [Edge Case, Spec §FR-003] - [ ] CHK042 — Is behavior defined for rapid consecutive emergency alerts from multiple nodes? [Edge Case, Spec §Edge Cases] -- [ ] CHK043 — Are requirements defined for handling GPS-less nodes on the map screen (nodes without position data)? [Edge Case, Spec §FR-009] +- [x] CHK043 — ~~Are requirements defined for handling GPS-less nodes on the map screen?~~ N/A — map deferred [Edge Case] - [ ] CHK044 — Is behavior defined when the message being composed via voice exceeds mesh packet size limit (228 bytes)? [Edge Case, Gap] - [ ] CHK045 — Is behavior defined when Minimized Control Panel data sources become stale (BLE connected but no mesh traffic)? [Edge Case, Spec §FR-010] diff --git a/specs/20260521-153452-car-app-library-integration/contracts/car-app-service.md b/specs/20260521-153452-car-app-library-integration/contracts/car-app-service.md index dae0c52f1..6af1ef7f9 100644 --- a/specs/20260521-153452-car-app-library-integration/contracts/car-app-service.md +++ b/specs/20260521-153452-car-app-library-integration/contracts/car-app-service.md @@ -16,7 +16,7 @@ The `MeshtasticCarAppService` is the entry point for Android Auto and AAOS hosts - + ``` @@ -26,7 +26,7 @@ The `MeshtasticCarAppService` is the entry point for Android Auto and AAOS hosts | Category | Purpose | Justification | |----------|---------|---------------| | `MESSAGING` | Primary — enables ConversationItem, voice reply | Core use case: read/reply to mesh messages | -| `POI` | Secondary — enables PlaceListMapTemplate | Node map with static pins (not navigation) | +| ~~`POI`~~ | ~~Secondary — enables PlaceListMapTemplate~~ | **DEFERRED** — pending NAVIGATION vs POI decision | ### Car API Level @@ -75,10 +75,8 @@ class MeshtasticCarSession(private val sessionInfo: SessionInfo) : Session() { HomeScreen (root, never popped) ├── MessagingScreen (tab 1) │ └── ConversationScreen (push on conversation tap) - ├── NodeDashboardScreen (tab 2) - │ └── NodeDetailScreen (push on node tap) - └── MapScreen (tab 3) - └── NodeDetailScreen (push on map item tap) + └── NodeDashboardScreen (tab 2) + └── NodeDetailScreen (push on node tap) ``` Maximum screen depth: 3 (compliant with CAL template depth limits). @@ -92,7 +90,6 @@ TabTemplate { tabs: [ Tab("Messages", messagingIcon), Tab("Nodes", nodeIcon), - Tab("Map", mapIcon), ] headerAction: Action.APP_ICON } @@ -170,25 +167,9 @@ PaneTemplate { } ``` -### MapScreen → PlaceListMapTemplate +### ~~MapScreen → PlaceListMapTemplate~~ (DEFERRED) -``` -PlaceListMapTemplate { - title: "Node Map" - itemList: ItemList { - items: [ - Row( - title: node.name, - text: "Updated {timeAgo} • {distanceFormatted}", - metadata: Place(LatLng(lat, lng)), - onClickListener: → push NodeDetailScreen - ) for each node with position - ] - } - anchor: LatLng(ownLat, ownLng) // if own position available - isCurrentLocationEnabled: true -} -``` +> Map implementation deferred pending NAVIGATION vs POI category decision. Template contract will be defined when map strategy is resolved. ### MeshStatusPanel → Minimized Control Panel @@ -224,7 +205,7 @@ AppManager.showAlert( | BLE disconnected | Banner shown; screens degrade to cached data (read-only) | | No channels configured | Show onboarding PaneTemplate directing to phone app | | No nodes in range | Empty state in NodeDashboard: "No nodes heard" | -| No positions available | MapScreen shows empty map with "No positions reported" | +| No positions available | ~~MapScreen shows empty map~~ (DEFERRED with map feature) | | Template item limit exceeded | Paginate with "Load more" action row | | Voice input fails | Fall back to quick-reply template list | | Session crash | Crashlytics captures with `car_session` tag; session restarts cleanly | diff --git a/specs/20260521-153452-car-app-library-integration/contracts/manifest-declarations.md b/specs/20260521-153452-car-app-library-integration/contracts/manifest-declarations.md index d1f1d1306..89ddba270 100644 --- a/specs/20260521-153452-car-app-library-integration/contracts/manifest-declarations.md +++ b/specs/20260521-153452-car-app-library-integration/contracts/manifest-declarations.md @@ -17,7 +17,7 @@ - + diff --git a/specs/20260521-153452-car-app-library-integration/data-model.md b/specs/20260521-153452-car-app-library-integration/data-model.md index f47963efb..6f3b8e73a 100644 --- a/specs/20260521-153452-car-app-library-integration/data-model.md +++ b/specs/20260521-153452-car-app-library-integration/data-model.md @@ -139,10 +139,11 @@ data class TopologyHeader( **Source**: `NodeRepository.nodeDBbyNum`, `NodeRepository.onlineNodeCount` -### MapUiState +### ~~MapUiState~~ (DEFERRED) -State for the PlaceListMapTemplate. +> Map models deferred pending NAVIGATION vs POI category decision. These models will be defined when map strategy is resolved. + ### EmergencyAlert diff --git a/specs/20260521-153452-car-app-library-integration/plan.md b/specs/20260521-153452-car-app-library-integration/plan.md index 2f0a71ec5..e029caa5d 100644 --- a/specs/20260521-153452-car-app-library-integration/plan.md +++ b/specs/20260521-153452-car-app-library-integration/plan.md @@ -85,12 +85,11 @@ feature/car/ │ │ │ │ ├── MeshtasticCarAppService.kt # CarAppService entry point │ │ │ │ └── MeshtasticCarSession.kt # Session lifecycle, screen manager │ │ │ ├── screens/ -│ │ │ │ ├── HomeScreen.kt # Tab-based entry (messaging, nodes, map) +│ │ │ │ ├── HomeScreen.kt # Tab-based entry (messaging, nodes) │ │ │ │ ├── MessagingScreen.kt # ConversationItem list, channel chips │ │ │ │ ├── ConversationScreen.kt # Single conversation with voice reply │ │ │ │ ├── NodeDashboardScreen.kt # Condensed Items node grid │ │ │ │ ├── NodeDetailScreen.kt # Expanded node info -│ │ │ │ ├── MapScreen.kt # PlaceListMapTemplate │ │ │ │ └── ChannelManagementScreen.kt # Channel selection/switching │ │ │ ├── alerts/ │ │ │ │ └── EmergencyHandler.kt # Banner management for emergencies @@ -110,8 +109,7 @@ feature/car/ │ │ └── MeshtasticCarSessionTest.kt │ ├── screens/ │ │ ├── MessagingScreenTest.kt -│ │ ├── NodeDashboardScreenTest.kt -│ │ └── MapScreenTest.kt +│ │ └── NodeDashboardScreenTest.kt │ └── alerts/ │ └── EmergencyHandlerTest.kt diff --git a/specs/20260521-153452-car-app-library-integration/research.md b/specs/20260521-153452-car-app-library-integration/research.md index e6fb0e748..28cdd0af8 100644 --- a/specs/20260521-153452-car-app-library-integration/research.md +++ b/specs/20260521-153452-car-app-library-integration/research.md @@ -90,24 +90,28 @@ The existing `SendMessageUseCase` in `core/repository` accepts `(text, contactKe - Custom speech recognition → Rejected: CAL handles this automatically; would duplicate system capabilities - Google Assistant App Actions → Rejected: Separate concern handled by AppFunctions feature -## R6: PlaceListMapTemplate for Node Map (POI Category) +## R6: Map Template Strategy (UNDER REVIEW) -**Decision**: Use `PlaceListMapTemplate` under POI category for static node position display +**Status**: ⚠️ **Decision deferred** — pending further research on NAVIGATION vs POI implications. -**Rationale**: POI category avoids NAVIGATION category requirements (turn-by-turn guidance, active routing), which would trigger additional Play Store review burden and potential conflicts with navigation apps. `PlaceListMapTemplate` renders a map with place items (pins) + a scrollable list — perfect for showing node positions. +**Options under consideration**: -**Implementation approach**: -- Each node with known GPS position becomes a `Place` item with `LatLng` -- List items show node name + distance + last update time -- Map auto-zooms to fit all visible pins -- Tap a list item → NodeDetailScreen with message option -- Refresh interval: 5 seconds (matches NFR map update latency requirement) +| Option | Template | Pros | Cons | +|--------|----------|------|------| +| POI | `PlaceListMapTemplate` | Simple, no nav conflicts, static pins | 6-item cap, limited interactivity | +| NAVIGATION | `MapWithContentTemplate` | Full map control, live tracking | Exclusive with Google Maps/Waze, stricter review | -**Limitation**: No live tracking line or animated position updates (NAVIGATION category feature, deferred to v2) +**Previous analysis** (preserved for reference): +- POI category avoids NAVIGATION requirements (turn-by-turn guidance, active routing), which would trigger additional Play Store review burden and conflicts with navigation apps +- `PlaceListMapTemplate` renders a map with place items (pins) + a scrollable list — suitable for showing node positions +- MapWithContentTemplate offers richer UX but requires NAVIGATION category declaration -**Alternatives considered**: -- MapWithContentTemplate + NAVIGATION category → Rejected by spec decision; deferred to v2 -- No map at all → Rejected: Location awareness is core Meshtastic differentiator +**Open questions**: +1. Does NAVIGATION category preclude simultaneous Google Maps use on car display? +2. Would Google Maps SDK for AAOS (announced I/O 2026) change the calculus? +3. Is 6-item cap on PlaceListMapTemplate acceptable for typical mesh networks? + +**Implementation approach**: TBD after decision is made ## R7: Koin DI Integration for Car Module diff --git a/specs/20260521-153452-car-app-library-integration/spec.md b/specs/20260521-153452-car-app-library-integration/spec.md index 5e1907437..2335984ee 100644 --- a/specs/20260521-153452-car-app-library-integration/spec.md +++ b/specs/20260521-153452-car-app-library-integration/spec.md @@ -15,7 +15,7 @@ Integrate the Android Car App Library 1.9.0-alpha01 into Meshtastic-Android to d ### Session 2026-05-21 - Q: How should voice commands be implemented — CAL built-in voice input, full Assistant App Actions, or both? → A: CAL built-in voice input only (tap reply → dictate → send). System-level "Hey Google" commands are handled separately by the AppFunctions feature (`specs/20260521-091500-app-functions/`), which exposes `sendMessage`, `getMeshStatus`, `listNodes`, `getRecentMessages`, and `getNodePosition` to Android system AI (Gemini) automatically — including on car displays. -- Q: Should the app declare NAVIGATION category for MapWithContentTemplate, or use PlaceListMapTemplate under POI? → A: Stay with POI category, use PlaceListMapTemplate (static pin list, refreshable). Avoids nav app conflicts and Play Store review burden. Live position tracking under NAVIGATION category deferred to v2. +- Q: Should the app declare NAVIGATION category for MapWithContentTemplate, or use PlaceListMapTemplate under POI? → A: **DECISION DEFERRED** — originally selected POI/PlaceListMapTemplate but reopened for further research. See US-5 deferral note for open questions on NAVIGATION vs POI implications. - Q: Should the CarAppService maintain an independent BLE connection or share the phone app's existing connection? → A: Shared connection — single Application-scoped BleConnectionManager instance via Koin. CarAppService keeps the process alive via Android Auto host; BLE connection persists at the Service/Application level, not Activity level. - Q: What observability approach should the car module use? → A: Reuse existing Crashlytics with `car_session` custom key tagging for car-specific filtering. No new observability infrastructure; tag existing analytics paths. - Q: Should the car app unlock additional features when the vehicle is parked? → A: No parked-mode differentiation. Templated messaging apps provide a uniform experience regardless of driving state. Voice reply is built into ConversationItem. The Android Auto host enforces its own driving restrictions; the app just provides templates. @@ -225,7 +225,7 @@ A driver uses CAL's built-in voice input to compose messages and perform actions | MeshtasticCarAppService | `feature/car/service/` | CAL Session host, entry point for Android Auto/AAOS | | MessagingScreen | `feature/car/screens/` | Message list with channel chips, voice reply, quick-reply | | NodeDashboardScreen | `feature/car/screens/` | Condensed Items grid of all mesh nodes | -| MapScreen | `feature/car/screens/` | PlaceListMapTemplate showing node positions as place items | +| ~~MapScreen~~ | ~~`feature/car/screens/`~~ | ~~PlaceListMapTemplate showing node positions~~ — **DEFERRED** | | EmergencyHandler | `feature/car/alerts/` | Banner management for emergency messages | | MeshStatusPanel | `feature/car/panels/` | Minimized Control Panel with mesh health | | CarMessageRepository | `core/data/` | Existing message repository (reused) | @@ -313,7 +313,7 @@ A driver uses CAL's built-in voice input to compose messages and perform actions - The `google` build flavor is the distribution target; F-Droid/GitHub flavors do not include car support - Quick-reply templates are configurable via the phone app's settings; the car app consumes them read-only - Voice input quality depends on the car's microphone hardware; the app delegates to Android's speech recognition system -- MapWithContentTemplate availability depends on NAVIGATION category declaration (deferred to v2); v1 uses PlaceListMapTemplate under POI which is widely supported +- Map template strategy (POI vs NAVIGATION category) is deferred; no map screen in initial implementation - Minimum Car API Level 8 is required; older Android Auto hosts will not show the app (graceful absence, not crash) - Koin dependency injection is used consistently with Koin Annotations for the new module - TTS (text-to-speech) for reading messages aloud uses Android's built-in TTS engine @@ -453,7 +453,7 @@ ConversationItem.Builder() **Android-exclusive features (exceeding Apple):** - Node dashboard with Condensed Items (Apple has no node visibility) - Emergency Banner overlays with audio alerts (Apple shows emergencies as regular messages) -- Map integration via PlaceListMapTemplate (Apple has no map) +- ~~Map integration~~ (DEFERRED pending NAVIGATION vs POI decision) - Channel Chips for instant switching (Apple requires tab navigation) - Quick-reply templates (Apple only offers Siri voice) - Visual hierarchy via Spotlight/Section Headers/Expanded Headers diff --git a/specs/20260521-153452-car-app-library-integration/tasks.md b/specs/20260521-153452-car-app-library-integration/tasks.md index 5e1d0fffa..42c72de0f 100644 --- a/specs/20260521-153452-car-app-library-integration/tasks.md +++ b/specs/20260521-153452-car-app-library-integration/tasks.md @@ -24,7 +24,7 @@ - [ ] T002 Add `include(":feature:car")` to settings.gradle.kts - [ ] T003 Create module build file at feature/car/build.gradle.kts with android-library, flavors, koin plugins, and all dependencies per contracts/manifest-declarations.md - [ ] T004 [P] Add `"googleImplementation"(projects.feature.car)` dependency in androidApp/build.gradle.kts -- [ ] T005 [P] Create AndroidManifest.xml at feature/car/src/main/AndroidManifest.xml with CarAppService, MESSAGING+POI categories, and minCarApiLevel 8 meta-data +- [ ] T005 [P] Create AndroidManifest.xml at feature/car/src/main/AndroidManifest.xml with CarAppService, MESSAGING category, and minCarApiLevel 8 meta-data - [ ] T006 [P] Create AAOS descriptor at feature/car/src/main/res/xml/automotive_app_desc.xml - [ ] T007 [P] Create car-specific strings file at feature/car/src/main/res/values/strings.xml with initial string resources @@ -42,7 +42,7 @@ - [ ] T011 [P] Create TemplateBuilders helper extensions at feature/car/src/main/kotlin/org/meshtastic/feature/car/util/TemplateBuilders.kt with reusable CAL template construction helpers - [ ] T012 Create MeshtasticCarAppService at feature/car/src/main/kotlin/org/meshtastic/feature/car/service/MeshtasticCarAppService.kt extending CarAppService, creating sessions via Koin - [ ] T013 Create MeshtasticCarSession at feature/car/src/main/kotlin/org/meshtastic/feature/car/service/MeshtasticCarSession.kt with onCreateScreen (returns HomeScreen), onNewIntent, onCarConfigurationChanged, Crashlytics tagging, 300ms invalidation debouncing -- [ ] T014 Create presentation state models (CarSessionState, ConnectionStatus, MessagingUiState, ChannelUi, ConversationUi, NodeDashboardUiState, NodeUi, SignalQuality, TopologyHeader, MapUiState, NodePlace, LatLngWrapper, EmergencyAlert) at feature/car/src/main/kotlin/org/meshtastic/feature/car/model/CarUiModels.kt +- [ ] T014 Create presentation state models (CarSessionState, ConnectionStatus, MessagingUiState, ChannelUi, ConversationUi, NodeDashboardUiState, NodeUi, SignalQuality, TopologyHeader, EmergencyAlert) at feature/car/src/main/kotlin/org/meshtastic/feature/car/model/CarUiModels.kt - [ ] T015 Create HomeScreen (TabTemplate with Messages/Nodes tabs; Map tab placeholder deferred) at feature/car/src/main/kotlin/org/meshtastic/feature/car/screens/HomeScreen.kt **Checkpoint**: Foundation ready — CarAppService binds, session creates, HomeScreen renders tabs. User story implementation can now begin in parallel. @@ -245,7 +245,7 @@ Task: T031 "Register panel in session" 1. Setup + Foundational → Module compiles and binds to Android Auto 2. Add US1 (Messaging) → Core value delivered (MVP!) 3. Add US2 (Emergency) → Safety-critical alerts operational -4. Add US3 + US5 (Nodes + Map) → Location awareness complete +4. Add US3 (Nodes) → Node awareness complete 5. Add US4 (Channels) → Multi-channel workflows enabled 6. Add US6 + US7 (Panel + Voice) → Polish and hands-free refinement 7. Each increment is independently testable with the Desktop Head Unit (DHU) @@ -254,8 +254,8 @@ Task: T031 "Register panel in session" With multiple developers after Phase 2: - Developer A: US1 (Messaging) → US4 (Channels) → US7 (Voice) -- Developer B: US3 (Nodes) → US5 (Map) -- Developer C: US2 (Emergency) + US6 (Status Panel) +- Developer B: US3 (Nodes) + US6 (Status Panel) +- Developer C: US2 (Emergency) ---