74 lines
15 KiB
Markdown
74 lines
15 KiB
Markdown
# MotorSignal QA execution — 2026-10-01
|
||
|
||
QA lead: root. Product-code owner: hazard investigator; root took file ownership after its focused work ended. P2 investigator exclusively owned `emulator-5556` and `permission.md`; browser investigator owned their session and report; auth investigator owned fixture scripts/results. Root later exclusively owned Playwright session `motorsignal-qa` and `emulator-5554`. No device or browser session was shared while active. No merge, deploy, purchase, production setting change, or production data mutation occurred.
|
||
|
||
## P0 baseline
|
||
|
||
- Repository: `C:\Users\Bill\Desktop\flutter-app`; branch `release/v1.0.2-build102-community-feed`; HEAD `d378db4c86e02518b2d02d1fa030ac569ee238bb`.
|
||
- Source worktree was already dirty at baseline. Preserve all changes. Initial patch and file manifest: `baseline.patch`, `baseline-files.json`. Final state: `final-status.txt`, `final-tracked.patch`, `final-files.json` (refresh after final closeout edits).
|
||
- Current default Firebase project: `motoapp-d22e0` (`lib/firebase_options.dart`); this is production configuration. Isolated SDK fixture project: `demo-motorsignal-qa`, Auth `127.0.0.1:9099`, Firestore `127.0.0.1:8088`; loopback emulator services were stopped at closeout. `tools/qa_auth_main.dart` selects emulators and requires `R2_WORKER_URL=http://127.0.0.1:1`; it ran under isolated QA flavor. QA services used `adb reverse` to host-only ports 9299/8288 and were stopped after checks.
|
||
- Flutter `3.44.6` stable, framework `ee80f08bbf`; Dart `3.12.2`; DevTools `2.57.0`. Android SDK/build tools `37.0.0`; emulator `36.6.11.0`; ADB `1.0.41` / platform tools `37.0.0-14910828`. `flutter doctor -v` reports missing Android cmdline-tools, although requested build/test commands completed.
|
||
- Windows 11 build `28120.2760`; Node `v24.14.0`; npm `11.9.0`; Edge `155.0.4283.24`; Chrome `154.0.8037.58`; browser owner used Codex in-app browser and Edge popup flow. Devices available: Pixel 8 Pro AVD `emulator-5554`, API 37; dedicated fresh Pixel 8 Pro AVD `emulator-5556`, API 37 (P2); attached ONN TV `FUSA2529023938` (not used for mobile QA). Physical Pixel 8a was not attached.
|
||
- Initial tested APK: `app-debug.apk`, package `app.motorsignal.motorcycle`, 102/1.0.2, SHA-256 `279F561D8DB91D01138321EE2666B2029D239BC6008809E802458FF835796AA2`. Follow-up QA APK: `app-qa-debug.apk`, package `app.motorsignal.motorcycle.qa`, 102/1.0.2, SHA-256 `1EDB7FC2DF04C6640A3B593D69794071156C2F21A708D3477ED6940E933237E2`; resolved component `app.motorsignal.motorcycle.qa/app.motorsignal.motorcycle.MainActivity`, Android user 0. Required standard command `flutter build apk --debug` also passed using production flavor; `app-production-debug.apk`, package `app.motorsignal.motorcycle`, 102/1.0.2, SHA-256 `8FBFC7D55864224D1C387CE013E5395FE853C884A0F2E1AB3A12D63357B02B4`. The production-configured APK was not installed for QA.
|
||
|
||
## P1 hazard submission
|
||
|
||
**Source/regression result: PASS. Runtime emulator result: PARTIAL / BLOCKED.** The supplied baseline test was run against original modal code and failed reproducibly: delayed GPS resolution yielded zero reports where one was expected (`hazard-baseline-red.log`). The focused fixed suite passed **23/23**: 11 modal lifecycle tests plus 12 Swarm service tests (`hazard-test.log`). Regression coverage includes delayed location, user dismissal during GPS, closing during exit animation, duplicate taps, missing location, GPS/last-known timeout and retry, confirmed/rejected/pending cloud writes, provider-scope removal during write, and fake persisted document verification.
|
||
|
||
The fix converts the modal to `ConsumerStatefulWidget`, takes provider service references before awaiting, applies bounded GPS/last-known waits, cancels safely after route dismissal, guards context/provider use by mounted/current route, prevents repeated submits, and reports local/cloud outcome. No schema or telemetry path changed.
|
||
|
||
The installed package and build were inspected with manifest, package manager resolver, package version, and Android user. The resolver returned `app.motorsignal.motorcycle.qa/app.motorsignal.motorcycle.MainActivity`; explicit launch succeeded. There was no packaging defect; the earlier assumed component/error was stale/mis-targeted. Existing test data was copied and same-ID `adb install -r` preserved it. Isolated QA Firebase/Auth Firestore accepted a hazard from the app. Admin read verified `road_alerts/swarm_1790854134314_1_P2z7H`, category hazard, anonymous UID prefix `P2z7HFWM0`, `reportedAt=1790854134314`, coordinates 37.7749/-122.4193983 matching injected GPS. A prior rapid-tap run from same QA source produced one additional record for two taps, but was on an earlier package build. Full current-build checks, dismissal during a live pending await, permission/location failure feedback and deterministic backend rejection remain **BLOCKED / UNTESTED**. No hazard was submitted to production. Full details in `android-launch-followup.md`.
|
||
|
||
## P2 permission and ANR
|
||
|
||
Dedicated investigator report: `permission.md`; raw current-session ANR dump: `historical-anr-dropbox.txt`. Historical Dropbox evidence contains a real Android `data_app_anr`, 2026-09-30 18:52:28 EDT: `Input dispatching timed out` waiting 5,017 ms for `MainActivity` FocusEvent. Captured main-thread samples were idle in the Looper in one dump and in Flutter `EventChannel.success` from the sensors plugin callback in another; emulator CPU was 99% (81% kernel). This proves Android classified a MainActivity ANR, but does not prove permission denial caused it. Current emulator `lastanr` has no new event. Fresh dedicated-AVD test reproduced permission denial while keeping dashboard usable (`NO GPS`, `STANDBY`); Settings grant required tapping in-app Enable to clear stale banner and show `GPS 3D FIX`. Revocation during recording caused documented Android permission-revocation process kill; no crash/ANR was observed. Ride and 704 telemetry samples survived in SQLite and were recovered after relaunch; GPS-off recording remained degraded; restoring global location produced no new emulator fix, so reacquisition remains blocked and no app defect is confirmed. Full scenarios and timestamps are in `permission.md`.
|
||
|
||
## P3/P4 isolated authenticated workflows
|
||
|
||
**Automated backend checks: PASS; Flutter/browser authenticated end-to-end: BLOCKED.** Six disposable demo accounts cover owner, admin, organizer/club admin, participant, member, and outsider. Client SDK scenarios: **24/24 PASS** (`auth.results.json`, `auth.extra-results.json`); existing Firestore rules suite: **148/148 PASS** (`auth.rules-results.json`). Security rules were not weakened; credentials were not saved. These tests prove SDK behavior with real rules, not browser/mobile UI, process restart, or independent auth persistence. Firebase services were not listening at closeout; accounts/fixtures were ephemeral emulator state.
|
||
|
||
Initial activity assumption was resolved by package-manager component resolution; isolated QA app launch and hazard persistence now pass as detailed in `android-launch-followup.md`. Isolated browser sign-in, token verification, cookie/session exchange and protected session requests pass against a verified loopback fixture. Authenticated Flutter role workflows against a real MotorSignal API remain unverified; SDK/rules checks are distinct evidence.
|
||
|
||
## P5 browser separation
|
||
|
||
Public production Group Rides showcase filtering was directly exercised: Track Pace reduced five sample cards to one. Deployed revision: `9bc16329ef539371e62cea175c89df8de6accd8f`; latest repository website-touching commit `71cd994b2f177417e1d67d62a95125b496d35f32`; these differ. Website `npm run build` passed; focused Firebase emulator wiring tests **6/6 PASS**. Follow-up sign-in, local token verification, cookie exchange, and protected session requests all returned 200. Organizer ride creation persisted in Firestore emulator. Public member discovery is blocked by scoped Hub queries/rules; join-code success is simulated, with no membership write; approval UI was not found. Production profile/API integration and authenticated mobile flows remain unverified. Details in `website-auth-followup.md`.
|
||
|
||
### Follow-up — isolated website session and Group Ride Hub
|
||
|
||
`website-auth-followup.md` records a separate demo project, three browser sessions, real Firebase Google sign-in, Firebase Admin ID-token verification, same-origin session exchange, Secure cookie issuance, and protected session reads: all returned **200**. Local fixture deliberately implements only token/session verification; account profile `GET /api/v1/me` returned fixture 404, and email login returned fixture 401 because that test path is intentionally unsupported. Earlier root-run 401s came from the local Next route's default remote API base when no override was supplied; the remote endpoint was not called again, so its exact rejection reason remains unverified. Test setup now uses explicit loopback API override and demo Firebase project/ports; config and auth form focused Vitest tests pass **7/7**, `npm run build` passed after the error-feedback fix. Authenticated Hub organizer creation passed against Firestore emulator, but user-scoped member queries correctly yielded empty result. Simulated join/approval remain blocked/unimplemented.
|
||
|
||
Authenticated organizer created a group ride through the real Firestore client SDK and emulator rules; Admin SDK confirmed the persisted record and organizer participant. Separate member account discovered no rides. Source and rules show user-scoped Hub list queries and list authorization for organizer/access UIDs/club admins; `public` permits point reads but not collection listing. Community discovery therefore remains unsupported by current list query/rule contract. Join-code UI showed success but made no Firestore write; request-slot handler only changes React state, and no web approval flow was found. Member join/approval are **BLOCKED / unimplemented in exercised website path**, not passes. Emulator fixtures/users were cleared; owned services and browser sessions stopped. See `website-auth-followup.md` for evidence and screenshots.
|
||
|
||
## P6–P9 data, exports, offline, lifecycle
|
||
|
||
- Social feed cross-account, restart, and sign-out persistence: **UNTESTED**. Source has canonical in-memory demo items, synchronous local updates, and optional Firestore writes, but no initial Firestore read/listener; widget tab navigation is not persistence evidence.
|
||
- Legitimate Pro CSV export and GPX/CSV contents comparison: **BLOCKED**. No isolated Play tester entitlement/token plus verifier credentials/configuration. Paywall is not export success. No test purchase or production entitlement mutation.
|
||
- Offline recording/reconnect/server synchronization: **BLOCKED**. No verified network-isolation tool or server-side sync inspection used. Do not infer sync from local persistence/outbox.
|
||
- Pause/resume domain path: automated regression PASS in `forensic_lifecycle_audit_test.dart`; preserves ride ID/cloud ID and excludes paused samples. No recording-cancel path was found/exposed; recording cancel remains untested. Group-ride cancellation is separate and SDK/rule-tested, not recording cancel.
|
||
|
||
## P10 unique-row reconciliation
|
||
|
||
Re-read matrix rows directly and extracted bold IDs; 44 unique IDs, no duplicates. By original verification tags: 32 emulator, 5 browser, 3 automated web, 4 hardware. Earlier summary's emulator groups total 30; adding SOC-06/SOC-07 yields 32 matrix rows. The prose claim of “24 emulator workflows” is not supported by these rows. GRP-01/CLB-01/CLB-02 appear in summary only and are not extra matrix rows.
|
||
|
||
Non-overlapping current classification of the 44 existing rows: **3 automated**, **36 legacy runtime smoke claims** (31 mobile rows plus 5 browser rows; do not treat as current authenticated E2E), **2 blocked** (MAP-03 device retest and HW-01 dongle), **3 hardware-required** (HW-02..04), **0 unclassified**. Current added evidence is separately identified above; it does not silently convert legacy screenshots/claims into current passes. Historical screenshot smoke evidence is under `qa_screenshots/` and prior report.
|
||
|
||
## P11/P12 validation and cleanup
|
||
|
||
- `flutter test`: **1,422 passed**, `All tests passed!`.
|
||
- `flutter analyze`: **No issues found** (193.1 s).
|
||
- `flutter build apk --debug`: **PASS**, 97.2 s Gradle build. Warnings: Java restricted native access and Flutter plugin `flutter_tts` applying Kotlin Gradle Plugin; no build errors.
|
||
- `npm run build` in `website/`: **PASS after latest auth form change**, TypeScript and 37 static pages generated.
|
||
- Website focused Firebase emulator config and auth form tests: **7 passed**. Firebase SDK auth exercise: **24 passed**. Existing Firestore rules: **148 passed**.
|
||
- `git diff --check`: no whitespace errors; CRLF normalization warnings for existing modified files only.
|
||
- No production data/settings, external billing, account, or deployment changes. Demo Auth/Firestore cleanup endpoints returned HTTP 200; Playwright browser, local website server, Auth and Firestore emulator services stopped. P2 dedicated AVD and logcat were cleaned by its owner. Evidence and hashes retained. P1 emulator app data remained unchanged after install; no report submitted.
|
||
- Final source status/hash manifests are `final-status.txt`, `final-tracked.patch`, and `final-files.json`. The manifest leaves its own recursive hash blank by design. No files staged or committed.
|
||
|
||
## Exact unresolved blockers
|
||
|
||
1. P1 device matrix is partial: success and isolated persistence, correct injected coordinates, launch, plus rapid tap suppression on an earlier QA build verified. Dismissal during active await, repeated taps on final suffixed package, permission/location failure and deterministic backend failure outcomes remain unverified; runtime overall BLOCKED.
|
||
2. Website browser session and organizer create are verified against local demo services, not production MotorSignal server. Exact production API rejection for earlier 401s remains unknown because endpoint intentionally not called; profile route absent in fixture. Public member discovery does not match scoped queries/rules; join success is canned, backend join/approval UI absent. Authenticated browser multi-user lifecycle therefore blocked after organizer creation. Authenticated Flutter server workflows/restart persistence remain unverified.
|
||
3. No legitimate isolated Google Play Pro entitlement/verifier; entitled CSV export is blocked.
|
||
4. Effective network isolation and backend sync inspection unavailable; end-to-end offline server sync blocked.
|
||
5. A fresh GPS fix reached the app during the QA-auth run (hazard coordinates match injected fix); a later clean Pixel 8 Pro AVD reboot could not reproduce provider delivery (`dumpsys location last location=null`). Permission recovery and recording process-restart were previously verified on the isolated AVD, but GPS-off then fresh-fix restoration and its app timestamp remain blocked. Historical ANR cause remains unresolved.
|
||
6. Physical OBD-II and motorcycle hardware scenarios require hardware; recording-cancel domain path is not exposed.
|