Skip to content

BLE connection/sync redundancy, derivation concurrency, platform-standards compliance - #44

Merged
abdulsaheel merged 2 commits into
mainfrom
feat/ble-sync-redundancy
Jul 8, 2026
Merged

BLE connection/sync redundancy, derivation concurrency, platform-standards compliance#44
abdulsaheel merged 2 commits into
mainfrom
feat/ble-sync-redundancy

Conversation

@abdulsaheel

Copy link
Copy Markdown
Collaborator

Summary

BLE reliability — closes gaps found in a full audit of the reconnect/sync ladder (connection timeouts, corruption detection, band-reboot signal, per-chunk sync ledger + quarantine, staleness escalation notification, activated schemaHealth()) and verifies the implementation against official Android/Apple documentation rather than community folklore (notably: gated the OEM-autostart deep link behind ActivityManager.isBackgroundRestricted(), and made notification-permission requests respect the platform rule that authorization must come from a foreground context, never a headless one).

Derivation engine concurrency — the real fix for "results aren't ready when the app opens." Backlog sweeps (run/runDays/rescanRecent) were fully sequential single-threaded for-loops that also computed the oldest pending day first and today last. Replaced with a bounded worker-pool (runWithConcurrency) that runs multiple independent days' isolate work genuinely in parallel across cores, plus newest-first ordering so today lands first.

CI/Xcode (teammate's changes, included in this PR): strips the Watch companion from the unsigned sideload IPA (its WKCompanionAppBundleIdentifier can't survive a per-user resign under any sideloading tool), and adds a build phase to re-sign ad-hoc-signed native-assets frameworks — verified as a no-op under --no-codesign via an actual build log.

Test plan

  • flutter test --concurrency=1 — 434/434 green (62 new tests)
  • flutter analyze — 11 pre-existing issues only, zero new
  • flutter build apk --debug — clean
  • flutter build ios --debug --no-codesign — clean, including after the Xcode project change (verified the new re-sign build phase correctly no-ops via verbose build log)
  • All standards claims verified against fetched official docs (developer.android.com, developer.apple.com), not recalled from memory

…-standards compliance

BLE reliability (connection ladder + sync integrity):
- Timeout discoverServices()/setNotifyValue() so a wedged BLE stack can't
  hang the connect chain forever and jam the whole reconnect ladder above it
- FrameCorruptionDetector: CRC-failure-rate detector, independent of the
  existing timeout-based MarginalRadioDetector (catches a radio that
  responds promptly but wrong, not just one that stops responding)
- Band-truth reconciliation: track expectedPacketCount mismatch streaks
  over time instead of only logging once
- CounterRegressionDetector: explicit, observable band-reboot signal,
  seeded from the durable counter_hw cursor across reconnects
- Periodic RTC re-verification on long-lived connections (previously only
  checked once at connect)
- isCorruptFutureRtc: sanity-check GET_DATA_RANGE's range_newest before it
  can poison the session's plausibility window
- Real per-chunk sync_ledger (ChunkFailureLedger) + wired sync_quarantine
  read/write — a token failing ACK repeatedly across reconnects is now
  tracked and quarantined instead of silently overwriting one shared row
- Activated schemaHealth() (real PRAGMA integrity_check) at startup + on
  the foreground cadence — was fully implemented but never called
- Removed dead, unwired, untested Whoop5EmptyOffloadTracker
- HeadlessSyncGate skip-streak telemetry (per-owner + lifetime counters)
- Cross-platform staleness escalation: local notification at 48h+ silence,
  quiet in-app tier at 12h, wired into both the headless and foreground
  cadence paths
- Android OEM autostart deep links (Xiaomi/Huawei/Honor/Oppo/Vivo/OnePlus),
  gated behind ActivityManager.isBackgroundRestricted() (the one official
  documented signal) rather than firing on manufacturer-string match alone
- iOS force-quit explainer tied to the staleness notification
- Per-checkpoint diagnostic logging in commitSyncBatch (decoded/archive/
  cursor phases) via a failure-safe optional callback, atomicity unchanged
- Notification permission requests now respect platform docs: background/
  headless code paths only check (never request) authorization, since an
  interactive prompt requires a foreground scene the OS won't grant one to
  from a background execution context

Derivation engine concurrency (single-threaded backlog sweeps were the
biggest contributor to "results aren't ready when the app opens"):
- runWithConcurrency: bounded worker-pool primitive replacing three
  identical fully-sequential per-day for-loops (run/runDays/rescanRecent).
  A multi-day backlog used to process one day's isolate work fully before
  starting the next, leaving every core but one idle; days within a run
  are independent (frozen baseline snapshot, day_id-keyed writes) so this
  is genuinely safe to parallelize
- Newest-first day ordering — a backlog sweep used to compute the oldest
  pending day first and today dead last, backwards from what the user
  actually wants on open
- Per-day-local prepare-stats accumulator so concurrent days don't race on
  shared diagnostic counters (telemetry-only; never a correctness issue for
  the derived values themselves)

All changes verified against official Android/Apple documentation (not
community folklore) where platform behavior was load-bearing. 434 Dart
tests green (62 new), zero new analyzer issues, Android debug APK and iOS
debug build both verified.
…sets frameworks

The Watch app's Info.plist carries a literal WKCompanionAppBundleIdentifier
that must exactly match the phone app's bundle id. Every free-account
resigner (Sideloadly, AltStore) mints its own unique per-user bundle id
without patching that unrelated nested plist key, so the Watch companion
fails install for every sideloaded user under every resigner. Drop it from
the unsigned CI artifact only; source builds via Xcode/flutter run keep
full Watch support with a consistent signing identity.

Also adds a "Re-sign ad-hoc native-assets frameworks" build phase: Dart's
native-assets pipeline copies compiled frameworks into the app bundle via
Flutter's own script rather than Xcode's auto-signing Copy Files mechanism,
so they can end up ad-hoc-signed instead of matching the app's real signing
identity, which fails code-signing validation on-device. Runs after both
Embed Frameworks and CP Embed Pods Frameworks, re-signs only frameworks
actually detected as ad-hoc via codesign -dv, and is a verified no-op when
code signing isn't active (confirmed in a local --no-codesign build log).
@abdulsaheel
abdulsaheel merged commit a1e2b19 into main Jul 8, 2026
@abdulsaheel abdulsaheel mentioned this pull request Jul 8, 2026
@abdulsaheel
abdulsaheel deleted the feat/ble-sync-redundancy branch July 12, 2026 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant