diff --git a/docs/BACKLOG.md b/docs/BACKLOG.md index 7b15866..1eea3f5 100644 --- a/docs/BACKLOG.md +++ b/docs/BACKLOG.md @@ -1,32 +1,67 @@ # Backlog -Seed list for the issue tracker. Each becomes a GitHub issue (see -`scripts/create-issues.sh`). `[client]` = iOS, `[backend]` = coordinate with the -backend service. +Open issues, seeding the Gitea tracker via `scripts/create-issues.sh` (run once the +repo exists). `[client]` = iOS, `[backend]` = the platform service on the Docker host, +`[ci]` = build/test. -1. **[client][backend] Add `Sport` (F1) and `World` topic pills.** The 47 feeds now - include heavy F1 + global-news coverage that gets squeezed into finance/tech/ - politics/africa. Add pills in `Topic.filters`; backend classifier must emit `sport` - / `world` slugs to match. -2. **[client] Wire the Tailscale remote host in Connectivity.** Populate the Remote - Access card's host so away-from-home auto-selects the Tailscale address. Verify the - LAN⇄Tailscale switch via `/health` probing. -3. **[client] SSID-based trusted networks.** Pin trusted Wi-Fi by name ("Add current - network"). Needs the *Access WiFi Information* entitlement (real device + paid - account); no-ops in the simulator. Currently approximated by LAN reachability. -4. **[client] Optional in-app WireGuard tunnel.** NetworkExtension packet-tunnel so - Jarvis can bring up a WireGuard tunnel itself (WireGuard/Netmaker configs only). - Needs entitlement + real device. Deferred. -5. **[client] App icon + launch assets.** `AppIcon` is an empty placeholder. -6. **[client] Flesh out Latest / Saved / Search tabs.** Currently minimal reuse of the - feed components; add proper empty/loading states and dedicated behavior. -7. **[client] Verify hero image loading.** `AsyncImage` against real feed `imageUrl`s - (ATS, redirects, grey fallback) in the article reader. -8. **[client] Infinite scroll / pagination at scale.** Validate `loadMore`/cursor - round-trips against the live ~850-story dataset; guard against dupes. -9. **[backend] Topic-classifier coverage for the 47 feeds.** Ensure science/tech/world/ - sport map sensibly into the supported topic slugs. -10. **[ci] Add unit/UI tests.** The build matrix compiles but runs no tests yet; add a - test target and a `test` matrix leg. -11. **[client] Offline polish.** Green "cached" dot + Saved tab depend on opening an - article; consider pre-caching top stories for true offline-first. +## Backend — data quality (highest priority) + +1. **[backend] F1 stories are mis-classified into tech/finance/politics.** The topic + classifier has no sport category, so F1 (with 100% F1 sources) scatters across topics. + Evidence from the live feed: "Monaco Grand Prix stewards…" → `tech`, "F1 reports 35% + CO2 reduction…" → `finance`, "McLaren launch appeal against Gasly penalty" → `politics`. + Add a `sport` (or `f1`) topic and route motorsport sources there. +2. **[backend] Over-clustering merges unrelated articles.** Stories pair a headline with a + summary about something else, e.g. an Ebola/Bunia (DR Congo) headline carried a + South-Africa summary, and a CRISPR headline carried Drakensberg/SA text. Raise the + TF-IDF similarity threshold (~0.22 → 0.30–0.40) and make the canonical `headline` and + `summary` come from the **same** representative article. This also inflates + `sourceCount` / `crossSourceConfirmation` and the signal score. +3. **[backend] Add accurate per-story tags (topic + region).** So the client can *read* + tags (sport, uganda, east-africa, south-africa, …) instead of keyword-guessing. Unblocks + moving the filter pills to server-side. Pairs with #1/#2. +4. **[backend] Topic-classifier coverage for the 47 feeds.** Ensure science/world/tech map + sensibly into the supported topics. + +## Backend — features + +5. **[backend] Server-side push for breaking alerts (APNs or ntfy).** Needed for + breaking-story notifications while the app is fully closed; the backend already computes + the stories. Client currently does local notifications + background refresh only. + +## Client + +6. **[client] Move interest filters server-side once tags exist (#3).** Replace the + client-side keyword filters (F1 / Uganda / East Africa / South Africa) — which only see + loaded stories and match the headline — with backend tag filtering for full coverage. +7. **[client] SSID-based trusted networks.** Pin trusted Wi-Fi by name. Needs the Access + WiFi Information entitlement (real device + paid account); no-ops in the simulator. + Currently approximated by LAN reachability. +8. **[client] Optional in-app WireGuard tunnel.** NetworkExtension packet-tunnel so Jarvis + can bring up a WireGuard tunnel itself (WireGuard/Netmaker configs only). Entitlement + + real device. Deferred. +9. **[client] App icon + launch assets.** `AppIcon` is an empty placeholder. +10. **[client] Flesh out Latest / Search tabs.** (Saved is now an explicit bookmarks list.) + Add proper empty/loading states and dedicated behavior. +11. **[client] Verify hero image loading.** `AsyncImage` against real feed `imageUrl`s + (ATS, redirects, grey fallback) in the article reader. +12. **[client] Offline-first polish.** Pre-cache top stories for true offline-first; today + the green "cached" dot depends on opening an article. + +## CI + +13. **[ci] Add unit/UI tests + a test matrix leg.** The build matrix compiles but runs no + tests yet. +14. **[ci] Backend CI build matrix.** Python 3.11–3.13 + lint + Docker image build/health + probe, for the backend repo (template lives in chat/handoff). + +--- + +## Recently shipped (this iteration) + +Signal feed + detail + reader + feed manager; LAN⇄Tailscale connectivity; notifications +(morning/evening briefings + breaking alerts) with Open-Meteo weather; device code signing; +feed resilience (no blank-on-refresh, ignore cancelled, coalesced WS refresh); clearer +empty states; deterministic feed order; read/unread (drop stripe on open); 6-line summary +preview; pinned mutually-exclusive filters (F1 split out, regions non-overlapping, +Finance/Tech by topic); swipe actions (left = save, right = share + mark read). diff --git a/scripts/create-issues.sh b/scripts/create-issues.sh index 41e6f11..64c5204 100755 --- a/scripts/create-issues.sh +++ b/scripts/create-issues.sh @@ -22,27 +22,40 @@ mk() { -d "$body" >/dev/null && echo " + $1" } -mk "Add Sport (F1) and World topic pills" \ -"The 47 feeds include heavy F1 + global-news coverage squeezed into finance/tech/politics/africa. Add pills in Topic.filters; backend classifier must emit sport/world slugs to match. [client][backend]" -mk "Wire the Tailscale remote host in Connectivity" \ -"Populate the Remote Access card's host so away-from-home auto-selects the Tailscale address. Verify the LAN<->Tailscale switch via /health probing. [client]" -mk "SSID-based trusted networks" \ -"Pin trusted Wi-Fi by name. Needs the Access WiFi Information entitlement (real device + paid account); no-ops in the simulator. Currently approximated by LAN reachability. [client]" -mk "Optional in-app WireGuard tunnel" \ -"NetworkExtension packet-tunnel so Jarvis can bring up a WireGuard tunnel itself (WireGuard/Netmaker configs only). Needs entitlement + real device. Deferred. [client]" -mk "App icon + launch assets" \ -"AppIcon is an empty placeholder. [client]" -mk "Flesh out Latest / Saved / Search tabs" \ -"Currently minimal reuse of the feed components; add proper empty/loading states and dedicated behavior. [client]" -mk "Verify hero image loading in the reader" \ -"AsyncImage against real feed imageUrls (ATS, redirects, grey fallback) in the article reader. [client]" -mk "Validate infinite scroll / pagination at scale" \ -"Validate loadMore/cursor round-trips against the live ~850-story dataset; guard against dupes. [client]" -mk "Topic-classifier coverage for the 47 feeds" \ -"Ensure science/tech/world/sport map sensibly into the supported topic slugs. [backend]" -mk "Add unit/UI tests + test matrix leg" \ -"The build matrix compiles but runs no tests yet; add a test target and a test matrix leg. [ci]" -mk "Offline-first polish" \ -"Green cached dot + Saved tab depend on opening an article; consider pre-caching top stories. [client]" +# --- Backend: data quality --- +mk "[backend] F1 stories mis-classified into tech/finance/politics" \ +"The topic classifier has no sport category, so F1 (100% F1 sources) scatters across topics. Live evidence: 'Monaco Grand Prix stewards…' -> tech, 'F1 reports 35% CO2 reduction…' -> finance, 'McLaren launch appeal against Gasly penalty' -> politics. Add a sport/f1 topic and route motorsport sources there." +mk "[backend] Over-clustering merges unrelated articles" \ +"Stories pair a headline with an unrelated summary: an Ebola/Bunia (DR Congo) headline carried a South-Africa summary; a CRISPR headline carried Drakensberg/SA text. Raise the TF-IDF similarity threshold (~0.22 -> 0.30-0.40) and make canonical headline + summary come from the SAME representative article. Also inflates sourceCount/crossSourceConfirmation/score." +mk "[backend] Add accurate per-story tags (topic + region)" \ +"Expose accurate tags (sport, uganda, east-africa, south-africa, ...) so the client reads them instead of keyword-guessing. Unblocks server-side filter pills. Pairs with the F1 and over-clustering fixes." +mk "[backend] Topic-classifier coverage for the 47 feeds" \ +"Ensure science/world/tech map sensibly into the supported topic slugs." + +# --- Backend: features --- +mk "[backend] Server-side push for breaking alerts (APNs or ntfy)" \ +"Needed for breaking-story notifications while the app is fully closed. The backend already computes the stories; client currently does local notifications + background refresh only." + +# --- Client --- +mk "[client] Move interest filters server-side once backend tags exist" \ +"Replace the client-side keyword filters (F1/Uganda/East Africa/South Africa) — which only see loaded stories and match the headline — with backend tag filtering for full coverage." +mk "[client] SSID-based trusted networks" \ +"Pin trusted Wi-Fi by name. Needs the Access WiFi Information entitlement (real device + paid account); no-ops in the simulator. Currently approximated by LAN reachability." +mk "[client] Optional in-app WireGuard tunnel" \ +"NetworkExtension packet-tunnel so Jarvis can bring up a WireGuard tunnel itself (WireGuard/Netmaker configs only). Entitlement + real device. Deferred." +mk "[client] App icon + launch assets" \ +"AppIcon is an empty placeholder." +mk "[client] Flesh out Latest / Search tabs" \ +"Saved is now an explicit bookmarks list. Add proper empty/loading states and dedicated behavior to Latest and Search." +mk "[client] Verify hero image loading in the reader" \ +"AsyncImage against real feed imageUrls (ATS, redirects, grey fallback) in the article reader." +mk "[client] Offline-first polish" \ +"Pre-cache top stories for true offline-first; today the green cached dot depends on opening an article." + +# --- CI --- +mk "[ci] Add unit/UI tests + a test matrix leg" \ +"The build matrix compiles but runs no tests yet; add a test target and a test matrix leg." +mk "[ci] Backend CI build matrix" \ +"Python 3.11-3.13 + lint + Docker image build/health probe for the backend repo (template in the handoff)." echo "Done."