Skip to content

MAP_MODULE_SPEC.md — Canonical Map Module Specification

Last updated: April 13, 2026 (Omega v2.7) Status: CANONICAL — v1.0 launch spec Owner: Alpha / Beta-1 / Gamma / Delta (builders) + Epsilon (pipeline integration) Supersedes: files/MAP_MODULE_SPEC.md v1.1 (March 30) + all earlier drafts · V2_5 progressive-zoom pin spec · map_routing_traffic_strategy_LOCKED.md · alaivOS_map_route_strategy.md · alaivOS_map_routing_traffic_strategy.md. Cross-refs: DATA_PIPELINE.md (traffic engine, POI pipeline, 290 cities, Photon Worker) · VOICE_AND_AI.md (Piper TTS, InstructionEnricher, SkillRouter, Ask Laiv POI) · PRODUCT_SCOPE.md · PRICING_AND_TIERS.md · GHOST_PROTOCOL.md (Ghost DDG enrichment fallback) · INFRASTRUCTURE.md.


1. PURPOSE & IDENTITY

The Map module is alaivOS's spatial brain: discovery, intelligence, visualization, navigation. One privacy-first, offline-capable, circadian-adaptive map.

Identity: "Your private map that knows when to tell you to leave, what's nearby, where your family is, and navigates you there — without sending your location to anyone."

Navigation engine roadmap: | Version | Engine | Voice | Instructions | CarPlay | |:--|:--|:--|:--|:--| | v1.0 | OSRM | Piper TTS | Enriched (street names, distances) | — | | v1.1 | Valhalla | Piper | Lane guidance, complex interchanges | — | | v1.2 | Valhalla | Piper | Speed cameras, hazards | CarPlay + Android Auto |


2. FIVE VIEWS

View Purpose Default Trigger
Explore Full-screen map + POI discovery + category chips + overlays Module opened normally
Directions Route + travel time + traffic to a destination Tap "Directions" on POI / saved place
Navigate Voice-guided turn-by-turn, heading-up, real-time Tap "Navigate" from Directions
My Places Saved locations (home/work/favorites/custom) + private notes Tap "My Places" icon
Trip View Itinerary pins on map, day selector, safety overlay Travel mode active with trip, or "View on map"

Dock position: Scrollable 14-module dock, smart default slot 2 (after Insights). User rearranges in Settings → Dock Customization. Dock = WHERE (modules); OmniOrb = HOW (modes: Travel / Family / Focus / Sports / Wind Down).


3. FEATURE-GATE MATRIX (MAP)

Gate Min Tier Controls
interactiveMap Starter Map renders, POI, search, My Places, Trip View, voice nav, motorcycle time, offline maps
mapTrafficPatterns Spark Historic traffic ETA (proprietary patterns)
mapLiveTraffic Core Live TomTom traffic ETA, departure alert live recheck
mapTrafficNavigate Pro Traffic coloring, alt routes, multi-stop optimization, navigate deep link
mapFamilySharing Spark Family location sharing (local-only v1.0, PARTIAL per V2_7)
contactMapPins Spark Per-address "Show on map" toggle in People module (PersonPin markers)

Voice nav + motorcycle time + interactive map + POI pins + offline maps + My Places + Trip View = FREE FOR ALL TIERS INCLUDING STARTER. The premium value is ETA accuracy (traffic data) and advanced routing, not navigation itself.

Full gating matrix by view is in §10.


4. EXPLORE VIEW

4.1 Layout

Full-screen map, user blue dot always centered by default. Locate-me button (◎). Add-place button (⊕). Search bar top, scrollable category chips bottom, overlays toggleable.

4.2 POI Glass Pins — Progressive Zoom (V2_6 LOCK)

Zoom Rendering
z13-15 Small colored dots (~8px), category-tinted
z16 Mini glass pins with category emoji (~24px)
z17+ Full detail glass cards: emoji + name + distance

Contradiction resolved: V2_5 spec (dots z10-12, emoji z13-14, cards z15+) rationalized after V2_6 device testing — cards at z14-15 cluttered the map. V2_6 locked glass-pins-only progressive detail per table above. This V2_7 canonical reflects the V2_6 lock.

Category chips (scrollable, multi-select): Food 🍔 · Health 💊 · ATM 🏧 · Shopping 🛒 · Gas ⛽ · Tourism 🏛️ · Leisure 🌳 · Services 📮 · Transport 🚇.

4.3 Place Detail Sheet

Bottom sheet (half → full, draggable). Name, rating, distance, open-now, address, phone, website, hours. Actions: [🧭 Directions] [💾 Save] [📝 Note]. Private local notes + visit count (geofencing-driven, ~50m radius).

4.4 Nearby Places + Ask Laiv POI

  • Prism "Nearby" card (Insights home) → tap → Map Explore centered on POI with detail sheet open.
  • Ask Laiv POI (laiv_poi_search_service.dart + laiv_poi_card_sheet.dart, 23 tests): cross-module context — budget (Money), allergens (Health), calendar (Events), weather (Insights). On-device Qwen first; Ghost DDG enrichment fallback when user is online and needs web facts. SkillRouter intent poi_search.

5. OVERLAYS

Overlay Source Behaviour
Rain RainViewer radar tiles maxNativeZoom: 12 (tiles don't exist above 12; Flutter upscales). Live net only (not in CDN pipeline).
Air Quality (AQ) Open-Meteo AQI (free, 290 cities, pipeline ≤30 min stale) City-wide zoom-adaptive tint. Feeds Prism AQ card, Observer Rule #11, Morning Briefing, Checkup integration, Laiv context.
Wind Windy.com style — animated 200 particles, Beaufort scale colors Canvas particle layer, 60fps, wind-speed-scaled. Decorative + informative.
Compass heading cone Device magnetometer Cone emitted from user dot showing facing direction; useful for walking nav and orientation.

Toggle in overlay bar. Rain + AQ + Wind + Compass are all-tier (free).


6. DIRECTIONS VIEW

6.1 Transport Modes (all four shown simultaneously)

Mode Source Offline
🚗 Car Proprietary patterns → TomTom live → OSRM cold patterns + OSRM
🏍️ Motorcycle Car × calibration multiplier (congestion-dependent)
🚶 Walking OSRM foot profile
🚲 Cycling OSRM bicycle profile
🚇 Transit GTFS (v1.2) ✅ when downloaded

6.2 Directions Tier Gating

Route line + distance + car freeflow + motorcycle + walk/cycle → Starter. Pattern-based ETA → Spark. Live traffic ETA + departure alerts → Core. Traffic coloring + alt routes + multi-stop + navigate deep link → Pro.

6.3 Data Flow

  1. Instant (offline, all tiers): OSRM freeflow + motorcycle multiplier + route geometry.
  2. Pattern overlay (Spark+): Dijkstra through segment graph using proprietary patterns.json. "Normally 47 min on Mondays at this time."
  3. Live overlay (Core+): If patterns show >30% deviation, fetch TomTom live.
  4. Traffic coloring (Pro): TomTom Flow Tiles green/yellow/red on route line.

OSRM coords are longitude,latitude order (not lat,lng). Place-detail sheet expands into Directions state rather than navigating to a new screen (map stays visible).


7. NAVIGATE VIEW (voice-guided, FREE all tiers)

7.1 NavigationService state machine

idle → navigating → rerouting → arrived. Transitions triggered by FollowEngine, OffRouteDetector, geofence arrival (~30m of destination).

7.2 Map behaviour

Heading-up rotation, user dot slightly below center (more road visible ahead), completed route fades, zoom auto-adjusts (zoom-in for turns, zoom-out on long straights), traffic coloring on route for Pro.

7.3 GPS tracking

Geolocator.getPositionStream every 2s during navigation. Android foreground service / iOS background-location (already built). Battery indicator visible.

7.4 Enriched OSRM → natural language (21 locales)

InstructionEnricher maps OSRM maneuver types (turn, roundabout, merge, depart, arrive, continue) into localized strings via ARB keys. Examples: "In 200 meters, turn left onto Av. Américas" / "En 200 metros, gira a la izquierda hacia Av. Américas".

7.5 NavVoiceService (Piper TTS)

SovereignTtsService (sherpa_onnx, en_US-hfc_female-medium + per-locale voices). Requests audio focus → speaks → releases (music/podcasts duck and resume). Prompt timing scales with speed (~25s warning window).

Voice sequence per turn: 1. Advance warning (~500m highway / ~200m city) 2. Immediate warning (~100m) 3. Confirmation after turn Specials: "Rerouting…", "You have arrived", long-straight announcements.

7.6 Off-route + rerouting

OffRouteDetector: 100m threshold × 3 consecutive checks → state rerouting → OSRM recalc → new polyline + instructions → voice resumes with next step.

7.7 Navigate tier gating

Visual route + next-turn card + Piper voice + off-route rerouting + freeflow ETA + "Open in Google Maps" escape hatch → all tiers. Pattern ETA → Spark. Live ETA → Core. Traffic coloring during nav → Pro.


8. 5-LAYER SEARCH STACK

300ms debounced, merged & deduped, ranked by proximity + recency + exact-match weight.

Layer Source Offline Role
1 My Places FTS5 (SQLite) Exact-match first: "Mom's house", "Gym"
2 POI cache (CDN infra/poi/{city}/) Cached POIs for user's city
3 Photon Cloudflare Worker net Autocomplete / typeahead (pipeline-hosted, zero paid API)
4 Nominatim (User-Agent: alaivOS/1.0 — mandatory) net Address geocoding fallback
5 Google Places (luxury, dart-define kill-switch) net Temporary rich-data layer; credit expires June 5, 2026; kill-switch flips → 4 layers remain intact

Foursquare & Yelp: cancelled. Zero paid API dependencies in core stack.


9. TRAFFIC INTELLIGENCE ENGINE

Location: lib/core/location/traffic_intelligence/ — 8 files, 58 tests.

9.1 5-Layer Composite ETA

composite_eta = baseline_spline × live_calibration × weather × calendar × event
Layer Data
baseline_spline Proprietary segment graph. Catmull-Rom cubic spline for Gold cities (smooth time-of-day curve), linear interpolation for Standard cities.
live_calibration TomTom live (Core+ only). Damped multiplier against baseline to avoid jitter.
weather Rain/snow/visibility → severity → minutes added. Pipeline-fed (≤30 min stale).
calendar 20-country calendar adjustment: holidays, school-term vs. break, public-sector hours, major cultural days.
event Concerts/matches/protests: proximity to route + decay over time + expected attendance. Largest-only, no stacking (one dominant event per route).

9.2 Factor Chips (MINUTES, not percentages — locked V2_5)

UI displays "Rain expected — adds ~8 min" not "+12%". All chips in minutes. Reference string: "Normally X min on Mondays" pattern-based for Spark+; live-shifted for Core+.

9.3 Integration Points

  • Directions view ETA block
  • Departure alerts (local notifications pre-event)
  • Morning Briefing ("Leave for work by 7:45 AM")
  • Navigate rolling ETA updates
  • SkillRouter intent navigate_to_x

10. CONTACT ADDRESS PINS (PersonPin)

contactMapPinsSpark+. Per-address toggle "Show on map" in People module. Address geocoded via Nominatim on first enable; cached locally. Renders as PersonPin marker (avatar circle with contact initial/photo) on Map Explore. Tap → contact sheet with [🧭 Directions] [💬 Message] [📞 Call].

Rolled out in SPRINT_CONTACT_MAP_PINS.md.


11. GEOFENCING

Native geofencing_api / platform APIs. Circular geofences (typical 50–200m). Used for: My Places visit tracking (auto-incrementing visitCount + lastVisited), Trip-stop arrival events, "you've arrived" nav trigger, family-share dwell detection. Max concurrent fences respects platform limits (Android 100 per app, iOS 20) — LRU eviction of distant fences.


12. OFFLINE MAPS — FMTC

flutter_map_tile_caching. Cache store per city, per tile style. Auto-download triggers:

Trigger What downloads Size When
User sets Home 4 circadian tile styles z12-16 + POI (8 cat) + patterns ~40-60MB Silent background
User sets Work Additional tiles if different city ~10-20MB Silent background
Trip created Destination tiles + POI + airport indoor ~30-50MB/city Background, WiFi preferred
Monthly refresh POI + patterns for cached cities ~5-10MB 1st of month
User enters new city Prompt "Download maps for [city]?" ~30MB User-prompted

Low storage (onTrimMemory) → LRU eviction. Never evict Home, Work, active-trip caches. Rolled out in SPRINT_R3_ALPHA_OFFLINE_MAPS.md + SPRINT_TILE_PREFETCH.md.


13. FAMILY LOCATION SHARING (v1.0 PARTIAL)

Gate: mapFamilySharing → Spark+. Status per V2_7: PARTIAL — local-only v1.0. No cloud sync service. Device-to-device via E2EE Chat channel; server stores only consent record (who shares with whom, never WHERE). Update cadence: active app 5 min, background 15 min. Reuses existing GPS (no extra polling). Focus mode auto-pauses. Language: "coordinate meetups" / "arrive safely" — never "track" or "monitor".

Cloud-sync service deferred to post-v1.0.


14. TRIP VIEW

Numbered pins per itinerary item, route lines colored by transport (drive blue / walk green / flight dashed). Day-selector tabs filter pins. Airport pins include gate/terminal from cached airport JSON (cdn.alaivos.com/infra/airports/{IATA}.json). Hotel pins show check-in/room. Default view when Travel mode active with trip. Safety overlay (foreign country detected): embassy pin (user's nationality from countries_extended.json), nearest hospital pin, border-crossing notification.


15. CIRCADIAN TILE STYLES

Time CartoDB style
6–10 AM voyager
10 AM–4 PM positron
4–8 PM voyager
8 PM–6 AM dark_matter

Brightness sensor override (dark environment → dark_matter regardless of clock). User manual override highest priority. All UI on top of map = mandatory glass blur (ClipRRect + BackdropFilter 24 + gradient white 0.14→0.05).


16. LAZY LOADING & GPS DISCIPLINE

16.1 Module load

ModuleLoader.ensureLoaded('maps') on first dock tap. Registers providers, hydrates FMTC, initializes TrafficIntelligence, wires SkillRouter.

16.2 GPS 5 Modes

Mode When Accuracy Interval
idle Default none paused
significantChange Background, map not open low OS significant-change
mapExplore Explore view active balanced ~10s
navigating Navigate view active best 2s via position stream
paused Focus mode / user toggle

GpsManager centralizes all requests. No module talks to Geolocator directly.


17. SKILLROUTER INTEGRATION

skill_router.dart routes intents: - navigate_to_x → Map Directions (voice: "navigate to Farmacia Guadalajara") - poi_search → Ask Laiv POI service - show_family_on_map → Map Explore + family layer - set_home / set_work → My Places special-place flow Multilingual keywords EN/ES/PT/FR/DE. All map-facing routes honor tier gates — e.g., mapLiveTraffic required when user asks "how long with traffic right now".


18. COMPLETE TIER-GATING MATRIX

Feature Starter Spark Core Pro Elite
Interactive map (pan/zoom/rotate)
POI pins + categories + overlays (rain/AQ/wind/compass)
5-layer search stack
My Places + private notes + visit tracking
Trip View + airport indoor + safety overlay
OSRM freeflow ETA (car/motorcycle/walk/bike)
Voice nav (Piper, 21 locales, enriched)
Off-route rerouting
Offline maps (FMTC)
"Open in Google Maps" escape
Historic traffic patterns (ETA + nav)
Contact address pins (PersonPin)
Family location sharing (local-only v1.0)
Live traffic ETA
Departure alerts (live recheck)
Traffic coloring on route
Navigate deep link
Alternative routes + multi-stop optimization

19. DATA SOURCES (AT-A-GLANCE)

Data Source Offline Refresh
Base tiles CartoDB 4 circadian styles via FMTC ✅ cached Monthly
POI cdn.alaivos.com/infra/poi/{city}/ (Overpass-built) Monthly
Routing freeflow OSRM (bundled)
Routing patterns cdn.alaivos.com/infra/traffic/{city}/patterns.json Monthly
Live traffic TomTom API Real-time
Traffic coloring TomTom Flow Tiles Real-time
Weather / AQ / events 3-server pipeline → CDN (≤30 min stale) Pipeline schedule
Rain radar RainViewer (live tiles only) Real-time
Airport indoor cdn.alaivos.com/infra/airports/{IATA}.json Monthly
Address geocoding Nominatim (UA: alaivOS/1.0) Per query
Autocomplete Photon Cloudflare Worker Per query
Google luxury Google Places (dart-define kill-switch, expires 2026-06-05) Per query
Safety data countries_extended.json (bundled) Per release

Zero paid API deps in core stack. Pipeline details in DATA_PIPELINE.md.


20. SPRINTS ABSORBED INTO THIS CANONICAL

CRA trio: SPRINT_CRA_ALPHA_DATA.md, SPRINT_CRA_BETA.md, SPRINT_CRA_GAMMA_UI.md (category chips, POI data foundations, UI scaffold).

Wave 1 (Map core): SPRINT_W1_ALPHA_MAP_CORE.md, SPRINT_W1_BETA1_MAP_DIRECTIONS.md, SPRINT_W1_GAMMA_MAP_DOCK.md.

Wave 2 (Places + Trip): SPRINT_W2_ALPHA_MAP_PLACES.md, SPRINT_W2_BETA1_MAP_TRIP.md.

Wave 3 (Lazy + Family + Wiring): SPRINT_W3_ALPHA_MAP_LAZY.md, SPRINT_W3_BETA1_MAP_FAMILY.md, SPRINT_W3_GAMMA_MAP_WIRE.md.

Wave 4 (Verify): SPRINT_W4_DELTA_MAP_VERIFY.md.

POI & Search: SPRINT_ALPHA_MAP_POI_PERSONA.md (Ask Laiv POI, 23 tests), SPRINT_ALPHA_MAP_SEARCH.md (5-layer stack).

Overlays: SPRINT_BETA1_MAP_OVERLAYS.md, SPRINT_BETA1_OVERLAY_FIXES.md (rain maxNativeZoom:12, AQ zoom-adaptive, Windy-style 200 particles, compass cone).

Contacts: SPRINT_CONTACT_MAP_PINS.md.

Offline/geofencing: SPRINT_R3_ALPHA_OFFLINE_MAPS.md, SPRINT_R3_BETA_GEOFENCING.md, SPRINT_TILE_PREFETCH.md.

Navigation pipeline: SPRINT_NAV1_FOLLOW_ENGINE.md, SPRINT_NAV2_INSTRUCTION_ENRICHER.md (21 locales), SPRINT_NAV3_VOICE_ORCHESTRATOR.md, SPRINT_NAV4_NAVIGATION_UI.md.

Traffic Intelligence: SPRINT_BETA2_TRAFFIC_ENGINE.md (8 files, 58 tests, 5-layer composite, Catmull-Rom Gold / linear Standard, 20-country calendar, event largest-only, factor chips in minutes).


21. CONTRADICTIONS RESOLVED

  1. POI pin zoom breakpoints. V2_5 had dots z10-12 / emoji z13-14 / cards z15+. V2_6 device testing showed cards at z14-15 cluttered. V2_6 lock (reflected here): dots z13-15 / mini pins z16 / detail z17+. V2_7 confirmed.
  2. Factor chips. Early drafts used percentages; V2_5 locked minutes. This canonical = minutes only.
  3. Spline model. alaivOS_map_routing_traffic_strategy.md left spline unspecified; BETA2_TRAFFIC_ENGINE locked Catmull-Rom cubic for Gold cities, linear for Standard.
  4. Cloud Gemini routes in early map drafts (e.g., "Open in Gemini"): DEAD per CLAUDE.md v2.7 (AiProvider = {local, ghost} only).
  5. Family sharing earlier spec'd full cloud sync; V2_7 PARTIAL — local-only for v1.0, cloud-sync service deferred.
  6. Foursquare/Yelp referenced in alaivOS_map_route_strategy.md: cancelled. Stack = My Places FTS5 + POI cache + Photon Worker + Nominatim + Google (kill-switch).
  7. TomTom as primary routing. Earlier strategy doc made TomTom primary; current lock: OSRM + proprietary patterns primary, TomTom is LIVE overlay only (Core+).
  8. AI model references in early drafts (2B/4B/9B on-device): superseded by Qwen 3.5 0.8B/2B/4B on-device and Gemma 4 E4B Ghost-server per CLAUDE.md v2.7.

End of canonical MAP_MODULE_SPEC.md v2.7.