wip: phase 05 web-push paused — code complete + verified, awaiting iOS/Android device UAT

This commit is contained in:
Lucas Berger
2026-06-09 22:51:04 -04:00
parent 17dfaac5f2
commit 3b54ea2f12
2 changed files with 57 additions and 57 deletions
+17 -17
View File
@@ -1,34 +1,34 @@
{
"version": "1.0",
"timestamp": "2026-06-09T19:14:03.727Z",
"phase": "5",
"phase_name": "Web Push Notifications",
"timestamp": "2026-06-10T02:49:45.903Z",
"phase": "05",
"phase_name": "web-push-notifications",
"phase_dir": ".planning/phases/05-web-push-notifications",
"plan": null,
"plan": 8,
"task": null,
"total_tasks": null,
"status": "paused",
"stage": "discuss-complete; ready-to-plan",
"completed_tasks": [
{"id": 1, "name": "discuss-phase 5 → 05-CONTEXT.md + 05-DISCUSSION-LOG.md (D-01..D-14, 3 areas discussed)", "status": "done", "commit": "e74f24d"},
{"id": 2, "name": "Recorded STATE.md session (phase 5 context gathered)", "status": "done", "commit": "3bbfbbc"}
{"id": 1, "name": "All 8 plans (05-01..05-08) executed across 5 waves, sequential (worktree degrade)", "status": "done"},
{"id": 2, "name": "Code review --fix --all --auto: 14 findings fixed over 3 iterations; 05-REVIEW.md clean", "status": "done"},
{"id": 3, "name": "Phase verification: 12/12 must-haves in code; NOTIF-01/02/03 traced; 05-VERIFICATION.md status human_needed", "status": "done"},
{"id": 4, "name": "5 device-only UAT items persisted to 05-UAT.md; ROADMAP reverted to pending device UAT", "status": "done"}
],
"remaining_tasks": [
{"id": 3, "name": "Optional: /gsd-ui-phase 5 — UI design contract (permission prompt, settings toggle, notification flow)", "status": "not_started"},
{"id": 4, "name": "/gsd-plan-phase 5 — research + plan (reads 05-CONTEXT.md → RESEARCH.md, PLAN.md files)", "status": "not_started"},
{"id": 5, "name": "Execute Phase 5 plans", "status": "not_started"}
{"id": 5, "name": "On-device UAT (iOS 16.4+ Home-Screen PWA + Android) via /gsd-verify-work 5 — 5 items in 05-UAT.md", "status": "not_started"},
{"id": 6, "name": "After UAT passes, phase auto-transitions to complete (verify-work); milestone can advance to Phase 6", "status": "not_started"}
],
"blockers": [],
"human_actions_pending": [
{"action": "Create + share the shared Family calendar and mark is_shared=1 on the primary Fastmail account", "context": "Phase 2 D-16 deferred. Reminders (NOTIF-01) fire ONLY on shared-calendar events (D-05), so live verification of reminders needs a real shared calendar with events. Implementation/planning is not blocked — the reminder path handles the empty-shared-calendar case correctly.", "blocking": false}
{"action": "Run /gsd-verify-work 5 on a physical iOS device and an Android device", "context": "Phase goal 'reliably on iOS and Android' is device-only; 5 UAT items cannot be automated (CLAUDE.md)", "blocking": true},
{"action": "Create + share the 'Family' calendar and set is_shared=1 (Phase 2 D-16)", "context": "Reminders (NOTIF-01/SC-1) only fire on shared Family-calendar events; needed before SC-1 has real events", "blocking": false}
],
"decisions": [
{"decision": "Reminders fire for SHARED Family-calendar events ONLY (not personal)", "rationale": "Native device calendar apps already remind for personal events; FamilySync must not duplicate. Deliberately narrows literal NOTIF-01 — single most consequential decision; revisit if the household expects all-event reminders.", "phase": "5"},
{"decision": "Coalesce list-change pushes per list; events specific / list pings generic; name the actor; meaningful event-changes only (description-only edits silent)", "rationale": "Anti-spam for the chatty list source; clear attribution for a two-person household.", "phase": "5"},
{"decision": "Contextual permission prompt after install; single master toggle (v1); silent auto re-subscribe on dead subscription", "rationale": "Low-friction for the non-technical member; per-category opt-out deferred to v1.x.", "phase": "5"},
{"decision": "Fixed 15-min lead time; no all-day reminders", "rationale": "MVP simplicity; custom/per-event lead time is v1.x.", "phase": "5"}
{"decision": "VAPID keypair generated by assistant; user pasted into root .env (gitignored); wired into docker-compose.yml env + .env.example", "rationale": "Config env-injected for Docker transposability; no key baked into image; .env is permission-blocked from assistant Read/Write", "phase": "05"},
{"decision": "Reverted premature ROADMAP [x] complete to [ ] pending device UAT", "rationale": "Verification is human_needed; goal not confirmable without devices; avoid false completion claim", "phase": "05"},
{"decision": "Ran code review --fix --all --auto rather than ship-then-fix", "rationale": "4 Criticals (esp. iOS gesture gate) defeated success criteria; fixed before declaring done", "phase": "05"}
],
"uncommitted_files": [],
"next_action": "/clear then /gsd-plan-phase 5 (CONTEXT.md is the source of truth; entry gates from Ph3/Ph4 already cleared).",
"context_notes": "Just finished discuss-phase for Phase 5 (Web Push, MVP mode, depends on Ph3+Ph4). 05-CONTEXT.md + 05-DISCUSSION-LOG.md written and committed; clean stopping point between discuss and plan, nothing mid-edit. Most consequential locked choice: D-05 shared-only reminder scope (deliberate NOTIF-01 narrowing — flagged for planner + verification). For the planner: the new push-subscription table MUST use drizzle generate+migrate (db:push unsafe on populated MariaDB); push dispatch reuses the existing in-memory listEmitter publish points (apps/api/src/lib/listEmitter.ts) + poller/outboxWorker change-detection; web-push and ioredis are NOT installed (VAPID keys need generating, no Redis — single Node process); SW is vite-plugin-pwa generateSW + autoUpdate so the push/notificationclick handler likely needs an injectManifest switch; iOS subscription health-check + event.waitUntil() + visible-notification-on-every-push are mandatory from day one (STATE.md)."
"next_action": "Run /gsd-verify-work 5 on iOS + Android devices to close the 5 UAT items in 05-UAT.md. Dev MariaDB (familysync-mariadb-1, host port 3306) is up for any API re-checks.",
"context_notes": "Phase 5 is code-complete and fully verified at the code level (12/12). The only open work is on-device confirmation. The iOS user-gesture bug was the highest-stakes issue and was fixed correctly only on the 3rd review iteration (pre-resolve SW registration + VAPID key into state, disable Enable control until both ready, zero await before pushManager.subscribe()). Do NOT reintroduce any await between the tap and pushManager.subscribe() when touching push UI."
}