Skip to main content

Terms & consent — requirements

Epic — release gate. MVP-1 requirements for the consent-record substrate (see the feature architecture). These are pass/fail launch conditions, audited each release and continuously in production. Not legal advice — counsel must sign off on VPC method and re-consent triggers. The Children's privacy (COPPA) epic depends on these records.

TypeNon-functional
Layer (build approach)Cross — consent record + re-consent gate (SDK service + RLS + UI)
RICER 10 × I 2 × C 80% / E 2 = 8.0 · Tier MVP-1
KPI (summary)Consent-acceptance % (100% pre-use); re-consent completion — see Success criteria
Traces tofeature terms-consent · C4 auth
Depends onChildren's privacy (COPPA) (VPC definition + method) · Account (account holder is the consenting adult)

Success criteria (definitive KPI)

Success = these gates hold at 100%, verified each release and sampled continuously in production:

  • ToS acceptance gate: 100% of active sessions are preceded by a recorded acceptance of the current Terms of Service and Privacy Policy — zero sessions reach app functionality without a current acceptance record.
  • VPC gate: 100% of under-13 child members have a current verifiable-parental-consent record before any child-data write — zero child records written without a consentRef.
  • Re-consent completion: when a material version bump occurs, re-consent completion ≥ 85% of affected accounts within 14 days of the version going live; accounts that do not re-consent are suspended from child-data writes (and from the app, for the adult gate) until they do.

Window: continuous; every release must re-prove both gates before ship. A single violation of either gate fails the release condition — no ramp.

Measurement & audit

Instrument the consent substrate so every gate is provable. No child PII in any payload; child and parent references are opaque/hashed:

EventWhenKey properties
terms_acceptedaccount holder accepts ToS + Privacy Policyversion, timestamp — no user PII in BI tier
consent_capturedparent completes VPC for a childparentRef, method, consentVersion, timestamp, consentRef
reconsent_completedaccount completes re-consent after version bumpversion, days_since_bump, accountType (adult|parent)
(audit)release + nightlyassert 0 active sessions without a current ToS record; assert 0 child records lacking a consentRef

Privacy model for these events:

  • OPERATIONAL (child PII → VPC): consent_captured records method, parentRef, consentRef — retained for the life of the consent relationship.
  • INTERNAL BI: terms_accepted and reconsent_completed carry version + coarse timing only; no child identity; content-free; never marketing.
  • MARKETING: parent/account count and plan type only; never child-derived; never targets children.

Scope

This epic owns the consent-record substrate that the rest of the system builds on:

  • Adult ToS + Privacy Policy acceptance — recorded on first use before any app functionality is accessible; version-stamped; blocks the session if absent.
  • Verifiable parental consent (VPC) records for child members — method, consenting-parent reference, child reference, consent version, timestamp; the record is a hard prerequisite for any child-data write.
  • Consent versioning — each ToS/Privacy-Policy version and VPC version is tracked; a new version triggers a re-consent gate on next launch.
  • Re-consent on material change — accounts are blocked from the app (adult gate) or from child-data writes (VPC gate) until re-consent is recorded for the current version.

Out of scope here: COPPA-specific data-minimization, no-marketing, and parental-deletion controls — those are governed by Children's privacy (COPPA).

Non-functional requirements

Priority: P1 · Status: 🔨 to build

Statement. No account holder accesses app functionality until they have accepted the current Terms of Service and Privacy Policy; the acceptance is recorded with version and timestamp before any session proceeds.

Acceptance

  • Given a new account holder When they launch the app Then an acceptance gate is presented before any functional screen; no data is read or written until acceptance is recorded (terms_accepted fires).
  • Given an existing account with a current acceptance When they launch Then the gate does not re-appear.
  • Given the gate displayed When the user declines Then the session terminates and no data is written.

Priority: P1 · Status: 🔨 to build

Statement. The SDK service refuses to persist any child PII — name, emoji, age band, wallet, goals, chore completions — until a verifiable-parental-consent record (method, parentRef, consentVersion, timestamp) exists for that child, tied to the creating parent. Enforcement lives in the service (offline-safe) and in Supabase RLS (cloud-side); it cannot be bypassed by a direct write.

Acceptance

  • Given a parent creating a child member When VPC has not been captured Then the service returns an error and no child record is written (child_member_created requires a consentRef).
  • Given VPC captured Then consent_captured fires and the consentRef is present on the child record before the child write proceeds.
  • Given a direct Supabase write without a valid consentRef Then the RLS policy rejects the write, independent of SDK enforcement.

Priority: P1 · Status: 🔨 to build

Statement. Both ToS/Privacy-Policy versions and VPC consent versions are tracked as first-class values. The service compares the stored acceptance version against the current version at session start; a stale version triggers a re-consent gate before any data operation proceeds.

Acceptance

  • Given the current ToS version bumped When a returning account holder launches Then the re-consent gate fires before any functional screen is accessible.
  • Given the current VPC version bumped When a parent opens the app Then re-consent is required for each child before further child-data writes proceed.

Priority: P1 · Status: 🔨 to build

Statement. On a material version bump, affected accounts must complete re-consent within 14 days; accounts that do not re-consent are suspended from child-data writes (and from the app, for the adult gate) until they do. A reconsent_completed event is emitted on completion.

Acceptance

  • Given a version bump deployed When an account has not re-consented within 14 days Then child-data writes are blocked and a re-consent prompt is shown on next launch.
  • Given re-consent completed When reconsent_completed fires Then the gate lifts and child-data writes resume immediately.

Priority: P1 · Status: 🔨 to build

Statement. Consent records are append-only and immutable after creation; each record carries method, version, timestamp, and opaque parent/child references. Records are retained for the life of the consent relationship and are auditable without exposing child PII.

Acceptance

  • Given a stored consent record When any system process reads it Then method, version, and timestamp are present and unmodified.
  • Given the nightly audit When it runs Then zero child records lack a consentRef and zero active sessions lack a current ToS acceptance.

Priority: P1 · Status: 🔨 to build

Statement. ToS acceptance and VPC consent records are cached locally so the app functions offline for accounts with a current acceptance. The child-data write gate is enforced locally via the cached VPC record; without a cached record for a child, child-data writes are held until connectivity is restored and the record is confirmed from the cloud.

Acceptance

  • Given an account with a current ToS acceptance When the device is offline Then the app proceeds normally without re-presenting the acceptance gate.
  • Given a child with no cached VPC record When the device is offline Then child-data writes are blocked until the record is fetched on reconnect.

Architecture considerations

  • Consent record as a first-class entity. The substrate defines two record types: (1) an account-level ToS acceptance (version, timestamp, accountRef) and (2) a child-level VPC record (method, parentRef, childRef, consentVersion, timestamp, consentRef). These are separate entities; the VPC record joins to the child member, and deletion of the VPC record cascades to child PII (cascade owned by the COPPA epic, gated on this record existing).
  • Version gating in the service layer. At session start the service compares the current published version against the stored acceptance version; a mismatch surfaces a re-consent event to the presentation layer and blocks all data operations until the record is updated.
  • Service-layer gate (offline-safe). The SDK service enforces the VPC check locally using the Drift-cached record. No child-data write proceeds without a local VPC record for that child. This gate cannot be short-circuited through the repository or presentation layers — the enforcement lives in the Service, not the UI.
  • RLS as the cloud-side backstop. Supabase RLS policies mirror the service gate: a child row without a valid consentRef is rejected at the database boundary, independent of SDK enforcement. Defence-in-depth, not the primary gate.
  • Offline behaviour. Accepted consent records are written to the local Drift store at acceptance time. The app reads from this cache when offline. The child-data gate holds if the child's VPC record is absent from cache — the service does not optimistically assume consent.
  • Shadow member activation. A shadow household member must complete ToS acceptance before being activated as a full account — see Open decisions.

Design work (ahead of build)

  • Adult acceptance gate — the full-screen ToS + Privacy Policy presentation on first launch and on version bump; must meet the a11y floor (Atkinson body, readable contrast, scroll-to-bottom confirmation before the accept button activates); must not be dismissible without accepting or declining.
  • VPC capture flow — the parent-facing screen that collects verifiable parental consent before the child member is created; method TBD (see Open decisions); must clearly name the child, state what data will be collected, and confirm which parent is consenting.
  • Re-consent prompt — the version-bump screen shown at next launch; must distinguish between a ToS bump (adult gate) and a VPC bump (parent gate per child); must not be dismissible without acting.
  • Consent status surface — a lightweight entry in account settings where the adult can review their current accepted version and, for parents, the VPC status of each child.

Decisions (resolved for MVP-1)

Resolved — see the MVP-1 decisions log for the canonical record, rationale, and status legend (✅ decided · ⚖️ counsel confirms · 🔜 MVP-1.x).

  • 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 shadow member 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.

Out of scope (MVP-1)

  • COPPA-specific data-minimization, parental review/deletion, and no-marketing controls → Children's privacy (COPPA).
  • GDPR right-to-erasure on consent records, data-portability SLAs, and cross-jurisdiction retention limits → Privacy & GDPR (pre-EU launch).
  • General admin audit-log surface → Audit log.
  • Teen (13–17) consent flows under CCPA/CPRA or state minor-privacy laws — handled in COPPA epic or Privacy & GDPR, not here.