MVP-1 decisions log
Every requirement epic carried an Open decisions section. This page is the canonical record of how each was resolved for MVP-1, so the epics stop holding live questions and the build can proceed from settled ground.
:::tip How to read this Each decision is D-<EPIC>-<n>. The epic pages now carry a short Decisions (resolved for MVP-1) section that mirrors these; this log is the single source of truth. Status legend:
- ✅ Decided — settled; build to it.
- ⚖️ Decided — counsel confirms — the build posture is set; legal must sign off the wording/method before ship (it does not reopen the design).
- 🔜 Decided — MVP-1.x — deliberately deferred just past the first release, with the path noted. :::
Four strategic anchors drove the cascade (chosen with the product owner):
| Anchor | Decision |
|---|---|
| Analytics provider | Mixpanel, consented + config-gated — receives only de-identified internal-BI + parent-only marketing signals, never a child identifier. Re-added to the sub-processor / DPA chain. |
| VPC method | Email-plus (free tier, internal-use-only child data) + payment-card verification when a paid plan is on file. FTC-recognized methods; in-app. |
| Accessibility target | AAA body-text contrast (7:1) in the dark theme; WCAG 2.2 AA floor everywhere else. |
| Money scope | Full money-moves ship in MVP-1 — transfers, Unallocated, default allocation, goal-envelope balances, supervised attribution. |
Functional epics
Money & Envelopes
- D-MONEY-1 — Scope & sequencing. ✅ Money is its own sub-project (like SP3), but its full surface ships in MVP-1, not staged out. Household surfaces read-only money tiles that the Money sub-project's writes feed.
- D-MONEY-2 — Goal balances & default allocation. ✅ Both FR-MONEY-8 (goal-envelope balances) and FR-MONEY-5 (household default allocation) ship in MVP-1 (full-moves anchor).
- D-MONEY-3 — Supervised-attribution visibility (FR-MONEY-10). ✅ A household-attributed envelope surfaces on Household as a "Family / Unassigned" envelope tile, never under a child's name or wallet. When no per-child record exists (supervised, no VPC), the bounty credits the household envelope; the tile reads as household-owned. (Ties to the money fork in the privacy-compliance model.)
- D-MONEY-4 — Default-allocation UX. ✅ Percentage routes (a parent sets % splits across envelopes/goals), not fixed amounts — reads as a deliberate "where earnings flow" config. Fixed-amount routing deferred (YAGNI).
Admin features
- D-ADMIN-1 — Billing placement. ✅ Admin → Billing is canonical (owner-only, the single config hub); the Profile hub surfaces an owner-only "Subscription" shortcut row that deep-links into it for discoverability. (Reconciles with D-SETTINGS-2.)
- D-ADMIN-2 —
updatePlacescope. ✅ Fill the SDK gap and ship room create / rename / delete in MVP-1 — a partial CRUD (no rename) is more confusing than the small added effort. - D-ADMIN-3 — Default-bucket template retroactivity (FR-ADMIN-7). ✅ New members only in MVP-1; adding a permanent bucket to the template does not retroactively touch existing members. A deliberate "apply to existing" admin action is 🔜 MVP-1.x.
Account & profile management
- D-ACCOUNT-1 — Last-owner deletion. ✅ Block deletion while the account is the sole owner of a household with other members — require ownership transfer first, or an explicit "delete household + all data" confirm. Cascade-delete only when the owner is the last member. Guard:
LastOwnerCannotDeleteWithMembers. (This is the same primitive a GDPR/CCPA erasure request reuses.) - D-ACCOUNT-2 — Multi-household membership. ✅ The data model stays forward-compatible (membership is a join), but MVP-1 binds one active household per session. Multi-household session-switching is deferred (X-tier); RLS keeps the household-id binding single-active.
- D-ACCOUNT-3 — Social login. 🔜 Defer to MVP-2. Email/password only in MVP-1 — explicit gate before MVP-2.
- D-ACCOUNT-4 —
updateEmaildesign. ✅ MVP-1 uses Supabase Auth's built-in email-change flow (double-opt-in, confirm on both addresses). SDK:client.updateEmail(newEmail)returns a pending-confirmation state. FR-ACCOUNT-7 schedulable on that signature. - D-ACCOUNT-5 —
plan_typeset point. ✅ Written at sign-up (freedefault), so the MARKETING-bucket signal is reliable from account creation; flips topaidon successful checkout. (Not at first paywall hit — too late/unreliable.)
Catalog
- D-CATALOG-1 — Eligibility display. ✅ Show ineligible items grayed-out with a short rationale ("unlocks at…" / "for ages…"), not hidden — transparency + aspiration aid motivation. Full household catalog visible.
- D-CATALOG-2 — Bounty claim mechanics. ✅ First-come-first-served (current SDK assumption) for MVP-1; admin-assigns-after-request and the claim-request flow are out of MVP-1 scope.
- D-CATALOG-3 — Post-claim state. ✅ A fully-claimed bounty shows "claimed today" (visible, disabled) rather than disappearing; remaining daily slots shown when more than one.
- D-CATALOG-4 — Redemption reversal. ✅ No undo (append-only ledger). A correction is a new compensating entry by an admin, never a mutation.
Household
- D-HOUSEHOLD-1 — Budget summary / recommend (FR-HOUSEHOLD-6). ✅ With full money in MVP-1, the Admin → Family Budget editor lands in MVP-1, so FR-HOUSEHOLD-6 ships in MVP-1. Build sequence: budget editor before/with the Household summary.
- D-HOUSEHOLD-2 —
watchGoalsstream (FR-HOUSEHOLD-7). ✅ Poll-first (one-shot on tab focus) for MVP-1; add the SDKwatchGoalsstream as a fast follow. - D-HOUSEHOLD-3 — Family-goal celebration. ✅ Micro-animation (burst on the goal tile), reduced-motion-aware; full-screen moment deferred. No build dependency.
Member Profile
- D-PROFILE-1 —
colorKeypalette & ownership (FR-PROFILE-2). ✅ A fixed palette of 8 contrast-safe colours; admin assigns at invite, member may later self-select from the palette (editable). Not free-form — keeps the DS coherent and contrast-safe. - D-PROFILE-2 — Archive / restore UI. ✅ Ship an "archived goals" filter toggle (default hidden) in MVP-1 —
restoreGoalexists; this avoids invisible rows. - D-PROFILE-3 — Watch-only goal creation. ✅ A watch-only member cannot create their own goals; an admin creates on their behalf. SDK guard: goal-create requires a non-watch-only actor or an admin actor.
- D-PROFILE-4 —
funds_moved_to_goalevent. ✅ With money in MVP-1, it emits from the service layer (not the facade) — analytics stays tied to the domain mutation, single source.
Onboarding
- D-ONBOARD-1 — VPC flow. ⚖️ In-app screen with stored attestation (email-plus on free / card on paid, per the VPC anchor); not an external service for MVP-1. Counsel signs off.
- D-ONBOARD-2 — Quick-start templates (FR-ONBOARD-6). ✅ A short picker of 3–5 curated templates (e.g. Young kids / Tweens / Mixed ages / Solo-or-teen) — modest choice beats a single forced template.
- D-ONBOARD-3 — Checklist auto-dismiss. ✅ Dismiss on first
chore_completed— ties the checklist directly to the activation KPI event. - D-ONBOARD-4 — Co-parent invite share UX. ✅ OS share sheet (covers clipboard, messaging, email in one) for MVP-1; QR deferred.
Print & printables
- D-PRINT-1 — Label copy (FR-PRINT-4). ✅ "earns X tokens" — aligns with the envelope/economy terminology; patch
_choreRowto match. - D-PRINT-2 — Weekly multi-day layout. 🔜 MVP-1.x. MVP-1 prints single-day / per-member + per-room lists only.
- D-PRINT-3 — Timed-chore indicator. ✅ Print a small duration hint ("~15 min") when
estimateMinis set — supports the visual-timer/estimate model.
Routines
- D-ROUTINE-1 — Skip a step (FR-ROUTINE-3). ✅ Strict order enforced in MVP-1 (no skip) — matches the scaffolding intent for the core audience; a skip affordance is deferred pending research.
- D-ROUTINE-2 — Cross-day rollover (FR-ROUTINE-4). ✅ Co-resolved with FR-TODAY-9: an incomplete routine/chore rolls to "overdue today" (carried, not reset) — one shared rule across Today and Routines.
- D-ROUTINE-3 — Completion bonus. ✅ An optional discrete completion bonus, admin-configurable per routine (default off) —
RoutineServiceearn path +hadCompletionBonusanalytics prop. - D-ROUTINE-4 —
RoutineRunkey. ✅ Composite(routineId, date)— natural daily idempotency, aligns with the rollover model; deferred multi-day routines extend with a span rather than breaking the key.
Settings (Profile hub)
- D-SETTINGS-1 — Sign-out placement. ✅ Bottom of the Profile page (2026-07-26 shell redesign; superseded the earlier "Account sub-page" ruling) — removed from the top header, avoids accidental taps.
- D-SETTINGS-2 — Subscription tile. ✅ Owner-only "Subscription" row in the Profile hub that deep-links to Admin → Billing (discoverable shortcut; Admin remains the config home). Reconciles with D-ADMIN-1.
- D-SETTINGS-3 — About / legal link target. ✅ In-app web view for ToS / Privacy (contained; pins a versioned URL tied to consent records); system-browser fallback if the web view is unavailable.
- D-SETTINGS-4 — Notifications tile. ✅ Ship the tile to a real (minimal) notifications-preferences route — local notifications are in MVP-1, so the tile is functional (quiet-hours + lead-time prefs live there), not a stub.
Today (chore surface)
- D-TODAY-1 — Overdue policy (FR-TODAY-9). ✅ Incomplete items roll forward as "overdue today" (carried with an overdue badge), not silently reset. Shared with D-ROUTINE-2.
- D-TODAY-2 — Sort order (FR-TODAY-10). ✅ Sort by overdue first → scheduled time → estimate ascending, within the By-kid / By-room grouping.
- D-TODAY-3 — Inline balance + goal-distance. ✅ Yes — a compact "balance · X to goal" line per member in the Today context (motivational, low cost), reduced on the child's own view.
Visual timers
- D-TIMER-1 — Expiry signal + admin disable (FR-TIMER-5). ✅ Expiry fires a gentle haptic + optional local notification; the household admin can disable the notification (haptic stays unless the device is muted).
- D-TIMER-2 — Timer in approval view. ✅ Yes — show elapsed/estimate on the approval card so a reviewer sees how long the chore took. Reuses the atom.
- D-TIMER-3 — Estimate adjustment. ✅ Admin-set estimate is the default; a member may adjust their own run's estimate within bounds — not the chore's canonical estimate.
- D-TIMER-4 — Colour thresholds. ✅ Green ≥ 50%, amber < 50%, red < 25% remaining; encode as colour tokens. Under reduced-motion the colour still shifts but does not pulse.
Notifications
- D-NOTIF-1 — Chore-due lead time. ✅ Default 20 min (ADHD-leaning) + a per-household preference (15 / 20 / 30); A/B post-launch.
- D-NOTIF-2 — Approval-prompt batching. ✅ One summary notification with a count ("3 chores need approval") → taps into the approval queue, which preserves per-item context.
- D-NOTIF-3 — Kid-mode suppression. ✅ Chore-due reminders fire in kid-mode (they help the child); approval prompts do not (parent-only). Decided now so the scheduler is correct when kid-mode (MVP-2) lands.
- D-NOTIF-4 — Quiet-hours default. ✅ Ship a sensible default window 21:00–07:00, user-editable / disable — avoids night-time noise out of the box.
Non-functional epics
Analytics & telemetry
- D-ANALYTICS-1 — Provider. ⚖️ Mixpanel, consented + config-gated (anchor). It receives only de-identified internal-BI events (content-free, no child identifier) + parent-only marketing signals (count / plan type / parent-feature-active flags); never child PII. Added to the sub-processor / DPA list. Re-introduces the previously-removed Mixpanel behind the consent + config gate.
- D-ANALYTICS-2 — Opt-in target. ⚖️ MVP-1 target ≥ 60% adult opt-in; treat < 40% as a consent-surface problem, not a target miss. Confirm with product/counsel.
- D-ANALYTICS-3 — Config gate. ✅ Build-time
dart-definefor the Mixpanel token/enable in MVP-1 (no network dependency); a remote-config path comes later. - D-ANALYTICS-4 — Internal-BI exemption. ⚖️ Adopt the internal-operations posture — the de-identified, content-free, never-marketing BI stream sits outside consent-for-marketing. This is the governing three-bucket spec; counsel confirms.
Personas & authorization
- D-PERSONA-1 — Non-parental admin. ✅ No for MVP-1 —
adminimpliesisParental; guardian/consent semantics stay coupled. Decoupling onto a separate guardian attribute is deferred to self-governed mode (A2 / X3). - D-PERSONA-2 — Co-parent scopes. ✅
coParent= full admin (isParental) in MVP-1; the "delegated / limited scopes" hint incontext.mdis deferred (A3). Reconcilecontext.mdto note coParent = full-admin for MVP-1. - D-PERSONA-3 — Intra-household visibility. ✅ A child Member sees their own wallet/goals + shared Family Goals; sibling wallets/goals are not visible. RLS shaped to self + household-shared. (Set now — expensive to retrofit.)
- D-PERSONA-4 — TV / kiosk identity. ✅ The always-on display runs under the authenticated parent's session in a read-only, privacy-reduced scope (supervised-action opt-in per the COPPA stance). The scope is defined now; the auth wiring lands with the deferred auth work.
Accessibility
- D-A11Y-1 — Contrast target. ✅ AAA body-text contrast (7:1) in the dark theme; AA (4.5:1) floor everywhere else and in the light theme (anchor). Dark-theme body tokens set to AAA.
- D-A11Y-2 — Reduced-motion style. ✅ Crossfade ≤ 100 ms when
disableAnimationsis true (not instant) — a soft fade reads as intentional. Encode asmotion_tokens.reducedMotionDuration = 100ms. - D-A11Y-3 —
textScaleFactorceiling. ✅ Formally support up to 200% (Android 14 cap) with no layout breakage; best-effort to 320% (iOS max) without an overflow guarantee. Layout constraints target 200%. - D-A11Y-4 — Focus-ring token. ✅ A dedicated
--focus-ringtoken = a high-contrast accent (calm-dusk accent at full chroma), distinct per theme (lighter ring on dark, darker on light), ≥ 3:1 against adjacent colours.
Children's privacy (COPPA)
- D-COPPA-1 — VPC method. ⚖️ Email-plus (free, internal-use-only) + card-on-file (paid) (anchor); counsel confirms. Drives NFR-COPPA-2.
- D-COPPA-2 — 2025 FTC amendments. ⚖️ Adopt data-retention limits + separate consent for any third-party sharing + a written security program as design requirements (folded into NFR-COPPA-3/4/7). Counsel confirms scope.
- D-COPPA-3 — Teens (13–17). ✅ Handled in the deferred Privacy & GDPR feature, not MVP-1 COPPA; MVP-1 treats all minors under the parent-supervised / VPC model. CCPA 13–15 opt-in + GDPR-K flagged as forward items.
- D-COPPA-4 — Re-score. ✅ Done — re-scored RICE 4.8 → 2.1 in the prioritization matrix (C 80% → 50%, E 5 → 7); stays MVP-1 as a legal blocker.
Offline sync
- D-SYNC-1 — Conflict resolution. ✅ Ledger-ordered replay (client enqueue order) for value/ledger writes; last-write-wins (server timestamp) for idempotent config/profile fields. Clock-drift handled by a server-assigned sequence on apply. Decided before the SP3.5 sync build.
- D-SYNC-2 — Sync boundary. ✅ Household-level full sync for MVP-1 (simpler, correct); per-member incremental deferred. Drives the hydrate-once
watch+ queue replay scope. - D-SYNC-3 — Approvals offline. ✅ Optimistic — a chore shows "pending approval" locally and unblocks the child; reconciles on reconnect. Neurodiversity-preferred; introduces the pending-approval state (visible to both parties).
- D-SYNC-4 — Sync trigger. ✅ Reconnect foreground only for MVP-1 (the doc's stated default); background fetch (Workmanager / iOS BG) deferred.
- D-SYNC-5 — Queue persistence schema. ✅ A Drift
pending_writestable:(id UUID, aggregate, op, payload JSON, idempotency_key, created_at, attempt_count, status). Theidempotency_key(client-generated UUID) is stored on both the queue row and, on apply, the ledger entry for dedup. Locked before the SP3.5 migration.
Security & data protection
- D-SEC-1 — Local encryption. ✅ SQLCipher via the Drift SQLCipher wrapper (whole-DB encryption at rest) for MVP-1; SDK-level field encryption deferred (granularity not yet needed). Locked before the offline-cache milestone.
- D-SEC-2 — Photo E2E. ✅ Supabase server-side Storage encryption is sufficient for MVP-1 (not client-side E2E) — content moderation must inspect photos server-side. Documented risk acceptance; revisit if moderation moves client-side.
- D-SEC-3 — Pen test. ✅ Third-party pen test at the private-beta → public-launch boundary (before public launch); internal review continuous. Feeds the SOC 2 roadmap.
- D-SEC-4 — SOC 2 Type II threshold. ⚖️ Trigger formal attestation at the first B2B / school ask or ~10k MAU, whichever first (placeholder); maintain evidence-collecting practices until then. Confirm with counsel/sales.
- D-SEC-5 — Anon-key rotation. ✅ CI-enforced reminder (a scheduled check flagging key age) for MVP-1 — between manual-only and full automation; automate via the Supabase dashboard API later. Locked before first production release.
Terms & consent
- D-CONSENT-1 — VPC method. ⚖️ Same as D-COPPA-1 — email-plus (free) + card (paid); counsel confirms. NFR-CONSENT-2 specced on that.
- D-CONSENT-2 — "Material change" definition. ⚖️ A material change = any change to data collected, purposes, processors/sub-processors, or sharing; copy/clarity edits are notification-only. Legal review per change. Drives NFR-CONSENT-3/4.
- D-CONSENT-3 — Shadow-member ToS. ✅ A
shadowmember is created under the household admin's acceptance (admin accepts on the household's behalf at creation); the shadow member completes their own ToS/consent on activation/claim (supplements, does not replace). - D-CONSENT-4 — Re-consent SLA. ⚖️ Keep 14 days / 85% as MVP-1 draft targets: adult ToS bumps = 14-day window; child VPC bumps block child-data processing immediately on a material child-consent change until re-consent. Counsel/product confirm the numbers.
- D-CONSENT-5 — Consent-record retention. ⚖️ Retain the consent/VPC event record (proof consent existed) for the legally-required minimum after child-PII erasure — the record itself carries no child PII beyond an opaque ref. Jurisdiction-specific; counsel confirms the duration.
What stays open past MVP-1 (by design)
These are intentionally not MVP-1 decisions; they are tracked where noted:
- Teens 13–17 / GDPR-K / CCPA minor opt-in → the deferred Privacy & GDPR feature.
- Social login (Google/Apple) → MVP-2 gate (D-ACCOUNT-3).
- Multi-household session switching, non-parental admin, co-parent delegated scopes → self-governed mode (D-PERSONA-1/2, D-ACCOUNT-2).
- Per-member incremental sync, background sync, SDK field-level encryption → post-MVP-1 (D-SYNC-2/4, D-SEC-1).
- Weekly grid printable, full-screen goal celebration, redemption undo → MVP-1.x niceties.
Not legal advice. ⚖️ items set the build posture; counsel signs off the method and wording before ship — especially the VPC method, the 2025 FTC COPPA amendments, and consent-record retention. See the Supabase DPA for the sub-processor chain.