From 8a06157ff4b08b08dffe9ef11e92ecb61f29357e Mon Sep 17 00:00:00 2001
From: James Rich <2199651+jamesarich@users.noreply.github.com>
Date: Mon, 13 Apr 2026 12:59:19 -0500
Subject: [PATCH] docs: remove agent cruft, condense and validate remaining
docs (#5110)
---
.github/workflows/pull-request.yml | 4 -
.skills/code-review/SKILL.md | 17 +-
.skills/project-overview/SKILL.md | 42 +--
.skills/testing-ci/SKILL.md | 8 -
AGENTS.md | 6 +-
SOUL.md | 31 --
conductor/code_styleguides/general.md | 23 --
conductor/index.md | 14 -
conductor/product-guidelines.md | 19 -
conductor/product.md | 26 --
conductor/tech-stack.md | 38 --
conductor/tracks.md | 5 -
conductor/workflow.md | 333 ------------------
docs/decisions/README.md | 15 -
docs/decisions/architecture-review-2026-03.md | 256 --------------
.../navigation3-api-alignment-2026-03.md | 124 -------
docs/decisions/navigation3-parity-2026-03.md | 167 ---------
docs/kmp-status.md | 26 +-
docs/roadmap.md | 2 +-
docs/testing/baseline_coverage.md | 6 -
docs/testing/final_coverage.md | 18 -
21 files changed, 30 insertions(+), 1150 deletions(-)
delete mode 100644 SOUL.md
delete mode 100644 conductor/code_styleguides/general.md
delete mode 100644 conductor/index.md
delete mode 100644 conductor/product-guidelines.md
delete mode 100644 conductor/product.md
delete mode 100644 conductor/tech-stack.md
delete mode 100644 conductor/tracks.md
delete mode 100644 conductor/workflow.md
delete mode 100644 docs/decisions/README.md
delete mode 100644 docs/decisions/architecture-review-2026-03.md
delete mode 100644 docs/decisions/navigation3-api-alignment-2026-03.md
delete mode 100644 docs/decisions/navigation3-parity-2026-03.md
delete mode 100644 docs/testing/baseline_coverage.md
delete mode 100644 docs/testing/final_coverage.md
diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml
index 22a611576..209d6e35c 100644
--- a/.github/workflows/pull-request.yml
+++ b/.github/workflows/pull-request.yml
@@ -3,10 +3,6 @@ name: Pull Request CI
on:
pull_request:
branches: [ main ]
- paths-ignore:
- - '**/*.md'
- - 'docs/**'
- - '.gitignore'
permissions:
contents: read
diff --git a/.skills/code-review/SKILL.md b/.skills/code-review/SKILL.md
index de8c93c88..b39e2d0d9 100644
--- a/.skills/code-review/SKILL.md
+++ b/.skills/code-review/SKILL.md
@@ -1,16 +1,7 @@
# Skill: Code Review
## Description
-Perform comprehensive and precise code reviews for the `Meshtastic-Android` project. This skill ensures that incoming changes adhere strictly to the project's architecture guidelines, Kotlin Multiplatform (KMP) conventions, Modern Android Development (MAD) standards, and Jetpack Compose Multiplatform (CMP) best practices.
-
-## Context & Prerequisites
-The `Meshtastic-Android` codebase is a highly modernized Kotlin Multiplatform (KMP) application designed for off-grid, decentralized mesh networks.
-- **Language:** Kotlin (primary), JDK 21 required.
-- **Architecture:** KMP core with Android and Desktop host shells.
-- **UI:** Jetpack Compose Multiplatform (CMP) and Material 3 Adaptive.
-- **Navigation:** JetBrains Navigation 3 (Scene-based).
-- **DI:** Koin Annotations (with K2 compiler plugin).
-- **Async & I/O:** Kotlin Coroutines, Flow, Okio, Ktor.
+Perform comprehensive code reviews for `Meshtastic-Android`, ensuring changes adhere to KMP architecture, Kotlin Multiplatform conventions, MAD standards, and CMP best practices.
## Code Review Checklist
@@ -64,9 +55,3 @@ When reviewing code, meticulously verify the following categories. Flag any devi
### 8. ProGuard / R8 Rules
- [ ] **New Dependencies:** If a new reflection-heavy dependency is added (DI, serialization, JNI, ServiceLoader), verify keep rules exist in **both** `app/proguard-rules.pro` (R8) and `desktop/proguard-rules.pro` (ProGuard). The two files must stay aligned.
- [ ] **Release Smoke-Test:** For dependency or ProGuard rule changes, verify `assembleRelease` and `./gradlew :desktop:runRelease` succeed.
-
-## Review Output Guidelines
-1. **Be Specific & Constructive:** Provide exact file references and code snippets illustrating the required project pattern.
-2. **Reference the Docs:** Cite `AGENTS.md` and project architecture playbooks to justify change requests (e.g., "Per AGENTS.md, `java.io.*` cannot be used in `commonMain`; please migrate to Okio").
-3. **Enforce Build Health:** Remind authors to run `./gradlew test allTests` locally to verify changes, especially since KMP `test` tasks are ambiguous.
-4. **Praise Good Patterns:** Acknowledge correct usage of complex architecture requirements, like proper Navigation 3 scene transitions or elegant `commonMain` helper extractions.
diff --git a/.skills/project-overview/SKILL.md b/.skills/project-overview/SKILL.md
index 6df668bf2..d7d6af473 100644
--- a/.skills/project-overview/SKILL.md
+++ b/.skills/project-overview/SKILL.md
@@ -1,21 +1,13 @@
# Skill: Project Overview & Codebase Map
## Description
-High-level project context, module directory, namespacing conventions, environment setup, and troubleshooting for Meshtastic-Android.
+Module directory, namespacing conventions, environment setup, and troubleshooting for Meshtastic-Android.
-## 1. Project Vision & Architecture
-Meshtastic-Android is a Kotlin Multiplatform (KMP) application for off-grid, decentralized mesh networks. The goal is to decouple business logic from the Android framework, enabling expansion to iOS and Desktop while maintaining a high-performance native Android experience.
+- **Build System:** Gradle (Kotlin DSL). JDK 21 REQUIRED. Target SDK: API 36. Min SDK: API 26.
+- **Flavors:** `fdroid` (OSS only) · `google` (Maps + DataDog analytics)
+- **Android-only Modules:** `core:api` (AIDL), `core:barcode` (CameraX). Shared contracts abstracted into `core:ui/commonMain`.
-- **Language:** Kotlin (primary), AIDL.
-- **Build System:** Gradle (Kotlin DSL). JDK 21 is REQUIRED.
-- **Target SDK:** API 36. Min SDK: API 26 (Android 8.0).
-- **Flavors:**
- - `fdroid`: Open source only, no tracking/analytics.
- - `google`: Includes Google Play Services (Maps) and DataDog analytics (RUM, Session Replay, Compose action tracking, custom `connect` RUM action). 100% sampling, Apple-parity environments ("Local"/"Production").
-- **KMP Modules:** Most `core:*` modules declare `jvm()`, `iosArm64()`, and `iosSimulatorArm64()` targets and compile clean across all.
-- **Android-only Modules:** `core:api` (AIDL), `core:barcode` (CameraX + flavor-specific decoder). Shared contracts abstracted into `core:ui/commonMain`.
-
-## 2. Codebase Map
+## Codebase Map
| Directory | Description |
| :--- | :--- |
@@ -47,13 +39,13 @@ Meshtastic-Android is a Kotlin Multiplatform (KMP) application for off-grid, dec
| `feature/wifi-provision` | KMP WiFi provisioning via BLE (Nymea protocol). Uses `core:ble` Kable abstractions. |
| `feature/firmware` | Fully KMP firmware update system: Unified OTA (BLE + WiFi), native Nordic Secure DFU protocol (pure KMP), USB/UF2 updates, and `FirmwareRetriever` with manifest-based resolution. Desktop is a first-class target. |
| `desktop/` | Compose Desktop application. Thin host shell relying on feature modules for shared UI. Full Koin DI graph, TCP, Serial/USB, and BLE transports. Versioning via `config.properties` + `GitVersionValueSource`. |
-| `mesh_service_example/` | **DEPRECATED — scheduled for removal.** Legacy sample app. See `core/api/README.md` for the current integration guide. |
+| `mesh_service_example/` | **DEPRECATED.** Legacy sample app; not yet removed. See `core/api/README.md` for the current integration guide. |
-## 3. Namespacing
+## Namespacing
- **Standard:** Use the `org.meshtastic.*` namespace for all code.
- **Legacy:** Maintain the `com.geeksville.mesh` Application ID.
-## 4. Environment Setup
+## Environment Setup
1. **JDK 21 MUST be used** to prevent Gradle sync/build failures.
2. **Secrets:** Copy `secrets.defaults.properties` to `local.properties`:
```properties
@@ -62,7 +54,7 @@ Meshtastic-Android is a Kotlin Multiplatform (KMP) application for off-grid, dec
datadogClientToken=dummy_token
```
-## 5. Workspace Bootstrap (MUST run before any build)
+## Workspace Bootstrap (MUST run before any build)
Agents **MUST** perform these steps automatically at the start of every session before running any Gradle task. Do not wait for the user to tell you.
1. **Android SDK:** `ANDROID_HOME` may not be set in agent workspaces. Detect and export it:
@@ -81,17 +73,7 @@ Agents **MUST** perform these steps automatically at the start of every session
git submodule update --init
```
-## 6. Troubleshooting
+## Troubleshooting
- **Build Failures:** Check `gradle/libs.versions.toml` for dependency conflicts.
-- **Missing Secrets:** Check `local.properties` (see Environment Setup above).
-- **JDK Version:** JDK 21 is required.
-- **SDK location not found:** See Workspace Bootstrap step 1 above.
-- **Proto generation failures:** See Workspace Bootstrap step 2 above.
-- **Configuration Cache:** Add `--no-configuration-cache` flag if cache-related issues persist.
-- **Koin Injection Failures:** Verify the KMP component is included in `app` root module wiring (`AppKoinModule`).
-
-## Reference Anchors
-- **KMP Migration Status:** `docs/kmp-status.md`
-- **Roadmap:** `docs/roadmap.md`
-- **Architecture Decision Records:** `docs/decisions/`
-- **Version Catalog:** `gradle/libs.versions.toml`
+- **Configuration Cache:** Add `--no-configuration-cache` if cache-related issues persist.
+- **Koin Injection Failures:** Verify the component is included in `AppKoinModule`.
diff --git a/.skills/testing-ci/SKILL.md b/.skills/testing-ci/SKILL.md
index 586c1ef9c..0dca01eb6 100644
--- a/.skills/testing-ci/SKILL.md
+++ b/.skills/testing-ci/SKILL.md
@@ -86,11 +86,3 @@ CI is defined in `.github/workflows/reusable-check.yml` and structured as four p
- **Path filtering:** `check-changes` in `pull-request.yml` must include module dirs plus build/workflow entrypoints (`build-logic/**`, `gradle/**`, `.github/workflows/**`, `gradlew`, `settings.gradle.kts`, etc.).
- **AboutLibraries:** Runs in `offlineMode` by default (no GitHub/SPDX API calls). Release builds pass `-PaboutLibraries.release=true` via Fastlane/Gradle CLI to enable remote license fetching. Do NOT re-gate on `CI` or `GITHUB_TOKEN` alone.
-## 5) Shell & Tooling Conventions
-- **Terminal Pagers:** When running shell commands like `git diff` or `git log`, ALWAYS use `--no-pager` (e.g., `git --no-pager diff`) to prevent getting stuck in an interactive prompt.
-- **Text Search:** Prefer `rg` (ripgrep) over `grep` or `find` for fast text searching across the codebase.
-
-## 6) Agent/Developer Guidance
-- Start with the smallest set that validates your touched area.
-- If unable to run full validation locally, report exactly what ran and what remains.
-- Keep documentation synced in `AGENTS.md` and `.skills/` directories.
diff --git a/AGENTS.md b/AGENTS.md
index 73d29f2b9..9fcc166b5 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -52,7 +52,7 @@ You are an expert Android and Kotlin Multiplatform (KMP) engineer working on Mes
- `CLAUDE.md` — Claude Code entry point; imports `AGENTS.md` via `@AGENTS.md` and adds Claude-specific instructions.
- `GEMINI.md` — Gemini redirect to `AGENTS.md`. Gemini CLI also configured via `.gemini/settings.json` to read `AGENTS.md` directly.
-Do NOT duplicate content into agent-specific files. When you modify architecture, module targets, CI tasks, validation commands, or agent workflow rules, update `AGENTS.md`, `.skills/`, `docs/kmp-status.md`, and `docs/decisions/architecture-review-2026-03.md` as needed.
+Do NOT duplicate content into agent-specific files. When you modify architecture, module targets, CI tasks, validation commands, or agent workflow rules, update `AGENTS.md`, `.skills/`, and `docs/kmp-status.md` as needed.
@@ -61,4 +61,8 @@ Do NOT duplicate content into agent-specific files. When you modify architecture
- **Koin Annotations:** Use `@Single`, `@Factory`, and `@KoinViewModel` inside `commonMain` instead of manual constructor trees. Do not enable A1 module compile safety.
- **CMP Over Android:** Use `compose-multiplatform` constraints (e.g., no float formatting in `stringResource`).
- **Always Check Docs:** If unsure about an abstraction, search `core:ui/commonMain` or `core:navigation/commonMain` before assuming it doesn't exist.
+- **Privacy First:** Never log or expose PII, location data, or cryptographic keys. Meshtastic is used for sensitive off-grid communication — treat all user data with extreme caution.
+- **Dependency Discipline:** Never add a library without first checking `libs.versions.toml` and justifying its inclusion against the project's size and complexity goals. Prefer removing dependencies over adding them.
+- **Zero Lint Tolerance:** A task is incomplete if `detekt` fails or `spotlessCheck` does not pass for touched modules.
+- **Read Before Refactoring:** When a pattern contradicts best practices, analyze whether it is legacy debt or a deliberate architectural choice before proposing a change.
diff --git a/SOUL.md b/SOUL.md
deleted file mode 100644
index 45924b40f..000000000
--- a/SOUL.md
+++ /dev/null
@@ -1,31 +0,0 @@
-# Meshtastic-Android: AI Agent Soul (SOUL.md)
-
-This file defines the personality, values, and behavioral framework of the AI agent for this repository.
-
-## 1. Core Identity
-I am an **Android Architect**. My primary purpose is to evolve the Meshtastic-Android codebase while maintaining its integrity as a secure, decentralized communication tool. I am not just a "helpful assistant"; I am a senior peer programmer who takes ownership of the technical stack.
-
-## 2. Core Truths & Values
-- **Privacy is Paramount:** Meshtastic is used for off-grid, often sensitive communication. I treat user data, location info, and cryptographic keys with extreme caution. I will never suggest logging PII or secrets.
-- **Code is a Liability:** I prefer simple, readable code over clever abstractions. I remove dead code and minimize dependencies wherever possible.
-- **Decentralization First:** I prioritize architectural patterns that support offline-first and peer-to-peer logic.
-- **MAD & KMP are the Standard:** Modern Android Development (Compose, Koin, Coroutines) and Kotlin Multiplatform are not suggestions; they are the foundation. I resist introducing legacy patterns unless absolutely required for OS compatibility.
-
-## 3. Communication Style (The "Vibe")
-- **Direct & Concise:** I skip the fluff. I provide technical rationale first.
-- **Opinionated but Grounded:** I provide clear technical recommendations based on established project conventions.
-- **Action-Oriented:** I don't just "talk" about code; I implement, test, and format it.
-
-## 4. Operational Boundaries
-- **Zero Lint Tolerance (for code changes):** I consider a coding task incomplete if `detekt` fails or `spotlessCheck` is not passing for touched modules.
-- **Test-Driven Execution (where feasible):** For bug fixes, I should reproduce the issue with a test before fixing it when practical. For new features, I should add appropriate verification logic.
-- **Dependency Discipline:** I never add a library without checking `libs.versions.toml` and justifying its inclusion against the project's size and complexity.
-- **No Hardcoded Strings:** I will refuse to add hardcoded UI strings, strictly adhering to the `:core:resources` KMP resource system.
-
-## 5. Evolution
-I learn from the existing codebase. If I see a pattern in a module that contradicts my "soul," I will first analyze if it's a legacy debt or a deliberate choice before proposing a change. I adapt my technical opinions to align with the specific architectural direction set by the Meshtastic maintainers.
-
-For architecture, module boundaries, and build/test commands, I treat `AGENTS.md` as the source of truth.
-For implementation recipes and verification scope, I use `.skills/` directory.
-
-
diff --git a/conductor/code_styleguides/general.md b/conductor/code_styleguides/general.md
deleted file mode 100644
index dfcc793f4..000000000
--- a/conductor/code_styleguides/general.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# General Code Style Principles
-
-This document outlines general coding principles that apply across all languages and frameworks used in this project.
-
-## Readability
-- Code should be easy to read and understand by humans.
-- Avoid overly clever or obscure constructs.
-
-## Consistency
-- Follow existing patterns in the codebase.
-- Maintain consistent formatting, naming, and structure.
-
-## Simplicity
-- Prefer simple solutions over complex ones.
-- Break down complex problems into smaller, manageable parts.
-
-## Maintainability
-- Write code that is easy to modify and extend.
-- Minimize dependencies and coupling.
-
-## Documentation
-- Document *why* something is done, not just *what*.
-- Keep documentation up-to-date with code changes.
diff --git a/conductor/index.md b/conductor/index.md
deleted file mode 100644
index 3a362bc99..000000000
--- a/conductor/index.md
+++ /dev/null
@@ -1,14 +0,0 @@
-# Project Context
-
-## Definition
-- [Product Definition](./product.md)
-- [Product Guidelines](./product-guidelines.md)
-- [Tech Stack](./tech-stack.md)
-
-## Workflow
-- [Workflow](./workflow.md)
-- [Code Style Guides](./code_styleguides/)
-
-## Management
-- [Tracks Registry](./tracks.md)
-- [Tracks Directory](./tracks/)
\ No newline at end of file
diff --git a/conductor/product-guidelines.md b/conductor/product-guidelines.md
deleted file mode 100644
index b54944fea..000000000
--- a/conductor/product-guidelines.md
+++ /dev/null
@@ -1,19 +0,0 @@
-# Product Guidelines
-
-## Brand Voice and Tone
-- **Technical yet Accessible:** Communicate complex networking and hardware concepts clearly without being overly academic.
-- **Reliable and Authoritative:** The app is a utility for critical, off-grid communication. Language should convey stability and safety.
-- **Community-Oriented:** Encourage open-source participation and community support.
-
-## UX Principles
-- **Offline-First:** Assume the user has no cellular or Wi-Fi connection. All core functions must work locally via the mesh network.
-- **Adaptive Layouts:** Support multiple form factors seamlessly (phones, tablets, desktop) using Material 3 Adaptive Scaffold principles.
-- **Information Density:** Give power users access to detailed metrics (SNR, battery, hop limits) without overwhelming beginners. Use progressive disclosure.
-
-## Prose Style
-- **Clarity over cleverness:** Use plain English.
-- **Action-oriented:** Button labels and prompts should start with strong verbs (e.g., "Send", "Connect", "Export").
-- **Consistent Terminology:**
- - Use "Node" for devices on the network.
- - Use "Channel" for communication groups.
- - Use "Direct Message" for 1-to-1 communication.
\ No newline at end of file
diff --git a/conductor/product.md b/conductor/product.md
deleted file mode 100644
index edfac5083..000000000
--- a/conductor/product.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# Initial Concept
-A tool for using Android with open-source mesh radios.
-
-# Product Guide
-
-## Overview
-Meshtastic-Android is a Kotlin Multiplatform (KMP) application designed to facilitate communication over off-grid, decentralized mesh networks using open-source hardware radios.
-
-## Target Audience
-- Off-grid communication enthusiasts and hobbyists
-- Outdoor adventurers needing reliable communication without cellular networks
-- Emergency response and disaster relief teams
-
-## Core Features
-- Direct communication with Meshtastic hardware (via BLE, USB, TCP, MQTT)
-- Decentralized text messaging across the mesh network
-- Unified cross-platform notifications for messages and node events
-- Adaptive node and contact management
-- Offline map rendering and device positioning
-- Device configuration and firmware updates
-- Unified cross-platform debugging and packet inspection
-
-## Key Architecture Goals
-- Provide a robust, shared KMP core (`core:model`, `core:ble`, `core:repository`, `core:domain`, `core:data`, `core:network`, `core:service`) to support multiple platforms (Android, Desktop, iOS)
-- Ensure offline-first functionality and resilient data persistence (Room 3 KMP)
-- Decouple UI and navigation logic into shared feature modules (`core:ui`, `feature:*`) using Compose Multiplatform
\ No newline at end of file
diff --git a/conductor/tech-stack.md b/conductor/tech-stack.md
deleted file mode 100644
index 75237887b..000000000
--- a/conductor/tech-stack.md
+++ /dev/null
@@ -1,38 +0,0 @@
-# Tech Stack
-
-## Programming Language
-- **Kotlin Multiplatform (KMP):** The core logic is shared across Android, Desktop, and iOS using `commonMain`.
-
-## Frontend Frameworks
-- **Compose Multiplatform:** Shared UI layer for rendering on Android and Desktop.
-- **Jetpack Compose:** Used where platform-specific UI (like charts or permissions) is necessary on Android.
-
-## Background & Services
-- **Platform Services:** Core service orchestrations and background work are abstracted into `core:service` to maximize logic reuse across targets, using platform-specific implementations (e.g., WorkManager/Service on Android) only where necessary.
-
-## Architecture
-- **MVI / Unidirectional Data Flow:** Shared view models using the multiplatform `androidx.lifecycle.ViewModel`.
-- **JetBrains Navigation 3:** Multiplatform fork for state-based, compose-first navigation without relying on `NavController`. Navigation graphs are decoupled and extracted into their respective `feature:*` modules, allowing a thinned out root `app` module.
-
-## Dependency Injection
-- **Koin 4.2:** Leverages Koin Annotations and the K2 Compiler Plugin for pure compile-time DI, completely replacing Hilt.
-
-## Database & Storage
-- **Room 3 KMP:** Shared local database using multiplatform `DatabaseConstructor` and platform-appropriate SQLite drivers (e.g., `BundledSQLiteDriver` for JVM/Desktop, Framework driver for Android).
-- **Jetpack DataStore:** Shared preferences.
-
-## Networking & Transport
-- **Ktor:** Multiplatform HTTP client for web services and TCP streaming.
-- **Kable:** Multiplatform BLE library used as the primary BLE transport for all targets (Android, Desktop, and future iOS).
-- **jSerialComm:** Cross-platform Java library used for direct Serial/USB communication with Meshtastic devices on the Desktop (JVM) target.
-- **KMQTT:** Kotlin Multiplatform MQTT client and broker used for MQTT transport, replacing the Android-only Paho library.
-- **Coroutines & Flows:** For asynchronous programming and state management.
-
-## Testing (KMP)
-- **Shared Tests First:** The majority of business logic, ViewModels, and state interactions are tested in the `commonTest` source set using standard `kotlin.test`.
-- **Coroutines Testing:** Use `kotlinx-coroutines-test` for virtual time management in asynchronous flows.
-- **Mocking Strategy:** Avoid JVM-specific mocking libraries. Prefer `Mokkery` or `Mockative` for multiplatform-compatible mocking interfaces, alongside handwritten fakes in `core:testing`.
-- **Platform-Specific Verification:** Use **Robolectric** on the Android host target to verify KMP modules that interact with Android framework components (like `Uri` or `Room`).
-- **Subclassing Pattern:** Maintain a unified test suite by defining abstract base tests in `commonTest` and platform-specific subclasses in `jvmTest` and `androidHostTest` for initialization (e.g., calling `setupTestContext()`).
-- **Flow Assertions:** Use `Turbine` for testing multiplatform `Flow` emissions and state updates.
-- **Property-Based Testing:** Use `Kotest` for multiplatform data-driven and property-based testing scenarios.
\ No newline at end of file
diff --git a/conductor/tracks.md b/conductor/tracks.md
deleted file mode 100644
index 0b5c54e3d..000000000
--- a/conductor/tracks.md
+++ /dev/null
@@ -1,5 +0,0 @@
-# Project Tracks
-
-This file tracks all major tracks for the project. Each track has its own detailed plan in its respective folder.
-
----
diff --git a/conductor/workflow.md b/conductor/workflow.md
deleted file mode 100644
index 6f9cfd8fc..000000000
--- a/conductor/workflow.md
+++ /dev/null
@@ -1,333 +0,0 @@
-# Project Workflow
-
-## Guiding Principles
-
-1. **The Plan is the Source of Truth:** All work must be tracked in `plan.md`
-2. **The Tech Stack is Deliberate:** Changes to the tech stack must be documented in `tech-stack.md` *before* implementation
-3. **Test-Driven Development:** Write unit tests before implementing functionality
-4. **High Code Coverage:** Aim for >80% code coverage for all modules
-5. **User Experience First:** Every decision should prioritize user experience
-6. **Non-Interactive & CI-Aware:** Prefer non-interactive commands. Use `CI=true` for watch-mode tools (tests, linters) to ensure single execution.
-
-## Task Workflow
-
-All tasks follow a strict lifecycle:
-
-### Standard Task Workflow
-
-1. **Select Task:** Choose the next available task from `plan.md` in sequential order
-
-2. **Mark In Progress:** Before beginning work, edit `plan.md` and change the task from `[ ]` to `[~]`
-
-3. **Write Failing Tests (Red Phase):**
- - Create a new test file for the feature or bug fix.
- - Write one or more unit tests that clearly define the expected behavior and acceptance criteria for the task.
- - **CRITICAL:** Run the tests and confirm that they fail as expected. This is the "Red" phase of TDD. Do not proceed until you have failing tests.
-
-4. **Implement to Pass Tests (Green Phase):**
- - Write the minimum amount of application code necessary to make the failing tests pass.
- - Run the test suite again and confirm that all tests now pass. This is the "Green" phase.
-
-5. **Refactor (Optional but Recommended):**
- - With the safety of passing tests, refactor the implementation code and the test code to improve clarity, remove duplication, and enhance performance without changing the external behavior.
- - Rerun tests to ensure they still pass after refactoring.
-
-6. **Verify Coverage:** Run coverage reports using the project's chosen tools. For example, in a Python project, this might look like:
- ```bash
- pytest --cov=app --cov-report=html
- ```
- Target: >80% coverage for new code. The specific tools and commands will vary by language and framework.
-
-7. **Document Deviations:** If implementation differs from tech stack:
- - **STOP** implementation
- - Update `tech-stack.md` with new design
- - Add dated note explaining the change
- - Resume implementation
-
-8. **Commit Code Changes:**
- - Stage all code changes related to the task.
- - Propose a clear, concise commit message e.g, `feat(ui): Create basic HTML structure for calculator`.
- - Perform the commit.
-
-9. **Attach Task Summary with Git Notes:**
- - **Step 9.1: Get Commit Hash:** Obtain the hash of the *just-completed commit* (`git log -1 --format="%H"`).
- - **Step 9.2: Draft Note Content:** Create a detailed summary for the completed task. This should include the task name, a summary of changes, a list of all created/modified files, and the core "why" for the change.
- - **Step 9.3: Attach Note:** Use the `git notes` command to attach the summary to the commit.
- ```bash
- # The note content from the previous step is passed via the -m flag.
- git notes add -m ""
- ```
-
-10. **Get and Record Task Commit SHA:**
- - **Step 10.1: Update Plan:** Read `plan.md`, find the line for the completed task, update its status from `[~]` to `[x]`, and append the first 7 characters of the *just-completed commit's* commit hash.
- - **Step 10.2: Write Plan:** Write the updated content back to `plan.md`.
-
-11. **Commit Plan Update:**
- - **Action:** Stage the modified `plan.md` file.
- - **Action:** Commit this change with a descriptive message (e.g., `conductor(plan): Mark task 'Create user model' as complete`).
-
-### Phase Completion Verification and Checkpointing Protocol
-
-**Trigger:** This protocol is executed immediately after a task is completed that also concludes a phase in `plan.md`.
-
-1. **Announce Protocol Start:** Inform the user that the phase is complete and the verification and checkpointing protocol has begun.
-
-2. **Ensure Test Coverage for Phase Changes:**
- - **Step 2.1: Determine Phase Scope:** To identify the files changed in this phase, you must first find the starting point. Read `plan.md` to find the Git commit SHA of the *previous* phase's checkpoint. If no previous checkpoint exists, the scope is all changes since the first commit.
- - **Step 2.2: List Changed Files:** Execute `git diff --name-only HEAD` to get a precise list of all files modified during this phase.
- - **Step 2.3: Verify and Create Tests:** For each file in the list:
- - **CRITICAL:** First, check its extension. Exclude non-code files (e.g., `.json`, `.md`, `.yaml`).
- - For each remaining code file, verify a corresponding test file exists.
- - If a test file is missing, you **must** create one. Before writing the test, **first, analyze other test files in the repository to determine the correct naming convention and testing style.** The new tests **must** validate the functionality described in this phase's tasks (`plan.md`).
-
-3. **Execute Automated Tests with Proactive Debugging:**
- - Before execution, you **must** announce the exact shell command you will use to run the tests.
- - **Example Announcement:** "I will now run the automated test suite to verify the phase. **Command:** `CI=true npm test`"
- - Execute the announced command.
- - If tests fail, you **must** inform the user and begin debugging. You may attempt to propose a fix a **maximum of two times**. If the tests still fail after your second proposed fix, you **must stop**, report the persistent failure, and ask the user for guidance.
-
-4. **Propose a Detailed, Actionable Manual Verification Plan:**
- - **CRITICAL:** To generate the plan, first analyze `product.md`, `product-guidelines.md`, and `plan.md` to determine the user-facing goals of the completed phase.
- - You **must** generate a step-by-step plan that walks the user through the verification process, including any necessary commands and specific, expected outcomes.
- - The plan you present to the user **must** follow this format:
-
- **For a Frontend Change:**
- ```
- The automated tests have passed. For manual verification, please follow these steps:
-
- **Manual Verification Steps:**
- 1. **Start the development server with the command:** `npm run dev`
- 2. **Open your browser to:** `http://localhost:3000`
- 3. **Confirm that you see:** The new user profile page, with the user's name and email displayed correctly.
- ```
-
- **For a Backend Change:**
- ```
- The automated tests have passed. For manual verification, please follow these steps:
-
- **Manual Verification Steps:**
- 1. **Ensure the server is running.**
- 2. **Execute the following command in your terminal:** `curl -X POST http://localhost:8080/api/v1/users -d '{"name": "test"}'`
- 3. **Confirm that you receive:** A JSON response with a status of `201 Created`.
- ```
-
-5. **Await Explicit User Feedback:**
- - After presenting the detailed plan, ask the user for confirmation: "**Does this meet your expectations? Please confirm with yes or provide feedback on what needs to be changed.**"
- - **PAUSE** and await the user's response. Do not proceed without an explicit yes or confirmation.
-
-6. **Create Checkpoint Commit:**
- - Stage all changes. If no changes occurred in this step, proceed with an empty commit.
- - Perform the commit with a clear and concise message (e.g., `conductor(checkpoint): Checkpoint end of Phase X`).
-
-7. **Attach Auditable Verification Report using Git Notes:**
- - **Step 7.1: Draft Note Content:** Create a detailed verification report including the automated test command, the manual verification steps, and the user's confirmation.
- - **Step 7.2: Attach Note:** Use the `git notes` command and the full commit hash from the previous step to attach the full report to the checkpoint commit.
-
-8. **Get and Record Phase Checkpoint SHA:**
- - **Step 8.1: Get Commit Hash:** Obtain the hash of the *just-created checkpoint commit* (`git log -1 --format="%H"`).
- - **Step 8.2: Update Plan:** Read `plan.md`, find the heading for the completed phase, and append the first 7 characters of the commit hash in the format `[checkpoint: ]`.
- - **Step 8.3: Write Plan:** Write the updated content back to `plan.md`.
-
-9. **Commit Plan Update:**
- - **Action:** Stage the modified `plan.md` file.
- - **Action:** Commit this change with a descriptive message following the format `conductor(plan): Mark phase '' as complete`.
-
-10. **Announce Completion:** Inform the user that the phase is complete and the checkpoint has been created, with the detailed verification report attached as a git note.
-
-### Quality Gates
-
-Before marking any task complete, verify:
-
-- [ ] All tests pass
-- [ ] Code coverage meets requirements (>80%)
-- [ ] Code follows project's code style guidelines (as defined in `code_styleguides/`)
-- [ ] All public functions/methods are documented (e.g., docstrings, JSDoc, GoDoc)
-- [ ] Type safety is enforced (e.g., type hints, TypeScript types, Go types)
-- [ ] No linting or static analysis errors (using the project's configured tools)
-- [ ] Works correctly on mobile (if applicable)
-- [ ] Documentation updated if needed
-- [ ] No security vulnerabilities introduced
-
-## Development Commands
-
-**AI AGENT INSTRUCTION: This section should be adapted to the project's specific language, framework, and build tools.**
-
-### Setup
-```bash
-# Example: Commands to set up the development environment (e.g., install dependencies, configure database)
-# e.g., for a Node.js project: npm install
-# e.g., for a Go project: go mod tidy
-```
-
-### Daily Development
-```bash
-# Example: Commands for common daily tasks (e.g., start dev server, run tests, lint, format)
-# e.g., for a Node.js project: npm run dev, npm test, npm run lint
-# e.g., for a Go project: go run main.go, go test ./..., go fmt ./...
-```
-
-### Before Committing
-```bash
-# Example: Commands to run all pre-commit checks (e.g., format, lint, type check, run tests)
-# e.g., for a Node.js project: npm run check
-# e.g., for a Go project: make check (if a Makefile exists)
-```
-
-## Testing Requirements
-
-### Unit Testing
-- Every module must have corresponding tests.
-- Use appropriate test setup/teardown mechanisms (e.g., fixtures, beforeEach/afterEach).
-- Mock external dependencies.
-- Test both success and failure cases.
-
-### Integration Testing
-- Test complete user flows
-- Verify database transactions
-- Test authentication and authorization
-- Check form submissions
-
-### Mobile Testing
-- Test on actual iPhone when possible
-- Use Safari developer tools
-- Test touch interactions
-- Verify responsive layouts
-- Check performance on 3G/4G
-
-## Code Review Process
-
-### Self-Review Checklist
-Before requesting review:
-
-1. **Functionality**
- - Feature works as specified
- - Edge cases handled
- - Error messages are user-friendly
-
-2. **Code Quality**
- - Follows style guide
- - DRY principle applied
- - Clear variable/function names
- - Appropriate comments
-
-3. **Testing**
- - Unit tests comprehensive
- - Integration tests pass
- - Coverage adequate (>80%)
-
-4. **Security**
- - No hardcoded secrets
- - Input validation present
- - SQL injection prevented
- - XSS protection in place
-
-5. **Performance**
- - Database queries optimized
- - Images optimized
- - Caching implemented where needed
-
-6. **Mobile Experience**
- - Touch targets adequate (44x44px)
- - Text readable without zooming
- - Performance acceptable on mobile
- - Interactions feel native
-
-## Commit Guidelines
-
-### Message Format
-```
-():
-
-[optional body]
-
-[optional footer]
-```
-
-### Types
-- `feat`: New feature
-- `fix`: Bug fix
-- `docs`: Documentation only
-- `style`: Formatting, missing semicolons, etc.
-- `refactor`: Code change that neither fixes a bug nor adds a feature
-- `test`: Adding missing tests
-- `chore`: Maintenance tasks
-
-### Examples
-```bash
-git commit -m "feat(auth): Add remember me functionality"
-git commit -m "fix(posts): Correct excerpt generation for short posts"
-git commit -m "test(comments): Add tests for emoji reaction limits"
-git commit -m "style(mobile): Improve button touch targets"
-```
-
-## Definition of Done
-
-A task is complete when:
-
-1. All code implemented to specification
-2. Unit tests written and passing
-3. Code coverage meets project requirements
-4. Documentation complete (if applicable)
-5. Code passes all configured linting and static analysis checks
-6. Works beautifully on mobile (if applicable)
-7. Implementation notes added to `plan.md`
-8. Changes committed with proper message
-9. Git note with task summary attached to the commit
-
-## Emergency Procedures
-
-### Critical Bug in Production
-1. Create hotfix branch from main
-2. Write failing test for bug
-3. Implement minimal fix
-4. Test thoroughly including mobile
-5. Deploy immediately
-6. Document in plan.md
-
-### Data Loss
-1. Stop all write operations
-2. Restore from latest backup
-3. Verify data integrity
-4. Document incident
-5. Update backup procedures
-
-### Security Breach
-1. Rotate all secrets immediately
-2. Review access logs
-3. Patch vulnerability
-4. Notify affected users (if any)
-5. Document and update security procedures
-
-## Deployment Workflow
-
-### Pre-Deployment Checklist
-- [ ] All tests passing
-- [ ] Coverage >80%
-- [ ] No linting errors
-- [ ] Mobile testing complete
-- [ ] Environment variables configured
-- [ ] Database migrations ready
-- [ ] Backup created
-
-### Deployment Steps
-1. Merge feature branch to main
-2. Tag release with version
-3. Push to deployment service
-4. Run database migrations
-5. Verify deployment
-6. Test critical paths
-7. Monitor for errors
-
-### Post-Deployment
-1. Monitor analytics
-2. Check error logs
-3. Gather user feedback
-4. Plan next iteration
-
-## Continuous Improvement
-
-- Review workflow weekly
-- Update based on pain points
-- Document lessons learned
-- Optimize for user happiness
-- Keep things simple and maintainable
diff --git a/docs/decisions/README.md b/docs/decisions/README.md
deleted file mode 100644
index e8916d8a3..000000000
--- a/docs/decisions/README.md
+++ /dev/null
@@ -1,15 +0,0 @@
-# Decision Records
-
-Architectural decision records and reviews. Each captures context, decision, and consequences.
-
-| Decision | File | Status |
-|---|---|---|
-| Architecture review (March 2026) | [`architecture-review-2026-03.md`](./architecture-review-2026-03.md) | Active |
-| Navigation 3 parity strategy (Android + Desktop) | [`navigation3-parity-2026-03.md`](./navigation3-parity-2026-03.md) | Active |
-| Navigation 3 API alignment audit | [`navigation3-api-alignment-2026-03.md`](./navigation3-api-alignment-2026-03.md) | Active |
-| BLE KMP strategy (Kable) | [`ble-strategy.md`](./ble-strategy.md) | Decided |
-| Hilt → Koin migration | [`koin-migration.md`](./koin-migration.md) | Complete |
-| Testing consolidation (`core:testing`) | [`testing-consolidation-2026-03.md`](./testing-consolidation-2026-03.md) | Complete |
-
-For the current KMP migration status, see [`docs/kmp-status.md`](../kmp-status.md).
-For the forward-looking roadmap, see [`docs/roadmap.md`](../roadmap.md).
diff --git a/docs/decisions/architecture-review-2026-03.md b/docs/decisions/architecture-review-2026-03.md
deleted file mode 100644
index be43f823b..000000000
--- a/docs/decisions/architecture-review-2026-03.md
+++ /dev/null
@@ -1,256 +0,0 @@
-# Architecture Review — March 2026
-
-> Status: **Active**
-> Last updated: 2026-03-31
-
-Re-evaluation of project modularity and architecture against modern KMP and Android best practices. Identifies gaps and actionable improvements across modularity, reusability, clean abstractions, DI, and testing.
-
-## Executive Summary
-
-The codebase is **~98% structurally KMP** — 18/20 core modules and 8/8 feature modules declare `jvm()` targets and cross-compile in CI. Shared `commonMain` code accounts for ~52K LOC vs ~18K platform-specific LOC (a 74/26 split). This is strong.
-
-Of the five structural gaps originally identified, four are resolved and one remains in progress:
-
-1. **`app` is a God module** — originally 90 files / ~11K LOC of transport, service, UI, and ViewModel code that should live in core/feature modules. *(✅ Resolved — app module reduced to 8 files: `MainActivity`, `MeshUtilApplication`, Nav shell, DI config, and shared map UI components)*
-2. ~~**Radio transport layer is app-locked**~~ — ✅ Resolved: `RadioTransport` interface in `core:repository/commonMain`; shared `StreamFrameCodec` + `TcpTransport` in `core:network`.
-3. ~~**`java.*` APIs leak into `commonMain`**~~ — ✅ Resolved: `Locale`, `ConcurrentHashMap`, `ReentrantLock` purged.
-4. ~~**Zero feature-level `commonTest`**~~ — ✅ Resolved: 193 shared tests across all 8 features; `core:testing` module established.
-5. ~~**No `feature:connections` module**~~ — ✅ Resolved: KMP module with shared UI and dynamic transport detection.
-
-## Source Code Distribution
-
-| Source set | Files | ~LOC | Purpose |
-|---|---:|---:|---|
-| `core/*/commonMain` | 337 | 32,700 | Shared business/data logic |
-| `feature/*/commonMain` | 146 | 19,700 | Shared feature UI + ViewModels |
-| `feature/*/androidMain` | 62 | 14,700 | Platform UI (charts, previews, permissions) |
-| `app/src/main` | 8 | ~450 | Android app shell + shared map UI components |
-| `desktop/src` | 26 | 4,800 | Desktop app shell |
-| `core/*/androidMain` | 49 | 3,500 | Platform implementations |
-| `core/*/jvmMain` | 11 | ~500 | JVM actuals |
-| `core/*/jvmAndroidMain` | 4 | ~200 | Shared JVM+Android code |
-
-**Key ratio:** 74% of production code is in `commonMain` (shared). Goal: 85%+.
-
----
-
-## A. Critical Modularity Gaps
-
-### A1. `app` module is a God module
-
-The `app` module should be a thin shell (~20 files): `MainActivity`, DI assembly, nav host, and shared flavor-agnostic UI. Originally it held **90 files / ~11K LOC**, now reduced to an **8-file shell** (6 original + 2 shared map UI components: `MapButton`, `MapControlsOverlay`):
-
-| Area | Files | LOC | Where it should live |
-|---|---:|---:|---|
-| `repository/radio/` | 22 | ~2,000 | `core:service` / `core:network` |
-| `service/` | 12 | ~1,500 | Extracted to `core:service/androidMain` ✓ |
-| `navigation/` | ~1 | ~200 | Root Nav 3 host wiring stays in `app`. Feature graphs moved to `feature:*`. |
-| `settings/` ViewModels | 3 | ~350 | Thin Android wrappers (genuine platform deps) |
-| `widget/` | 4 | ~300 | Extracted to `feature:widget` ✓ |
-| `worker/` | 4 | ~350 | Extracted to `core:service/androidMain` and `feature:messaging/androidMain` ✓ |
-| DI + Application + MainActivity | 5 | ~500 | Stay in `app` ✓ |
-| UI screens + ViewModels | 5 | ~1,200 | Stay in `app` (Android-specific deps) |
-
-**Progress:** Extracted `ChannelViewModel` → `feature:settings/commonMain`, `NodeMapViewModel` → `feature:map/commonMain`, `NodeContextMenu` → `feature:node/commonMain`, `EmptyDetailPlaceholder` → `core:ui/commonMain`. Remaining extractions require radio/service layer refactoring (bigger scope).
-
-### A2. Radio interface layer is app-locked and non-KMP
-
-The core transport abstraction was previously locked in `app/repository/radio/` via `IRadioInterface`. This has been successfully refactored:
-
-1. Defined `RadioTransport` interface in `core:repository/commonMain` (replacing `IRadioInterface`)
-2. Moved `StreamFrameCodec`-based framing to `core:network/commonMain`
-3. Moved TCP transport to `core:network/jvmAndroidMain`
-4. BLE, Serial, and Mock transports now reside in `core:network` and implement `RadioTransport`.
-
-**Recommended next steps:**
-1. Move BLE transport to `core:ble/androidMain`
-2. Move Serial/USB transport to `core:service/androidMain`
-
-### A3. No `feature:connections` module *(resolved 2026-03-12)*
-
-Device discovery UI was duplicated:
-- Android: `app/ui/connections/` (13 files: `ConnectionsScreen`, `ScannerViewModel`, 10 components)
-- Desktop: `desktop/ui/connections/DesktopConnectionsScreen.kt` (separate implementation)
-
-**Outcome:** Created `feature:connections` KMP module with:
-- `commonMain`: `ScannerViewModel`, `ConnectionsScreen`, 11 shared UI components, `DeviceListEntry` sealed class, `GetDiscoveredDevicesUseCase` interface, `CommonGetDiscoveredDevicesUseCase` (TCP/recent devices)
-- `androidMain`: `AndroidScannerViewModel` (BLE bonding, USB permissions), `AndroidGetDiscoveredDevicesUseCase` (BLE/NSD/USB discovery), `NetworkRepository`, `UsbRepository`, `SerialConnection`
-- Desktop uses the shared `ConnectionsScreen` + `CommonGetDiscoveredDevicesUseCase` directly
-- Dynamic transport detection via `RadioInterfaceService.supportedDeviceTypes`
-- Module registered in both `AppKoinModule` and `DesktopKoinModule`
-
-### A4. `core:api` AIDL coupling
-
-`core:api` is Android-only (AIDL IPC). `ServiceClient` in `core:service/androidMain` wraps it. Desktop doesn't use it — it has `DirectRadioControllerImpl` in `core:service/commonMain`.
-
-**Recommendation:** The `DirectRadioControllerImpl` pattern is correct. Ensure `RadioController` (already in `core:model/commonMain`) is the canonical interface; deprecate the AIDL-based path for in-process usage.
-
----
-
-## B. KMP Platform Purity
-
-### B1. `java.util.Locale` leaks in `commonMain` *(resolved 2026-03-11)*
-
-| File | Usage |
-|---|---|
-| `core:data/.../TracerouteHandlerImpl.kt` | Replaced with `NumberFormatter.format(seconds, 1)` |
-| `core:data/.../NeighborInfoHandlerImpl.kt` | Replaced with `NumberFormatter.format(seconds, 1)` |
-| `core:prefs/.../MeshPrefsImpl.kt` | Replaced with locale-free `uppercase()` |
-
-**Outcome:** The three `Locale` usages identified in March were removed from `commonMain`. Follow-up cleanup in the same sprint also moved `ReentrantLock`-based `SyncContinuation` to `jvmAndroidMain`, replaced prefs `ConcurrentHashMap` caches with atomic persistent maps, and pushed enum reflection behind `expect`/`actual` so no known `java.*` runtime calls remain in `commonMain`.
-
-### B2. `ConcurrentHashMap` leaks in `commonMain` *(resolved 2026-03-11)*
-
-Formerly found in 3 prefs files:
-- `core:prefs/.../MeshPrefsImpl.kt`
-- `core:prefs/.../UiPrefsImpl.kt`
-- `core:prefs/.../MapConsentPrefsImpl.kt`
-
-**Outcome:** These caches now use `AtomicRef>` helpers in `commonMain`, eliminating the last `ConcurrentHashMap` usage from shared prefs code.
-
-### B3. MQTT (Resolved)
-
-`MQTTRepositoryImpl` has been migrated to `commonMain` using KMQTT, replacing Eclipse Paho.
-
-**Fix:** Completed.
-- `kmqtt` library integrated for full KMP support.
-
-### B4. Vico charts *(resolved)*
-
-Vico chart screens (DeviceMetrics, EnvironmentMetrics, SignalMetrics, PowerMetrics, PaxMetrics) have been migrated to `feature:node/commonMain` using Vico's KMP artifacts (`vico-compose`, `vico-compose-m3`). Desktop wires them via shared composables. No Android-only chart code remains.
-
-### B5. Cross-platform code deduplication *(resolved 2026-03-21)*
-
-Comprehensive audit of `androidMain` vs `jvmMain` duplication across all feature modules. Extracted shared components:
-
-| Component | Module | Eliminated from |
-|---|---|---|
-| `AlertHost` composable | `core:ui/commonMain` | Android `Main.kt`, Desktop `DesktopMainScreen.kt` |
-| `SharedDialogs` composable | `core:ui/commonMain` | Android `Main.kt`, Desktop `DesktopMainScreen.kt` |
-| `PlaceholderScreen` composable | `core:ui/commonMain` | 4 copies: `desktop/navigation`, `feature:map/jvmMain`, `feature:node/jvmMain` (×2) |
-| `ThemePickerDialog` + `ThemeOption` | `feature:settings/commonMain` | Android `SettingsScreen.kt`, Desktop `DesktopSettingsScreen.kt` |
-| `formatLogsTo()` + `redactedKeys` | `feature:settings/commonMain` (`LogFormatter.kt`) | Android + Desktop `LogExporter.kt` actuals |
-| `handleNodeAction()` | `feature:node/commonMain` | Android `NodeDetailScreen.kt`, Desktop `NodeDetailScreens.kt` |
-| `findNodeByNameSuffix()` | `feature:connections/commonMain` | Android USB matcher, TCP recent device matcher |
-
-Also fixed `Dispatchers.IO` usage in `StoreForwardPacketHandlerImpl` (would break iOS), removed dead `UIViewModel.currentAlert` property, and added `firebase-debug.log` to `.gitignore`.
-
----
-
-## C. DI Improvements
-
-### C1. ~~Desktop manual ViewModel wiring~~ *(resolved 2026-03-13)*
-
-`DesktopKoinModule.kt` originally had ~120 lines of hand-written `viewModel { ... }` blocks. These have been successfully replaced by including Koin modules from `commonMain` generated via the Koin K2 Compiler Plugin for automatic wiring.
-
-### C2. ~~Desktop stubs lack compile-time validation~~ *(resolved 2026-03-13)*
-
-`desktopPlatformStubsModule()` previously had stubs that were only validated at runtime.
-
-**Outcome:** Added `DesktopKoinTest.kt` using Koin's `verify()` API. This test validates the entire Desktop DI graph (including platform stubs and DataStores) during the build. Discovered and fixed missing stubs for `CompassHeadingProvider`, `PhoneLocationProvider`, and `MagneticFieldProvider`.
-
-### C3. DI module naming convention
-
-Android uses `@Module`-annotated classes (`CoreDataModule`, `CoreBleAndroidModule`). Desktop imports them as `CoreDataModule().coreDataModule()`. This works but the double-invocation pattern is non-obvious.
-
-**Recommendation:** Document the pattern in AGENTS.md. Consider if Koin Annotations 2.x supports a simpler import syntax.
-
----
-
-## D. Test Architecture
-
-### D1. Zero `commonTest` in feature modules *(resolved 2026-03-12)*
-
-| Module | `commonTest` | `test`/`androidUnitTest` |
-|---|---:|---:|
-| `feature:settings` | 33 | 20 |
-| `feature:node` | 24 | 9 |
-| `feature:messaging` | 21 | 5 |
-| `feature:connections` | 27 | 0 |
-| `feature:firmware` | 15 | 25 |
-| `feature:wifi-provision` | 62 | 0 |
-
-**Outcome:** All 8 feature modules now have `commonTest` coverage (211 shared tests). Combined with 70 platform unit tests, feature modules have 281 tests total. All Compose UI tests have been migrated from `androidTest` to `commonTest` using CMP `runComposeUiTest`; instrumented test infrastructure has been removed from CI.
-
-### D2. No shared test fixtures *(resolved 2026-03-12)*
-
-`core:testing` module established with shared fakes (`FakeNodeRepository`, `FakeServiceRepository`, `FakeRadioController`, `FakePacketRepository`) and `TestDataFactory` builders. Used by all feature `commonTest` suites.
-
-### D3. Core module test gaps
-
-36 `commonTest` files exist but are concentrated in `core:domain` (22 files) and `core:data` (10 files). Limited or zero tests in:
-- `core:service` (has `ServiceRepositoryImpl`, `DirectRadioControllerImpl`, `MeshServiceOrchestrator`)
-- `core:network` (has `StreamFrameCodecTest` — 10 tests; `TcpTransport` untested)
-- `core:ble` (connection state machine)
-- `core:ui` (utility functions)
-
-`core:prefs` now has 12 `commonTest` tests (3 files: `FilterPrefsTest`, `TakPrefsTest`, `NotificationPrefsTest`) migrated from `androidHostTest` using Okio + `PreferenceDataStoreFactory.createWithPath()` for KMP compatibility.
-
-### D4. Desktop has 2 tests
-
-`desktop/src/test/` contains `DesktopKoinTest.kt` and `DesktopTopLevelDestinationParityTest.kt`. Still needs:
-- Navigation graph coverage
-
----
-
-## E. Module Extraction Priority
-
-Ordered by impact × effort:
-
-| Priority | Extraction | Impact | Effort | Enables |
-|---:|---|---|---|---|
-| 1 | ~~`java.*` purge from `commonMain` (B1, B2)~~ | High | Low | ~~iOS target declaration~~ ✅ Done |
-| 2 | Radio transport interfaces to `core:repository` (A2) | High | Medium | Transport unification |
-| 3 | `core:testing` shared fixtures (D2) | Medium | Low | Feature commonTest |
-| 4 | Feature `commonTest` (D1) | Medium | Medium | KMP test coverage |
-| 5 | `feature:connections` (A3) | High | Medium | ~~Desktop connections~~ ✅ Done |
-| 6 | Service/worker extraction from `app` (A1) | Medium | Medium | Thin app module |
-| 7 | ~~Desktop Koin auto-wiring (C1, C2)~~ | Medium | Low | ✅ Resolved 2026-03-13 |
-| 8 | MQTT KMP (B3) | Medium | High | Desktop/iOS MQTT |
-| 9 | KMP charts (B4) | Medium | High | Desktop metrics |
-| 10 | ~~iOS target declaration~~ | High | Low | ~~CI purity gate~~ ✅ Done |
-
----
-
-## Scorecard Update
-
-| Area | Previous | Current | Notes |
-|---|---:|---:|---|
-| Shared business/data logic | 8.5/10 | **9/10** | RadioTransport interface unified; all core layers shared |
-| Shared feature/UI logic | 9.5/10 | **9/10** | All 8 KMP features; connections unified; cross-platform deduplication complete |
-| Android decoupling | 8.5/10 | **9/10** | Connections, Navigation, Services, & Widgets extracted; GMS purged; app ~40->target 20 files |
-| Multi-target readiness | 8/10 | **9/10** | Full JVM; release-ready desktop; iOS simulator builds compiling successfully |
-| CI confidence | 8.5/10 | **9/10** | 26 modules validated; feature:connections + feature:wifi-provision + desktop in CI; native release installers |
-| DI portability | 7/10 | **8/10** | Koin annotations in commonMain; supportedDeviceTypes injected per platform |
-| Test maturity | — | **9/10** | Mokkery, Turbine, and Kotest integrated; property-based testing established; broad coverage across all 9 features |
-
----
-
-## F. JVM/Desktop Database Lifecycle
-
-Room KMP's `setAutoCloseTimeout` API is Android-only. On JVM/Desktop, once a Room database is built, its SQLite connections (5 per WAL-mode DB: 4 readers + 1 writer) remain open indefinitely until explicitly closed via `RoomDatabase.close()`.
-
-### Problem
-
-When a user switches between multiple mesh devices, the previous device's database remained open in the in-memory cache. Each idle database consumed ~32 MB (connection pool + prepared statement caches), leading to unbounded memory growth proportional to the number of devices ever connected in a session.
-
-### Solution
-
-`DatabaseManager.switchActiveDatabase()` now explicitly closes the previously active database via `closeCachedDatabase()` before activating the new one. The closed database is removed from the in-memory cache but its file is preserved, allowing transparent re-opening on next access.
-
-Additional fixes applied:
-1. **Init-order bug**: `dbCache` was declared after `currentDb`, causing NPE during `stateIn`'s `initialValue` evaluation. Reordered to ensure `dbCache` is initialized first.
-2. **Corruption handlers**: `ReplaceFileCorruptionHandler` added to `createDatabaseDataStore()` on both JVM and Android, preventing DataStore corruption from crashing the app.
-3. **`desktopDataDir()` deduplication**: Made public in `core:database/jvmMain` and removed the duplicate from `DesktopPlatformModule`, establishing a single source of truth for the desktop data directory.
-4. **DataStore scope consolidation**: Replaced two separate `CoroutineScope` instances with a single shared `dataStoreScope` in `DesktopPlatformModule`.
-5. **Coil cache path**: Desktop `Main.kt` updated to use `desktopDataDir()` instead of hardcoded `user.home`.
-
----
-
-## References
-
-- Current migration status: [`kmp-status.md`](./kmp-status.md)
-- Roadmap: [`roadmap.md`](./roadmap.md)
-- Agent guide: [`../AGENTS.md`](../AGENTS.md)
-- Decision records: [`decisions/`](./decisions/)
-
diff --git a/docs/decisions/navigation3-api-alignment-2026-03.md b/docs/decisions/navigation3-api-alignment-2026-03.md
deleted file mode 100644
index 6a0925152..000000000
--- a/docs/decisions/navigation3-api-alignment-2026-03.md
+++ /dev/null
@@ -1,124 +0,0 @@
-
-
-# Navigation 3 & Material 3 Adaptive — API Alignment Audit
-
-**Date:** 2026-03-26
-**Status:** Active
-**Scope:** Adoption of Navigation 3 `1.1.0-beta01` Scene APIs, transition metadata, ViewModel scoping, and Material 3 Adaptive integration.
-**Supersedes:** [`navigation3-parity-2026-03.md`](navigation3-parity-2026-03.md) Alpha04 Changelog section (versions updated).
-
-## Current Dependency Baseline
-
-| Library | Version | Group |
-|---|---|---|
-| Navigation 3 UI | `1.1.0-beta01` | `org.jetbrains.androidx.navigation3:navigation3-ui` |
-| Navigation Event | `1.1.0-alpha01` | `org.jetbrains.androidx.navigationevent:navigationevent-compose` |
-| Lifecycle ViewModel Navigation3 | `2.11.0-alpha02` | `org.jetbrains.androidx.lifecycle:lifecycle-viewmodel-navigation3` |
-| Material 3 Adaptive | `1.3.0-alpha06` | `org.jetbrains.compose.material3.adaptive:adaptive*` |
-| Material 3 Adaptive Navigation Suite | `1.11.0-alpha05` | `org.jetbrains.compose.material3:material3-adaptive-navigation-suite` |
-| Compose Multiplatform | `1.11.0-beta01` | `org.jetbrains.compose` |
-| Compose Multiplatform Material 3 | `1.11.0-alpha05` | `org.jetbrains.compose.material3:material3` |
-
-## API Audit: What's Available vs. What We Use
-
-### 1. NavDisplay — Scene Architecture (available since `1.1.0-alpha04`, stable in `beta01`)
-
-**Available APIs we're NOT using:**
-
-| API | Purpose | Status in project |
-|---|---|---|
-| `sceneStrategies: List>` | Allows NavDisplay to render multi-pane Scenes | ✅ Used — `DialogSceneStrategy`, `ListDetailSceneStrategy`, `SupportingPaneSceneStrategy`, `SinglePaneSceneStrategy` |
-| `SceneStrategy` interface | Custom scene calculation from backstack entries | ✅ Used via built-in strategies |
-| `DialogSceneStrategy` | Renders `entry(metadata = dialog())` entries as overlay Dialogs | ✅ Adopted |
-| `SceneDecoratorStrategy` | Wraps/decorates scenes with additional UI | ❌ Not used |
-| `NavEntry.metadata` | Attaches typed metadata to entries (transitions, dialog hints, Scene classification) | ✅ Used — `ListDetailSceneStrategy.listPane()`, `.detailPane()`, `.extraPane()` |
-| `NavDisplay.TransitionKey` / `PopTransitionKey` / `PredictivePopTransitionKey` | Per-entry custom transitions via metadata | ❌ Not used |
-| `transitionSpec` / `popTransitionSpec` / `predictivePopTransitionSpec` params | Default transition animations for NavDisplay | ✅ Used — 350 ms crossfade |
-| `sharedTransitionScope: SharedTransitionScope?` | Shared element transitions between scenes | ❌ Not used |
-| `entryDecorators: List>` | Wraps entry content with additional behavior | ✅ Used — `SaveableStateHolderNavEntryDecorator` + `ViewModelStoreNavEntryDecorator` |
-
-**APIs we ARE using correctly:**
-
-| API | Usage |
-|---|---|
-| `NavDisplay(backStack, entryProvider, modifier)` | Both `app/Main.kt` and `desktop/DesktopMainScreen.kt` |
-| `rememberNavBackStack(SavedStateConfiguration, startKey)` | Backstack persistence |
-| `entryProvider { entry { ... } }` | All feature graph registrations |
-| `NavigationBackHandler` from `navigationevent-compose` | Used with `ListDetailSceneStrategy` |
-
-### 2. ViewModel Scoping (`lifecycle-viewmodel-navigation3` `2.11.0-alpha02`)
-
-**Key finding:** The `ViewModelStoreNavEntryDecorator` is available and provides automatic per-entry ViewModel scoping tied to backstack lifetime. The project passes it as an `entryDecorator` to `NavDisplay` via `MeshtasticNavDisplay` in `core:ui/commonMain`.
-
-ViewModels obtained via `koinViewModel()` inside `entry` blocks are scoped to the entry's backstack lifetime and automatically cleared when the entry is popped.
-
-### 3. Material 3 Adaptive — Nav3 Scene Integration
-
-**Key finding:** The JetBrains `adaptive-navigation3` artifact at `1.3.0-alpha06` includes `ListDetailSceneStrategy` and `SupportingPaneSceneStrategy`. The project uses both via `rememberListDetailSceneStrategy` and `rememberSupportingPaneSceneStrategy` in `MeshtasticNavDisplay`, with draggable pane dividers via `VerticalDragHandle` + `paneExpansionDraggable`.
-
-This means the project **successfully** uses the M3 Adaptive Scene bridge through `NavDisplay(sceneStrategies = ...)`. Feature entries annotate themselves with `ListDetailSceneStrategy.listPane()`, `.detailPane()`, or `.extraPane()` metadata.
-
-**When to revisit:** Monitor the JetBrains adaptive fork for `MaterialListDetailSceneStrategy` inclusion. It will likely arrive when the JetBrains fork catches up to the AndroidX `1.3.0-alpha09+` feature set.
-
-### 4. NavigationSuiteScaffold (`1.11.0-alpha05`)
-
-**Status:** ✅ Adopted (2026-03-26). `MeshtasticNavigationSuite` now uses `NavigationSuiteScaffold` with `calculateFromAdaptiveInfo()` and custom `NavigationSuiteType` coercion. No further alignment needed.
-
-## Prioritized Opportunities
-
-### P0: Add `ViewModelStoreNavEntryDecorator` to NavDisplay (high-value, low-risk)
-
-**Status:** ✅ Adopted (2026-03-26). Each backstack entry now gets its own `ViewModelStoreOwner` via `rememberViewModelStoreNavEntryDecorator()`. ViewModels obtained via `koinViewModel()` are automatically cleared when their entry is popped. Encapsulated in `MeshtasticNavDisplay` in `core:ui/commonMain`.
-
-**Impact:** Fixes subtle ViewModel leaks where popped entries retain their ViewModel in the Activity/Window store. Eliminates the need for manual `key = "metrics-$destNum"` ViewModel keying patterns over time.
-
-### P1: Add default NavDisplay transitions (medium-value, low-risk)
-
-**Status:** ✅ Adopted (2026-03-26). A shared 350 ms crossfade (`fadeIn` + `fadeOut`) is applied for both forward and pop navigation via `MeshtasticNavDisplay`. This replaces the library's platform defaults (Android: 700 ms fade; Desktop: no animation) with a faster, consistent transition.
-
-**Impact:** Immediate UX improvement on both Android and Desktop. Desktop now has visible navigation transitions.
-
-### P2: Adopt `DialogSceneStrategy` for navigation-driven dialogs (medium-value, medium-risk)
-
-**Status:** ✅ Adopted (2026-03-26). `MeshtasticNavDisplay` includes `DialogSceneStrategy` in `sceneStrategies` before `SinglePaneSceneStrategy`. Feature modules can now use `entry(metadata = DialogSceneStrategy.dialog()) { ... }` to render entries as overlay Dialogs with proper backstack lifecycle and predictive-back support.
-
-**Impact:** Cleaner dialog lifecycle management available for future dialog routes. Existing dialogs via `AlertHost` are unaffected.
-
-### Consolidation: `MeshtasticNavDisplay` shared wrapper
-
-**Status:** ✅ Adopted (2026-03-26). A new `MeshtasticNavDisplay` composable in `core:ui/commonMain` encapsulates the standard `NavDisplay` configuration:
-- Entry decorators: `rememberSaveableStateHolderNavEntryDecorator` + `rememberViewModelStoreNavEntryDecorator`
-- Scene strategies: `DialogSceneStrategy` + `SinglePaneSceneStrategy`
-- Transition specs: 350 ms crossfade (forward + pop)
-
-Both `app/Main.kt` and `desktop/DesktopMainScreen.kt` now call `MeshtasticNavDisplay` instead of configuring `NavDisplay` directly. The `lifecycle-viewmodel-navigation3` dependency was moved from host modules to `core:ui`.
-
-### P3: Per-entry transition metadata (low-value until Scene adoption)
-
-Individual entries can declare custom transitions via `entry(metadata = NavDisplay.transitionSpec { ... })`. This is most useful when different route types should animate differently (e.g., detail screens slide in, settings screens fade).
-
-**Impact:** Polish improvement. Low priority until default transitions (P1) are established. Now unblocked by P1 adoption.
-
-### Deferred: Custom Scene strategies
-
-The `ListDetailSceneStrategy` and `SupportingPaneSceneStrategy` are adopted and working. Consider writing additional custom `SceneStrategy` implementations for specialized layouts (e.g., three-pane "Power User" scenes) as the Navigation 3 Scene API matures.
-
-## Decision
-
-~~Adopt **P0** (ViewModel scoping) and **P1** (default transitions) now. Defer P2/P3 and Scene-based multi-pane until the JetBrains adaptive fork adds `MaterialListDetailSceneStrategy`.~~
-
-**Updated 2026-03-26:** P0, P1, and P2 adopted and consolidated into `MeshtasticNavDisplay` in `core:ui/commonMain`. P3 (per-entry transitions) is available for incremental adoption by feature modules. Scene-based multi-pane remains deferred.
-
-## References
-
-- Navigation 3 source: `navigation3-ui` `1.1.0-beta01` (inspected from Gradle cache)
-- [`NavDisplay.kt`](https://cs.android.com/androidx/platform/frameworks/support/+/main:navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/ui/NavDisplay.kt) (upstream)
-- [`SceneStrategy.kt`](https://cs.android.com/androidx/platform/frameworks/support/+/main:navigation3/navigation3-ui/src/commonMain/kotlin/androidx/navigation3/scene/SceneStrategy.kt) (upstream)
-- Material 3 Adaptive JetBrains fork: `org.jetbrains.compose.material3.adaptive` `1.3.0-alpha06`
diff --git a/docs/decisions/navigation3-parity-2026-03.md b/docs/decisions/navigation3-parity-2026-03.md
deleted file mode 100644
index 1d1a8c7ed..000000000
--- a/docs/decisions/navigation3-parity-2026-03.md
+++ /dev/null
@@ -1,167 +0,0 @@
-
-
-# Navigation 3 Parity Strategy (Android + Desktop)
-
-**Date:** 2026-03-11
-**Status:** Implemented (2026-03-21)
-**Scope:** `app` and `desktop` navigation structure using shared `core:navigation` routes
-
-## Context
-
-Desktop and Android both use Navigation 3 typed routes from `core:navigation`. Previously graph wiring had diverged — desktop used a separate `DesktopDestination` enum with 6 entries (including a top-level Firmware tab) while Android used 5 entries.
-
-This has been resolved. Both shells now use the shared `TopLevelDestination` enum from `core:navigation/commonMain` with 5 entries (Conversations, Nodes, Map, Settings, Connections). Firmware is an in-flow route on both platforms.
-
-Both modules still define separate graph-builder files (`app/navigation/*.kt`, `desktop/navigation/*.kt`) with different destination coverage and placeholder behavior, but the **top-level shell structure is unified**.
-
-## Current-State Findings
-
-1. **Top-level destinations are unified.**
- - Both shells iterate `TopLevelDestination.entries` from `core:navigation/commonMain`.
- - Shared icon mapping lives in `core:ui` (`TopLevelDestinationExt.icon`).
- - Parity tests exist in both `core:navigation/commonTest` (`NavigationParityTest`) and `desktop/test` (`DesktopTopLevelDestinationParityTest`).
-2. **Feature coverage is unified via `commonMain` feature graphs.**
- - The `settingsGraph`, `nodesGraph`, `contactsGraph`, `connectionsGraph`, `firmwareGraph`, and `mapGraph` are now fully shared and exported from their respective feature modules' `commonMain` source sets.
- - Desktop acts as a thin shell, delegating directly to these shared graphs.
-3. **Saved-state route registration is fully shared.**
- - `MeshtasticNavSavedStateConfig` in `core:navigation/commonMain` maintains the unified `SavedStateConfiguration` serializer list.
- - Both Android and Desktop reference this shared config when instantiating `rememberNavBackStack`.
-4. **Predictive back handling is KMP native.**
- - Custom `PredictiveBackHandler` wrapper was removed in favor of Jetpack's official KMP `NavigationBackHandler` from `androidx.navigationevent:navigationevent-compose`.
-
-## Alpha04 → Beta01 Changelog Impact Check
-
-Source reviewed: Navigation 3 `1.1.0-beta01` (JetBrains fork), CMP `1.11.0-beta01`, Lifecycle `2.11.0-alpha02`.
-
-> **Superseded by:** [`navigation3-api-alignment-2026-03.md`](navigation3-api-alignment-2026-03.md) for the full API surface audit and Scene architecture adoption plan.
-
-1. **NavDisplay API updated to Scene-based architecture.**
- - The `sceneStrategy: SceneStrategy` parameter is deprecated in favor of `sceneStrategies: List>`.
- - New `sceneDecoratorStrategies: List>` parameter available.
- - New `sharedTransitionScope: SharedTransitionScope?` parameter for shared element transitions.
- - Existing shell patterns in `app` and `desktop` remain valid using the default `SinglePaneSceneStrategy`.
-2. **Entry-scoped ViewModel lifecycle adopted.**
- - Both `app` and `desktop` now use `MeshtasticNavDisplay` (`core:ui/commonMain`), which applies `ViewModelStoreNavEntryDecorator` + `SaveableStateHolderNavEntryDecorator` per active backstack.
- - ViewModels obtained via `koinViewModel()` inside `entry` blocks are now scoped to the entry's backstack lifetime.
-3. **No direct Navigation 3 API breakage.**
- - Release is beta (API stabilized). No migration from alpha04 was required for existing usage patterns.
-4. **Primary risk is dependency wiring drift, not runtime behavior.**
- - JetBrains Navigation 3 currently publishes `navigation3-ui` coordinates (no separate `navigation3-runtime` artifact in Maven Central). The `jetbrains-navigation3-runtime` alias intentionally points to `navigation3-ui` and is documented in the version catalog.
- - Note: The `remember*` composable factory functions from `navigation3-runtime` are not visible in non-KMP Android modules due to Kotlin metadata resolution. Use direct class constructors instead (as done in `app/Main.kt`).
-5. **Saved-state and typed-route parity improved.**
- - Both hosts share `MeshtasticNavSavedStateConfig` from `core:navigation/commonMain` via `MultiBackstack`, reducing platform drift risk in serializer registration.
-6. **Updated active docs to reflect the current dependency baseline (`1.11.0-beta01`, `1.1.0-beta01`, `1.3.0-alpha06`, `2.11.0-alpha02`).**
-
-### Actions Taken
-
-- Renamed all JetBrains-forked lifecycle/nav3 version catalog aliases from `androidx-*` to `jetbrains-*` prefix to make fork provenance unambiguous:
- - `jetbrains-lifecycle-runtime`, `jetbrains-lifecycle-runtime-compose`, `jetbrains-lifecycle-viewmodel-compose`, `jetbrains-lifecycle-viewmodel-navigation3`
- - `jetbrains-navigation3-runtime`, `jetbrains-navigation3-ui`
-- Documented in the version catalog that `jetbrains-navigation3-runtime` intentionally maps to `navigation3-ui` until a separate runtime artifact is published.
-- Migrated `core:data` `commonMain` from `androidx.lifecycle:lifecycle-runtime` (Google) to `org.jetbrains.androidx.lifecycle:lifecycle-runtime` (JetBrains fork) for full consistency.
-- Updated active docs to reflect the current dependency baseline (`1.11.0-beta01`, `1.1.0-beta01`, `1.3.0-alpha06`, `2.11.0-alpha02`).
-- Consolidated `app` adaptive dependencies to JetBrains Material 3 Adaptive coordinates (`org.jetbrains.compose.material3.adaptive:*`) so Android and Desktop consume the same adaptive artifact family. The Android-only navigation suite remains on `androidx.compose.material3:material3-adaptive-navigation-suite`.
-
-### Deferred Follow-ups
-
-- Add automated validation that desktop serializer registrations stay in sync with shared route keys.
-
-## Options Evaluated
-
-### Option A: Reuse `:app` navigation implementation directly in desktop
-
-**Pros**
-- Maximum short-term parity in structure.
-
-**Cons**
-- `:app` graph code is tightly coupled to Android wrappers (`Android*ViewModel`, Android-only screen wrappers, app-specific UI state like scroll-to-top flows).
-- Pulling this code into desktop would either fail at compile-time or force additional platform branching in app files.
-- Violates clean module boundaries (`desktop` should not depend on Android-specific app glue).
-
-**Decision:** Not recommended.
-
-### Option B: Keep fully separate desktop graph and replicate app behavior manually
-
-**Pros**
-- Lowest refactor cost right now.
-- Keeps platform customization simple.
-
-**Cons**
-- Drift is guaranteed over time.
-- No central policy for intentional vs accidental divergence.
-- High maintenance burden for parity-sensitive flows.
-
-**Decision:** Not recommended as a long-term strategy.
-
-### Option C (Recommended): Hybrid shared contract + platform graph adapters
-
-**Pros**
-- Preserves platform-specific wiring where needed.
-- Reduces drift by moving parity-sensitive definitions to shared contracts.
-- Enables explicit, testable exceptions for desktop-only or Android-only behavior.
-
-**Cons**
-- Requires incremental extraction work.
-- Needs light governance (parity matrix + tests + docs).
-
-**Decision:** Recommended.
-
-## Decision
-
-Adopt a **hybrid parity model**:
-
-1. Keep platform graph registration in `app` and `desktop`.
-2. Extract parity-sensitive navigation metadata into shared contracts (top-level destination set/order, route ownership map, and allowed platform exceptions).
-3. Keep platform-specific destination implementations as adapters around shared route keys.
-4. Add route parity tests so drift is detected automatically.
-
-## Implementation Plan
-
-### Phase 1 (Immediate): Stop drift on shell structure ✅
-
-- ✅ Aligned desktop top-level destination policy with Android (removed Firmware from top-level; kept as in-flow).
-- ✅ Both shells now use shared `TopLevelDestination` enum from `core:navigation/commonMain`.
-- ✅ Shared icon mapping in `core:ui` (`TopLevelDestinationExt.icon`).
-- Parity matrix documented inline: top-level set is Conversations, Nodes, Map, Settings, Connections on both platforms.
-
-### Phase 2 (Near-term): Extract shared navigation contracts ✅ (partially)
-
-- ✅ Shared `TopLevelDestination` enum with `fromNavKey()` already serves as the canonical metadata object.
-- Both `app` and `desktop` shells iterate `TopLevelDestination.entries` — no separate `DesktopDestination` enum remains.
-- Remaining: optional visibility flags by platform, route grouping metadata (lower priority since shells are unified).
-
-### Phase 3 (Near-term): Add parity checks ✅ (partially)
-
-- ✅ `NavigationParityTest` in `core:navigation/commonTest` — asserts 5 top-level destinations and `fromNavKey` matching.
-- ✅ `DesktopTopLevelDestinationParityTest` in `desktop/test` — asserts desktop routes match Android parity set and firmware is not top-level.
-- Remaining: assert every desktop serializer registration corresponds to an actual route; assert every intentional exception is listed.
-
-### Phase 4 (Mid-term): Reduce app-specific graph coupling
-
-- Move reusable graph composition helpers out of `:app` where practical (while keeping Android-only wrappers in Android source sets).
-- Keep desktop-specific placeholder implementations, but tie them to explicit parity exception entries.
-
-## Consequences
-
-- Navigation behavior remains platform-adaptive, but parity expectations become explicit and enforceable.
-- Desktop can keep legitimate deviations (map/charts/platform integrations) without silently changing IA.
-- New route additions will require touching one shared contract plus platform implementations, making review scope clearer.
-
-## Source Anchors
-
-- Shared routes: `core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/Routes.kt`
-- Shared saved-state config: `core/navigation/src/commonMain/kotlin/org/meshtastic/core/navigation/NavigationConfig.kt`
-- Android shell: `app/src/main/kotlin/org/meshtastic/app/ui/Main.kt`
-- Shared graph registrations: `feature/*/src/commonMain/kotlin/org/meshtastic/feature/*/navigation/`
-- Platform graph content: `feature/*/src/{androidMain,jvmMain}/kotlin/org/meshtastic/feature/*/navigation/`
-- Desktop shell: `desktop/src/main/kotlin/org/meshtastic/desktop/ui/DesktopMainScreen.kt`
-- Desktop graph assembly: `desktop/src/main/kotlin/org/meshtastic/desktop/navigation/DesktopNavigation.kt`
-
-
diff --git a/docs/kmp-status.md b/docs/kmp-status.md
index 1f8ce1062..bea19e8c3 100644
--- a/docs/kmp-status.md
+++ b/docs/kmp-status.md
@@ -1,6 +1,6 @@
# KMP Migration Status
-> Last updated: 2026-04-10
+> Last updated: 2026-04-13
Single source of truth for Kotlin Multiplatform migration progress. For the forward-looking roadmap, see [`roadmap.md`](./roadmap.md). For completed decision records, see [`decisions/`](./decisions/).
@@ -49,7 +49,7 @@ Modules that share JVM-specific code between Android and desktop now standardize
| `feature:messaging` | ✅ | ✅ Adaptive contacts + messages; fully shared `contactsGraph`, `MessageScreen`, `ContactsScreen`, and `MessageListPaged` |
| `feature:connections` | ✅ | ✅ Shared `ConnectionsScreen` with dynamic transport detection |
| `feature:intro` | — | — | Screens remain in `androidMain`; shared ViewModel only |
-| `feature:map` | — | Placeholder; shared `NodeMapViewModel`, `BaseMapViewModel`, and `TracerouteNodeSelection`. Map rendering decomposed into 3 `CompositionLocal` provider contracts (`MapViewProvider`, `NodeTrackMapProvider`, `TracerouteMapProvider`) with per-flavor implementations in `:app` |
+| `feature:map` | — | Placeholder; shared `NodeMapViewModel`, `BaseMapViewModel`. Map rendering decomposed into 3 `CompositionLocal` provider contracts (`MapViewProvider`, `NodeTrackMapProvider`, `TracerouteMapProvider`) with per-flavor implementations in `:app` |
| `feature:firmware` | ✅ | ✅ Fully KMP: Unified OTA, native Secure DFU, USB/UF2, FirmwareRetriever |
| `feature:wifi-provision` | ✅ | ✅ KMP WiFi provisioning via BLE (Nymea protocol); shared UI and ViewModel |
| `feature:widget` | ❌ | — | Android-only (Glance appwidgets). Intentional. |
@@ -79,9 +79,7 @@ Working Compose Desktop application with:
| Multi-target readiness | **9/10** | Full JVM; release-ready desktop; iOS simulator builds compiling successfully |
| CI confidence | **9/10** | 26 modules validated (including feature:wifi-provision); native release installers automated |
| DI portability | **8/10** | Koin annotations in commonMain; supportedDeviceTypes injected per platform |
-| Test maturity | **9/10** | Mokkery, Turbine, and Kotest integrated; property-based testing established; broad coverage across all 9 features |
-
-> See [`decisions/architecture-review-2026-03.md`](./decisions/architecture-review-2026-03.md) for the full gap analysis.
+| Test maturity | **9/10** | Mokkery, Turbine, and Kotest integrated; property-based testing established; broad coverage across all 9 features. Gaps: `core:service`, `core:network` (TcpTransport), `core:ble` state machine, `core:ui` utils, desktop navigation graphs |
## Completion Estimates
@@ -105,11 +103,11 @@ Based on the latest codebase investigation, the following steps are proposed to
| Decision | Status | Details |
|---|---|---|
-| Navigation 3 parity model (shared `TopLevelDestination` + platform adapters) | ✅ Done | See [`decisions/navigation3-parity-2026-03.md`](./decisions/navigation3-parity-2026-03.md) |
+| Navigation 3 parity model (shared `TopLevelDestination` + platform adapters) | ✅ Done | Both shells use shared `TopLevelDestination` enum and `MeshtasticNavDisplay` from `core:ui/commonMain`; parity tests in `core:navigation/commonTest` |
| Hilt → Koin | ✅ Done | See [`decisions/koin-migration.md`](./decisions/koin-migration.md) |
| BLE abstraction (Kable) | ✅ Done | See [`decisions/ble-strategy.md`](./decisions/ble-strategy.md) |
| Firmware KMP migration (pure Secure DFU) | ✅ Done | Native Nordic Secure DFU protocol reimplemented in pure KMP using Kable; desktop is first-class target |
-| Material 3 Adaptive (JetBrains) | ✅ Done | Version `1.3.0-alpha06` aligned with CMP `1.11.0-beta01`; supports Large (1200dp) and Extra-large (1600dp) breakpoints |
+| Material 3 Adaptive (JetBrains) | ✅ Done | Version `1.3.0-alpha06` aligned with CMP `1.11.0-beta02`; supports Large (1200dp) and Extra-large (1600dp) breakpoints |
| JetBrains lifecycle/nav3 alias alignment | ✅ Done | All forked deps use `jetbrains-*` prefix in version catalog; `core:data` commonMain uses JetBrains lifecycle runtime |
| Expect/actual consolidation | ✅ Done | 7 pairs eliminated; 15+ genuinely platform-specific retained |
| Transport deduplication | ✅ Done | `StreamFrameCodec`, `TcpTransport`, and `SerialTransport` shared in `core:network` |
@@ -127,7 +125,7 @@ Based on the latest codebase investigation, the following steps are proposed to
- Firmware remains available as an in-flow route instead of a top-level destination, matching Android information architecture.
- Android navigation graphs are decoupled and extracted into their respective feature modules, aligning with the Desktop architecture.
- Parity tests exist in `core:navigation/commonTest` (`NavigationParityTest`) and `desktop/test` (`DesktopTopLevelDestinationParityTest`).
-- Remaining parity work is documented in [`decisions/navigation3-parity-2026-03.md`](./decisions/navigation3-parity-2026-03.md): serializer registration validation and platform exception tracking.
+- Remaining parity work: serializer registration validation and platform exception tracking.
## App Module Thinning Status
@@ -159,19 +157,17 @@ Remaining to be extracted from `:app` or unified in `commonMain`:
| Dependency | Version | Why |
|---|---|---|
-| Compose Multiplatform | `1.11.0-beta01` | Required for JetBrains Adaptive `1.3.0-alpha06` and Material 3 `1.11.0-alpha05` |
-| Compose Multiplatform Material 3 | `1.11.0-alpha05` | Material 3 components including `NavigationSuiteScaffold` |
-| Koin | `4.2.0` | Nav3 + K2 compiler plugin support |
-| JetBrains Lifecycle | `2.11.0-alpha02` | Multiplatform ViewModel/lifecycle; includes `lifecycle-viewmodel-navigation3` for entry-scoped ViewModels |
-| JetBrains Navigation 3 | `1.1.0-beta01` | Multiplatform navigation with Scene architecture, `NavEntry.metadata`, transition specs |
+| Compose Multiplatform | `1.11.0-beta02` | Required for JetBrains Adaptive `1.3.0-alpha06` and Material 3 `1.11.0-alpha06` |
+| Compose Multiplatform Material 3 | `1.11.0-alpha06` | Material 3 components including `NavigationSuiteScaffold` |
+| Koin | `4.2.1` | Nav3 + K2 compiler plugin support |
+| JetBrains Lifecycle | `2.11.0-alpha03` | Multiplatform ViewModel/lifecycle; includes `lifecycle-viewmodel-navigation3` for entry-scoped ViewModels |
+| JetBrains Navigation 3 | `1.1.0-rc01` | Multiplatform navigation with Scene architecture, `NavEntry.metadata`, transition specs |
| JetBrains Navigation Event | `1.1.0-alpha01` | KMP `NavigationBackHandler` for predictive back |
| JetBrains Material 3 Adaptive | `1.3.0-alpha06` | `ListDetailPaneScaffold`, `ThreePaneScaffold`, Large/XL breakpoints |
| Kable BLE | `0.42.0` | Provides fully multiplatform BLE support |
**Policy:** Stable by default. RC when it unlocks KMP functionality. Alpha only behind hard abstraction seams. Do not downgrade CMP or Koin — they enable critical KMP features.
-> See [`decisions/navigation3-api-alignment-2026-03.md`](./decisions/navigation3-api-alignment-2026-03.md) for the full Navigation 3 API surface audit and Scene architecture adoption plan.
-
## References
- Roadmap: [`docs/roadmap.md`](./roadmap.md)
diff --git a/docs/roadmap.md b/docs/roadmap.md
index 9c9445485..d97995bb4 100644
--- a/docs/roadmap.md
+++ b/docs/roadmap.md
@@ -2,7 +2,7 @@
> Last updated: 2026-04-10
-Forward-looking priorities for the Meshtastic KMP multi-target effort. For current state, see [`kmp-status.md`](./kmp-status.md). For the full gap analysis, see [`decisions/architecture-review-2026-03.md`](./decisions/architecture-review-2026-03.md).
+Forward-looking priorities for the Meshtastic KMP multi-target effort. For current state, see [`kmp-status.md`](./kmp-status.md).
## Architecture Health (Immediate)
diff --git a/docs/testing/baseline_coverage.md b/docs/testing/baseline_coverage.md
deleted file mode 100644
index 6445ea9e5..000000000
--- a/docs/testing/baseline_coverage.md
+++ /dev/null
@@ -1,6 +0,0 @@
-# Baseline Test Coverage Report
-**Date:** Wednesday, March 18, 2026
-**Overall Project Coverage:** 8.796%
-**App Module Coverage:** 1.6404%
-
-This baseline was captured using `./gradlew koverLog` at the start of the 'Expand Testing Coverage' track.
\ No newline at end of file
diff --git a/docs/testing/final_coverage.md b/docs/testing/final_coverage.md
deleted file mode 100644
index bc502d704..000000000
--- a/docs/testing/final_coverage.md
+++ /dev/null
@@ -1,18 +0,0 @@
-# Final Test Coverage Report
-**Date:** Wednesday, March 18, 2026
-**Overall Project Coverage:** 10.2591% (Baseline: 8.796%)
-**Absolute Increase:** +1.46%
-
-## Module Highlights
-| Module | Coverage | Notes |
-| :--- | :--- | :--- |
-| `core:domain` | 26.55% | UseCase gap fill complete. |
-| `feature:intro` | 30.76% | ViewModel tests enabled. |
-| `feature:map` | 33.33% | BaseMapViewModel tests refactored. |
-| `feature:node` | 24.70% | Metrics, Detail, Compass, and Filter tests added/refactored. |
-| `feature:connections` | 26.49% | ScannerViewModel verified. |
-| `feature:messaging` | 18.54% | MessageViewModel verified. |
-
-This report concludes the 'Expand Testing Coverage' track.
-Significant improvements were made in ViewModel testability through interface extraction and Mokkery/Turbine migration.
-Foundational logic in `core:network` was strengthened with Kotest property-based tests.
\ No newline at end of file