Skip to main content
← Back to list
01Issue
FeatureShippedSwamp ClubPublic
Assigneeskeeb

Relationships

↑ child of #2008⊘ blocks #2016

#2012 feat(nurture): /admin/nurture — who would get what, and why

Opened by keeb · 9/4/2026· Shipped 9/4/2026

Parent: the product-nurture epic. Depends on the ledger + dry-run projector.

Problem

The ask, verbatim: an admin panel to show what is going to get sent out to who, and then send status. This is the gate for the whole epic — nothing gets armed until a human has looked at real names and real evidence and agreed the rule is right.

What ships

/admin/nurture, behind the existing routes/admin/_middleware.ts 404 gate, modelled on /admin/messages.

Per flow, one card:

  • Armed / disarmed, with armedAt and how many rows the cold-start seal claimed.
  • Counts by status: candidate, sealed, suppressed, sent, failed, skipped.
  • The pending list — who would receive this, with their evidence rendered as the numbers that qualified them (account age, last active, lifetime active days, the failing command). This is the whole point of the panel: a list of names is a list; a list of names with reasons is a rule you can falsify.
  • The sent log — what went out, when, on which channels, with the outcome per channel and the failure reason when there is one.
  • A per-flow arm / disarm control, and a per-flow channel matrix (email, inbox, both).

Reads, not writes, on the candidate list. The panel never triggers a send; arming is the only write, and it is deliberately a separate deliberate act.

Emails are never rendered. Per the standing rule, no operative email addresses on any admin listing surface — render the username and the tier, as the rest of the console does.

Verification

This issue is the verification surface for A1–A3, so its own verification is mostly "does it tell the truth":

  • tests/routes/admin_nurture_test.ts — 404 for non-admins (not 401/403); status counts match the underlying collection; a sealed row never appears in the pending list.
  • tests/components/ coverage for the evidence rendering, including a flow with zero candidates and a flow whose reads were unavailable — pending is not empty, and unavailable is not empty either. An unavailable cohort read must say so rather than rendering "nobody qualifies", which is the exact failure #1589 and the leaderboard fill both document.
  • Driven for real on the local stack at 375px: seed a population, run the projector, read the panel, and confirm the names and numbers match a hand-run query.

Out of scope

Sending, suppression, templates. Those are Phase B; the panel is what proves Phase A before Phase B starts.

02Bog Flow
OPENTRIAGEDIN PROGRESSSHIPPED+ 1 MOREASSIGNED+ 5 MOREREVIEW+ 4 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

9/4/2026, 11:09:22 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
keeb assigned keeb9/4/2026, 8:04:15 PM
keeb linked parent of #20089/4/2026, 7:41:07 PM
keeb linked blocked by #20169/4/2026, 7:41:44 PM

Sign in to post a ripple.