PLAN.md: add missing status icons, fix stale phase cross-reference

Formatting-only pass, no information changed:
- Added missing checkmarks to Phase 7 and Phase 9 headers (were plain
  'DONE' text while every other completed phase uses '✅ DONE').
- Added a status icon to the un-numbered SIM868 cellular fallback
  section ('⚠️ built, UNTESTED').
- Added a consistent '🚧 PLANNED' icon to Phases 12-17, which had no
  status icon at all.
- Fixed a stale cross-reference in the Phase 6 update ('see Phase 9
  update below' -> 'see Phase 11 update below' - the phone-relay
  content it points to has always lived under Phase 11).

Co-authored-by: Copilot <[email protected]>
This commit is contained in:
Mathieu Moran
2026-08-09 16:50:42 -04:00
co-authored by Copilot
parent e280f9ac96
commit 5877f16c9a
+10 -10
View File
@@ -237,7 +237,7 @@ HTTP 200 with no port number from another machine on the network. (Real hotspot
the Pi's LAN IP are intentionally not recorded in this file — see local, non-committed notes.) the Pi's LAN IP are intentionally not recorded in this file — see local, non-committed notes.)
**Update — real-hardware bug found + fixed (hotspot->home reconnect was flaky)**: while testing **Update — real-hardware bug found + fixed (hotspot->home reconnect was flaky)**: while testing
the phone-relay feature live (see Phase 9 update below), `yaris-netwatch` repeatedly logged "home the phone-relay feature live (see Phase 11 update below), `yaris-netwatch` repeatedly logged "home
WiFi not found" 4 times in a row over ~13 minutes while sitting right next to the router — a real WiFi not found" 4 times in a row over ~13 minutes while sitting right next to the router — a real
regression from the original design, not a one-off fluke. Root cause: a plain `nmcli con up regression from the original design, not a one-off fluke. Root cause: a plain `nmcli con up
home-wifi` straight out of AP mode relies on NM's scan cache for `wlan0`, which is stale/empty home-wifi` straight out of AP mode relies on NM's scan cache for `wlan0`, which is stale/empty
@@ -250,7 +250,7 @@ take up to ~80s, default systemd 90s start timeout was too tight). Verified fixe
both hotspot->home transitions after the fix recovered in ~7 seconds (previously failing outright). both hotspot->home transitions after the fix recovered in ~7 seconds (previously failing outright).
Deployed: `sudo cp deploy/yaris-netwatch.sh /usr/local/bin/... && cp .service ... && daemon-reload`. Deployed: `sudo cp deploy/yaris-netwatch.sh /usr/local/bin/... && cp .service ... && daemon-reload`.
### Phase 7: app_db.py / app_sql.py fixes — DONE ### Phase 7: app_db.py / app_sql.py fixes — ✅ DONE
Neither file was called from `app.py` or anywhere else - orphaned from a prior iteration. Fixed: Neither file was called from `app.py` or anywhere else - orphaned from a prior iteration. Fixed:
- `app_db.py`: applied a prior-session stash fix - resolves `.env` path via `__file__` (was - `app_db.py`: applied a prior-session stash fix - resolves `.env` path via `__file__` (was
cwd-relative), fixes `os.getenv()` calls to pass the actual key names (was called with zero cwd-relative), fixes `os.getenv()` calls to pass the actual key names (was called with zero
@@ -333,7 +333,7 @@ cleanly after being interrupted once by the OOM crash below - `copy_files()`'s s
copied logic meant re-running `/api/dash/import` just picked up the remaining files, no data loss copied logic meant re-running `/api/dash/import` just picked up the remaining files, no data loss
or re-copy of the first 19 files). SD card unmounted cleanly afterward. or re-copy of the first 19 files). SD card unmounted cleanly afterward.
### Phase 9: Remote server for itinerary/dashcam upload — DONE ### Phase 9: Remote server for itinerary/dashcam upload — ✅ DONE
Per architecture decisions #4 and #5: self-hosted server/API to receive itinerary (from the Per architecture decisions #4 and #5: self-hosted server/API to receive itinerary (from the
SQLite pipeline) and dashcam file uploads. SQLite pipeline) and dashcam file uploads.
@@ -449,7 +449,7 @@ the user (e.g. a data-blocking USB cable/adapter, or plugging/unplugging appropr
before recording vs. before importing. Worth revisiting if it becomes tedious in daily use (e.g. a before recording vs. before importing. Worth revisiting if it becomes tedious in daily use (e.g. a
Pi-controlled USB data-line switch), but out of scope for now. Pi-controlled USB data-line switch), but out of scope for now.
### SIM868 cellular fallback for tracking uploads — built, UNTESTED (no SIM card available) ### SIM868 cellular fallback for tracking uploads — ⚠️ built, UNTESTED (no SIM card available)
`modules/app_cellular.py` gives the tracking-upload path a fallback over the SIM868's cellular `modules/app_cellular.py` gives the tracking-upload path a fallback over the SIM868's cellular
data connection when WiFi/Ethernet is unreachable. Design notes: data connection when WiFi/Ethernet is unreachable. Design notes:
- Uses the SIM868's built-in AT-command HTTP(S) client (`AT+HTTPINIT`/`HTTPPARA`/`HTTPACTION`/ - Uses the SIM868's built-in AT-command HTTP(S) client (`AT+HTTPINIT`/`HTTPPARA`/`HTTPACTION`/
@@ -643,7 +643,7 @@ workaround currently in place for that specific case.
**Side-fix from this test session**: found and fixed a real, unrelated bug in `yaris-netwatch.sh` **Side-fix from this test session**: found and fixed a real, unrelated bug in `yaris-netwatch.sh`
during this same test — see the Phase 6 update above. during this same test — see the Phase 6 update above.
### Phase 12: Remove phone-relay feature — PLANNED ### Phase 12: Remove phone-relay feature — 🚧 PLANNED
Undo Phase 11 cleanly given the Phase 11 update above (fundamental browser platform limitation, Undo Phase 11 cleanly given the Phase 11 update above (fundamental browser platform limitation,
not fixable). Remove: not fixable). Remove:
- `app.py`: `/api/dash/pending`, `/api/dash/file/<path>`, `/api/dash/relay/config`, - `app.py`: `/api/dash/pending`, `/api/dash/file/<path>`, `/api/dash/relay/config`,
@@ -661,7 +661,7 @@ not fixable). Remove:
avoid rehashing its 20GB+ backlog every loop), `DASHCAM_CHUNK_SIZE`/Cloudflare 100MB avoid rehashing its 20GB+ backlog every loop), `DASHCAM_CHUNK_SIZE`/Cloudflare 100MB
workaround - none of that is relay-specific. workaround - none of that is relay-specific.
### Phase 13: Dashcam USB file browser (list + delete) — PLANNED ### Phase 13: Dashcam USB file browser (list + delete) — 🚧 PLANNED
Replace the current all-or-nothing "Import videos" flow's blind spot (no visibility into what's Replace the current all-or-nothing "Import videos" flow's blind spot (no visibility into what's
actually on the camera) with a real file browser for the mounted USB dashcam device: actually on the camera) with a real file browser for the mounted USB dashcam device:
- New endpoint(s) in `modules/app_dash.py` to list every video file on the mounted dashcam - New endpoint(s) in `modules/app_dash.py` to list every video file on the mounted dashcam
@@ -680,7 +680,7 @@ actually on the camera) with a real file browser for the mounted USB dashcam dev
select-mode/data-communication toggle behavior - the user replugs power manually to return the select-mode/data-communication toggle behavior - the user replugs power manually to return the
camera to recording mode, as they already do. camera to recording mode, as they already do.
### Phase 14: Local imported-video browser + player — PLANNED ### Phase 14: Local imported-video browser + player — 🚧 PLANNED
Same file-browser treatment for videos already imported to the Pi's own disk Same file-browser treatment for videos already imported to the Pi's own disk
(`dash/videos/`, populated by `import_dashcam()`): (`dash/videos/`, populated by `import_dashcam()`):
- List endpoint (reuses `find_video_files()` against `app_dash.DEFAULT_DESTINATION`) showing - List endpoint (reuses `find_video_files()` against `app_dash.DEFAULT_DESTINATION`) showing
@@ -699,7 +699,7 @@ Same file-browser treatment for videos already imported to the Pi's own disk
"Play" action that opens the video inline, and a delete button per row with a confirmation "Play" action that opens the video inline, and a delete button per row with a confirmation
prompt. prompt.
### Phase 15: OBD real-hardware readiness (code hardening) — PLANNED ### Phase 15: OBD real-hardware readiness (code hardening) — 🚧 PLANNED
Nothing has been installed or tested in the actual 2013 Yaris yet - `modules/app_obd.py` has Nothing has been installed or tested in the actual 2013 Yaris yet - `modules/app_obd.py` has
only ever been tested standalone on the Pi with nothing plugged into the OBD-II port (correctly only ever been tested standalone on the Pi with nothing plugged into the OBD-II port (correctly
reports "no connection to car"). Per explicit user decision, this phase is **code hardening reports "no connection to car"). Per explicit user decision, this phase is **code hardening
@@ -739,7 +739,7 @@ all in `modules/app_obd.py` / `modules/app_events.py`:
(falls under "code hardening only" for now - add the query with graceful "unsupported" handling (falls under "code hardening only" for now - add the query with graceful "unsupported" handling
rather than assuming it will work). rather than assuming it will work).
### Phase 16: Complete web UI redesign — PLANNED ### Phase 16: Complete web UI redesign — 🚧 PLANNED
The current `templates/`/`static/` UI is an old, mostly-unmodified admin dashboard template The current `templates/`/`static/` UI is an old, mostly-unmodified admin dashboard template
(SB Admin 2-style Bootstrap theme) with leftover placeholder cruft never replaced with real (SB Admin 2-style Bootstrap theme) with leftover placeholder cruft never replaced with real
content - e.g. `index.html`'s "Placeholder button", dropdown menus full of "Action" / "Another content - e.g. `index.html`'s "Placeholder button", dropdown menus full of "Action" / "Another
@@ -757,7 +757,7 @@ keep bolting new cards onto the old template:
the redesign is done once against the final feature set rather than repeatedly against a moving the redesign is done once against the final feature set rather than repeatedly against a moving
target. target.
### Phase 17: Native Android companion app — PLANNED (low priority, do last) ### Phase 17: Native Android companion app — 🚧 PLANNED (low priority, do last)
Revives the phone-relay goal (Phase 11/12) properly this time, using a real native app instead of Revives the phone-relay goal (Phase 11/12) properly this time, using a real native app instead of
a web page - the only way to actually hold a WiFi connection to the Pi's hotspot and a cellular a web page - the only way to actually hold a WiFi connection to the Pi's hotspot and a cellular
connection to the internet open simultaneously (`ConnectivityManager.bindProcessToNetwork()`, connection to the internet open simultaneously (`ConnectivityManager.bindProcessToNetwork()`,