Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
abe57fd
Add project refactoring audit and ignore local tmp directory
xarleyn Sep 1, 2026
fe53ec5
Fix LoRa service leaks, races, and teardown determinism
xarleyn Sep 1, 2026
64d362d
Make sample import atomic, dedupe queries, fix settings export gaps
xarleyn Sep 1, 2026
5911404
Allow picking any file for database import on Android
xarleyn Sep 1, 2026
0f8f49d
Harden location and carpeater services against dispose races
xarleyn Sep 1, 2026
606e94f
Update agent conventions and mark audit items fixed
xarleyn Sep 1, 2026
2bfadf5
Group root tests into prefix subdirectories per convention
xarleyn Sep 1, 2026
ea81281
Deduplicate batch upload loop and drop deprecated wrapper
xarleyn Sep 1, 2026
7f7edb4
Deduplicate protocol byte readers and drop dead raw log parser
xarleyn Sep 1, 2026
b1fc778
Move Carpeater password to secure storage and drop unused deps
xarleyn Sep 1, 2026
be61544
Fix all analyzer infos and move dropdown widgets out of utils
xarleyn Sep 1, 2026
4ca67ae
Extract shared pumpDialog harness for dialog widget tests
xarleyn Sep 1, 2026
f33a782
Refresh project docs and mark upstream MQTT sections
xarleyn Sep 2, 2026
095227a
Extract update check flow from map screen state
xarleyn Sep 2, 2026
190b40f
Avoid void_checks lint in dialog test closures
xarleyn Sep 2, 2026
7b7eebb
Extract data import and export flows from map screen
xarleyn Sep 2, 2026
5f1e67b
Extract map annotations persistence into controller
xarleyn Sep 2, 2026
e24b6b4
Extract Android tracking permission flow from map screen
xarleyn Sep 2, 2026
445acba
Extract radio connection and contact flows from map screen
xarleyn Sep 2, 2026
558aeb7
Extract upload, community coverage, and offline tile flows
xarleyn Sep 2, 2026
286fa7a
Extract theme flows and ducting presentation helpers
xarleyn Sep 2, 2026
203b08d
Split map screen initialization into staged phases
xarleyn Sep 2, 2026
8cd89d1
Extract manual ping recording into a service
xarleyn Sep 2, 2026
baa336a
Refresh documentation status and add doc-impact config
xarleyn Sep 2, 2026
d49b325
Rebalance doc-impact rules and document Carpeater mode
xarleyn Sep 2, 2026
1fb390b
Add feature guides for the main fork capabilities
xarleyn Sep 2, 2026
365519a
Exclude privacy-zone samples from file exports
xarleyn Sep 2, 2026
475c706
Cover database backup export and restore with round-trip tests
xarleyn Sep 3, 2026
3932b76
Cover DatabaseService CRUD, JSON import, and stats with host tests
xarleyn Sep 3, 2026
e202c9a
Cover DatabaseService schema creation and migrations on host SQLite
xarleyn Sep 3, 2026
3d2b883
Cover model JSON and SQLite serialization round trips
xarleyn Sep 3, 2026
94f583f
Finish MapControlPanel callback reconciliation and layer stack extrac…
xarleyn Sep 3, 2026
9cfb52c
Release v1.0.45-x
xarleyn Sep 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
222 changes: 222 additions & 0 deletions .dsh/doc-impact.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
# Documentation-impact rules for the dsh-doc-impact plugin
# (https://github.com/xarleyn/dsh-plugins/tree/main/plugins/dsh-doc-impact).
#
# When an agent turn touches the code globs of a rule, the plugin asks the
# agent to review or update the linked documents and resolve the impact via
# doc_impact_resolve. Keep rules precise: each code glob should map only to
# documents that actually describe that code. Personal overrides belong in
# .dsh/doc-impact.local.yml (git-ignored).
version: 1
defaults:
mode: remind
scope: turn
changeDetection: auto
rules:
# The map screen composition root is being slimmed down; its structure and
# the refactoring plan must move together (steps and live checklist live in
# the plan document).
- id: map-refactoring-plan
description: Map screen structure is tracked by the refactoring plan
code:
include:
- lib/screens/map_screen.dart
- lib/screens/map/**
exclude:
- "**/*.g.dart"
docs:
- docs/development/map-screen-refactoring.md
direction: bidirectional
relation: synchronized
mode: require-review

# The companion guide and the ping-debugging notes describe the behavior
# and frame flow implemented by these services.
- id: lora-companion-guide
description: Companion radio, protocol, and ping debugging documentation
code:
- lib/services/lora_companion_service.dart
- lib/services/meshcore_protocol.dart
- lib/services/manual_ping_service.dart
docs:
- docs/guides/lora-companion.md
- docs/development/debugging-pings.md
direction: code-to-docs
relation: documents

# Carpeater mode is a fork-specific feature with its own user guide.
- id: carpeater-guide
description: Carpeater mode guide
code:
- lib/services/carpeater_service.dart
- lib/screens/settings/sections/carpeater_section.dart
docs:
- docs/guides/carpeater.md
direction: code-to-docs
relation: documents

# Release tooling, signing configuration, and the release workflow define
# the documented release process.
- id: release-process
description: Release builds, versioning, signing, and GitHub Actions
code:
- tool/version.dart
- tool/build_release.ps1
- android/app/build.gradle.kts
- android/key.properties.example
- .github/workflows/release.yml
docs:
- docs/development/releasing.md
direction: bidirectional
relation: specification

# Installation steps mirror the requested Android permissions.
- id: installation-docs
description: Permissions and installation steps
code:
- android/app/src/main/AndroidManifest.xml
docs:
- docs/INSTALLATION.md
direction: code-to-docs
relation: documents

# Quick-start and the positioning guide document tracking, quality
# filtering, and positioning behavior; each mapped service implements a
# section of those documents.
- id: getting-started
description: Quick-start and positioning guides
code:
- lib/services/location_service.dart
- lib/services/location_quality_filter.dart
- lib/services/bad_fix_monitor.dart
- lib/services/radio_position_estimator.dart
- lib/services/wifi_location_service.dart
- lib/widgets/compass_calibration.dart
docs:
- docs/getting-started.md
- docs/guides/positioning.md
direction: code-to-docs
relation: documents

# Export format examples follow the export builders, data flows, and the
# database backup service.
- id: export-format
description: Data export and backup documentation
code:
- lib/utils/sample_export.dart
- lib/screens/map/data_io.dart
- lib/services/database_backup_service.dart
docs:
- docs/getting-started.md
- docs/guides/data-management.md
- docs/guides/lora-companion.md
direction: code-to-docs
relation: documents

# Version bumps sync the in-app constant and are recorded in the changelog
# and the fork changelog draft.
- id: changelog-version
description: Version bumps are recorded in the changelogs
code:
- lib/constants/app_version.dart
- tool/version.dart
docs:
- CHANGELOG.md
- docs/changelog-fork-ru.md
direction: code-to-docs
relation: synchronized

# Design specs describe implemented features; keep them synchronized.
- id: impossible-zones-spec
description: Impossible Zones design spec
code:
- lib/models/impossible_zone.dart
- lib/services/location_quality_filter.dart
- lib/services/bad_fix_monitor.dart
docs:
- docs/superpowers/specs/2026-08-20-impossible-zones-design.md
direction: bidirectional
relation: specification

- id: fresh-session-map-spec
description: Fresh session map view design spec
code:
- lib/widgets/tracking_play_button.dart
- lib/screens/map/map_screen_controller.dart
docs:
- docs/superpowers/specs/2026-08-19-fresh-session-map-design.md
direction: bidirectional
relation: specification

# Recording sessions are a fork feature with their own guide.
- id: recording-sessions-guide
description: Recording sessions guide
code:
- lib/widgets/tracking_play_button.dart
- lib/screens/session_history_screen.dart
docs:
- docs/guides/recording-sessions.md
direction: code-to-docs
relation: documents

# Markers and zones have their own guide.
- id: markers-zones-guide
description: Markers and zones guide
code:
- lib/screens/map/map_annotations_controller.dart
- lib/screens/map/dialogs/marker_dialogs.dart
- lib/screens/map/layers/zone_overlay_layer.dart
- lib/screens/map/layers/planned_marker_layer.dart
docs:
- docs/guides/markers-and-zones.md
direction: code-to-docs
relation: documents

# Upload, community coverage, offline tiles, and connectivity detection.
- id: online-coverage-guide
description: Online coverage features guide
code:
- lib/services/upload_service.dart
- lib/screens/map/layers/community_coverage_layer.dart
- lib/services/internet_connectivity_service.dart
docs:
- docs/guides/online-coverage.md
direction: code-to-docs
relation: documents

# Analytics screens and achievements have their own guide.
- id: analytics-guide
description: Analytics and statistics guide
code:
- lib/screens/analytics_screen.dart
- lib/screens/repeater_health_screen.dart
- lib/screens/signal_trend_screen.dart
- lib/screens/device_comparison_screen.dart
- lib/screens/achievements_screen.dart
- lib/services/achievement_service.dart
docs:
- docs/guides/analytics.md
direction: code-to-docs
relation: documents

# The tile provider investigation tracks the provider choice and the
# offline download policy.
- id: map-providers
description: Map provider choice and offline tile policy
code:
- lib/services/tile_download_service.dart
- lib/screens/map/dialogs/offline_tile_dialogs.dart
docs:
- docs/development/map-providers.md
- docs/guides/online-coverage.md
direction: code-to-docs
relation: related

# AGENTS.md points at analysis_options.yaml as the lint convention.
- id: agent-conventions
description: Repository lint conventions in AGENTS.md
code:
- analysis_options.yaml
docs:
- AGENTS.md
direction: bidirectional
relation: specification
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ app.*.map.json

# Local AI tooling
.aider*
.dsh/doc-impact.local.yml

# Local scratch scripts and data exports
/tmp/

# Environment files may contain secrets
.env
Expand Down
20 changes: 17 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ stores observations in SQLite, and renders aggregated coverage on a map.
- `lib/services/`: location, radio, protocol, storage, settings, logging, and
upload integrations.
- `lib/utils/`: reusable helpers without UI responsibilities.
- `lib/widgets/`: reusable widgets shared across screens.
- `lib/l10n/`: localization inputs; generated outputs under `lib/l10n/generated/`.
- `lib/constants/`: generated version constant synced by `tool/version.dart`.
- `tool/`: developer scripts for versioning and release builds (`version.dart`,
`build_release.ps1`).
- `android/`: the only maintained Flutter host platform.
- `test/`: unit and widget tests, grouped into subdirectories by name prefix
such as `test/bluetooth/` and `test/map/`; shared helpers stay in
Expand Down Expand Up @@ -68,7 +73,9 @@ not launch concurrent release builds. If a build runner was interrupted and a
subsequent build reports that an intermediate file such as `base.jar` is in
use, first confirm that no build is still active. A stale Gradle daemon for this
project can then be stopped from `android/` with `gradlew.bat --stop` before
retrying once.
retrying once. On a fresh clone the Gradle wrapper (`gradlew.bat` and its JAR)
is absent until the first `flutter run` or `flutter build` regenerates it,
because `android/.gitignore` excludes those files.

The full analyzer may report existing diagnostics outside the current change.
Still run it, and also use targeted analysis for edited files when needed to
Expand Down Expand Up @@ -97,8 +104,10 @@ or a physical LoRa device, describe any manual device testing that remains.
`lowerCamelCase` members.
- Keep asynchronous lifecycle cleanup explicit: cancel subscriptions, timers,
and device connections when their owner is disposed.
- Keep secrets and device credentials out of source control. Store runtime
credentials with the existing secure-storage abstraction.
- Keep secrets and device credentials out of source control and out of
exported settings files. A credential that must persist on the device is
stored with platform secure storage, never in plaintext
`SharedPreferences`, and never included in settings export/import.
- Add or update tests for behavior that can be exercised without physical
hardware. Isolate device and network boundaries so they can be faked.
- Prefer placing new tests in the `test/` subdirectory matching the test name
Expand Down Expand Up @@ -135,6 +144,11 @@ or a physical LoRa device, describe any manual device testing that remains.
output. Distribute binaries through GitHub Releases.
- Update documentation and examples when changing commands, paths, settings, or
user-visible behavior.
- `.dsh/doc-impact.yml` maps source areas to the documents they affect for the
`dsh-doc-impact` agent plugin. When a change touches files covered by a rule,
review or update the linked documents and resolve the impact with the
plugin's `doc_impact_resolve` tool before finishing the turn. Personal
overrides belong in `.dsh/doc-impact.local.yml`, which is not committed.

## Architecture notes

Expand Down
46 changes: 46 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,51 @@
# Changelog

## v1.0.45-x - 2026-09-03

### Changed

- Privacy-zone protection now also covers file exports: JSON, CSV, GPX, and
KML exports drop samples inside privacy zones the same way uploads already
did, so shared files never contain them. The SQLite database backup stays a
complete snapshot by design — it is the only export that keeps privacy-zone
data. Export snackbars and share texts report the filtered sample count.

- Carpeater passwords move from plaintext settings to Android secure storage.
A password entered in Carpeater settings is never written to
SharedPreferences and is never included in settings export/import; a legacy
plaintext password saved by an older version migrates to secure storage on
its next read, so updating an existing installation keeps the saved
password.

### Fixed

- Database import on Android: the system file picker greys out `.db` files
because Android has no MIME mapping for that extension, making backups
impossible to select. The picker now accepts any file, and the picked file
is validated by content (SQLite signature, expected schema, schema version)
before anything is replaced.

- Sample import (JSON) is now atomic: rows are validated before the
transaction and applied in a single batch, so a malformed row is skipped
instead of leaving a half-applied import behind. Duplicate samples are
skipped and the reported count reflects the rows actually imported.

- Fixed resource leaks and races in the LoRa companion service; teardown on
disconnect and dispose is now deterministic.

- Fixed dispose races in the location and Carpeater services that could crash
or leave listeners attached when tracking stopped mid-operation.

### Technical

- Continued map screen decomposition: staged initialization, extracted
connection/theme/upload/offline-tile/update flows, manual ping recording
moved into `ManualPingService`, typed callback objects for the control
panel and action buttons, and an extracted `MapLayerStack` widget.
- Host-SQLite test infrastructure (`sqflite_common_ffi`) and 60+ new tests
covering the database backup export/restore round trip, `DatabaseService`
CRUD, JSON import, schema migrations, and model serialization.

## v1.0.44-x - 2026-09-01

### Breaking change
Expand Down
Loading