docs(agents): Phase 2 background runner is impossible (no WebSocket); hold at Phase 1+1b

Verified against Capacitor v8 docs: Background Runner exposes fetch but not
WebSocket, and Nostr relays are WS-only — so on-device background relay polling
cannot work. Recorded the two real alternatives (push gateway / foreground
service) and the owner decision to hold at the zero-server design.
This commit is contained in:
SkateSpots 2026-09-29 14:17:57 +07:00
parent d966bca148
commit 5c8f84fca1

View file

@ -563,9 +563,18 @@ session with **no other memory of this project**. So:
`skatespots:notifications:reminders`; the hook cancels them all on unmount
(opt-out / logout). New pref key `reminders` (default on). Pro-expiry reminder
deliberately skipped — it would pull in the heavy `useSasquatchPro` query.
**Phase 2/3 (NOT built):** background runner (on-device polling, closed-app,
~15 min floor) and a content-free FCM "doorbell" (timely, but a server learns
metadata). `useResolvedDmRelays` is exported for the envelope hook.
**❌ Phase 2 (background runner) is DEAD — don't attempt it
(verified 2026-09-29):** Capacitor's Background Runner supports `fetch` but
**NOT `WebSocket`** (v8 docs), and Nostr relays are WebSocket-only, so a
runner physically cannot query relays while backgrounded. On-device background
relay polling is not possible. Closed-app DMs/invites therefore need either
**(a)** a push gateway (FCM; a server learns *metadata* "this pubkey has
something" — content/sender stay hidden by NIP-17, timestamps are randomised)
or **(b)** a foreground service keeping a native WS alive (no server, but a
permanent notification + battery + custom native code). **Owner decision
(2026-09-29): HOLD at Phase 1 + 1b** — the zero-server design stands and
closed-app DMs/crew are a documented limitation, revisited only if it becomes
load-bearing. `useResolvedDmRelays` is exported for the envelope hook.
- **Empty-map nudge (2026-09-28):** `MapPage` distinguishes the two empties — the
existing "No spots match" card is for *filters* (`filteredSpots.length === 0 &&
allLocations.length > 0`) and a new "No spots mapped yet — be the first" card