Review-and-Plan: lifecycle email/SMS (2026-09-08, Tue angle)
Reviewed: workers/daily-playset/src/{index.js,deliver.js,send.js} and its wrangler.toml (release HEAD, fresh git fetch); migrations-accounts/0006_plans_and_deliveries.sql; workers/retention-sweeper/*; workers/feedback-intake/* (Twilio); review-portal/src/*; live read-only checks (wrangler deployments list, d1 execute SELECT on deliveries, KV get retention:last), all run 2026-09-08. Note: the incident entry lives in escalations.md:181 (section header "2026-09-07 13:1x ET"), not rounds.md as the brief said.
Findings
- Zero-row miss: unfixed. escalations.md:181 guesses an uncaught throw before
recordDelivery. Confirmed in code:deliverHouseholdonly try/catches the package step (deliver.js:134-141); a throw inchildrenOf/recentHistory/curateHouseholdor the recipient-revalidation query (158-160) escapes torunTick's per-household catch (194-196), which onlyconsole.logs. No row, no alert.send.jsnever throws (1-4), so the gap sits upstream of it.git log --since=2026-09-07 -- workers/daily-playset/returns zero commits. Live query: household01m1hnrta46krys18wn7's 09-07 email landed 17:24:23Z, roughly 7 hours after its normal 10:30Z slot, the same hour as the escalation. That's a late catch-up, not a fix; nothing logs the founder giving the "explicit go" the escalation said a resend needed. - Retention is fine; two docs are stale.
retention-sweeperis built and deployed (live since 2026-09-02) and ran clean this morning (KVretention:last: 04:20:25Z, 5magic_linkspurged, 0 problems).wrangler.toml's "NOT DEPLOYED" banner and queue.md:168 ("not built") were both wrong; corrected in queue.md. - A nudge/re-engagement plan already exists, not yet built. [[2026-09-02-retention-nudges-plan]] (status: ray-selected, awaiting founder read) already specs five nudge types, cadence, caps, and the reply-loop plumbing against the amended [[2026-09-02-members-area-spec]] calendar. queue.md:225 defers a
nudgestable "if the retention plan is confirmed" — the sweeper side is confirmed live, but the plan doc itself is still waiting on the founder's read, and that doc flags its own build gate: the token reply-loop depends on Email Routing's catch-all being repointed atsw-feedback-intake, which today forwards to ben@raydata.co instead (per ruling 23 in that doc). - Twilio (Short Message Service) wiring is one-directional. Only wired into
feedback-intakefor inbound Multimedia Messaging Service replies, itself deployed inert (queue.md:178). No outbound or lifecycle use exists. "Open Twilio" (escalations.md:42-43) is still an open founder action item. - Review-portal has no notification path. Searched
resendcase-sensitively undersrc/,workers/, andfunctions/: 14 hits total, zero underreview-portal/.
Proposed queue.md diff
Already applied autonomously (engineering-lane correction + a new tracked P1, both within the standing autonomous editing column):
- [engineering] Retention sweeper: UGC (user-generated content) rows past retain_until (90 d) + feedback rows/contacts (180 d; R2 lifecycle already set) + a delete-my-row path (privacy page promises deletion on request) — not built.
+ ~~[engineering] Retention sweeper: ...~~ DONE — deployed 2026-09-02, confirmed live via KV retention:last. Retire this line.
+ [engineering, P1, NEW] Daily-playset zero-row miss (escalations.md:181, 09-07 13:1x): deliverHousehold has no catch-all between entry and send; add one that always writes a failed row with the real error. Never promoted from escalations.md to a tracked item.
Decisions needed
- Prioritize the zero-row catch-all now, given it's live on comped households (applied autonomously; queued P1 in queue.md).
- "Open Twilio" — still open, no new information this round (founder action, dashboard-gated).
- Read [[2026-09-02-retention-nudges-plan]] — a full nudge plan already exists and is waiting on your read, not a from-scratch scoping question. Building it also needs the Email Routing catch-all repointed (currently forwards to you directly), which is its own small decision inside that doc.
Top finding
The daily-playset delivery pipeline has a real, currently-unpatched reliability hole: deliverHousehold only guards the PDF-packaging step against exceptions, so anything that throws earlier (D1 reads, curation, the recipient-revalidation query) escapes to a catch that only logs to console. No failed row, no alert. This is exactly the silent zero-row miss investigated 2026-09-07 for mom's household, and zero commits have touched this file since; that household's next email arrived about 7 hours late rather than through any confirmed fix. Separately, and more positively: the retention sweeper both queue.md and the worker's own source comment describe as unbuilt is in fact live and ran clean this morning, and a full nudge/re-engagement plan is already drafted and waiting on the founder's read rather than needing fresh scoping.