ADR-0008: Opt-in, mutual, read-only household sharing of plans and daily totals
- Status: Accepted
- Date: 2026-09-20
- Scope: Household, planning, diary, authorization, and audit
Context
ADR-0006 limits a household to two independently authenticated adults and forbids blanket access.
M2 Planning and the M3 household foundation need a concrete shared-record model that the API can
enforce record by record. The UX documents ask for shared planning with a visible author and for
household adults to coordinate without seeing each other’s private diary or photos.
Decision
- Ownership never moves. Every diary meal, water entry, plan item, photo job, subscription,
preference, and export/deletion right belongs to exactly one adult (
adultProfileId). Joining
or leaving a household changes only the householdId on the adult’s own profile.
- Two sharing switches per adult, both default off, stored in
household_sharing_settings:
sharePlans — my plan items may appear in the other adult’s week view.
shareDaySummary — the other adult may read my eight daily totals for a date.
- Plans are shared only when both adults opt in.
GET /planning/week includes the other
adult’s items only if sharePlans is on for both members. Shared items are flagged
readOnly: true with authorAdultId; only the author can edit, move, delete, or confirm them.
- A day summary is totals only.
GET /household/shared-summary?date= returns the other adult’s
aggregate nutrition for one day and nothing else; it requires their shareDaySummary switch.
Meals, food items, water entries, photos, and plan details are never included.
- Invitations carry no data. A single-use 12-character code (unambiguous uppercase alphabet)
expires after seven days, can be revoked by the inviter or declined by the invitee, and is
refused when the household is already full, the invitee already shares a household, or the
code belongs to the invitee. Accepting revokes other open invitations on both sides.
- Leaving is unilateral and clean.
DELETE /household/membership moves the adult into a fresh
solo household, clears their sharing switches, and revokes their open invitations. The other
adult keeps their household and their own records; nothing that was shared is copied.
- Export and deletion stay per adult. An export contains only the fact
sharedWithAnotherAdult; a deletion never touches the other adult’s rows and leaves their
household in place.
- Every sharing-relevant mutation is audited (
household.*, plan.*) with public IDs only.
Consequences
- Turning a switch off takes effect immediately on the next read; there is no retroactive copy to
clean up because nothing was ever copied.
- The week view and the shared summary are the only cross-adult reads in the API, which keeps the
authorization matrix small enough to test exhaustively.
- Two-sided consent for plans means one adult cannot see the other’s plan while hiding their own.
- Copy must keep saying what “share” means (plans read-only, totals only) before acceptance.
Follow-up
- Household coercion and post-separation research (TM-04) before any default changes.
- Consider a per-item “private” flag if adults ask to share a week but hide individual items.
- Revisit when a third cross-adult read is proposed; it must extend this ADR rather than bypass it.