← All privacy impact assessments
PIA: child accounts, the guardian invariant and the child-safe variant
Amended 30 October 2026: deleting a group. An owner can delete a group. Members are told at once, and the group is deleted seven days later unless the group's owner cancels; meanwhile anyone can export their own data or leave. Deleting removes everything the group holds for everyone in it, children included: messages, photos (sealed or not), lists, routines, baby records, the group's inbox and its attachments, and its keys. Our backups expire within 90 days and a deleted group is not restored from them. A star rating a member gave stays, with no group attached. Copies of the group's events in connected groups say the group no longer exists.
Amended 28 October 2026, built, not yet released: a child never sends or sees typing. Our database now refuses a member under 16 both directions of the chat's typing indicator, whatever their switch says; before this, it was off for a child only because the app set it off and showed it settled, and a child whose birth month was recorded before 21 October could still have had it on. Their switch stays shown as settled off. Members aged 16 or 17 are treated like adults: off unless they turn it on themselves (member types and first-use consents).
Amended 27 October 2026: when an owner leaves. When an owner leaves or erases their account, the longest-serving eligible admin becomes owner, or else the longest-serving eligible adult member. If nobody is eligible, the group stays without an owner, and members keep everything they could read. The group is told "
is now the group's owner", never why. An owner can't leave while nobody else may lead the group; erasing their account still goes ahead.
Amended 22 October 2026, before release: staged sign-up. Authorised addresses, including guardian-created child entries, can still sign up while the gate is closed. Founding and joining require an adult birth month or a confirmed guardian link; a previously invited adult with no month must declare one before creating a group, joining or inviting a child. A guardian's month still prevails. A new guardian link waits for the young person's confirmation; 13–17-year-olds use the guardian invitation path. A founder's new assurance is
declared, not proof of age. These controls also apply after the founder opens account creation more widely.
Amended 21 October 2026: member types are removed. The child's page names no member type, and nothing in Settings offers one (member types and first-use consents, the amendment at the top).
Amended 21 October 2026: a child's quiet settings are set by our database. When a birth month first shows that an account is under 16, our database turns off message previews, glance details, the typing indicator and reading the last message aloud, and keeps notification detail off, with no choice for the child to make. Before this, the app did that only when the child tapped OK on a card. This happens once per account: correcting the month later, or a month that ages out and is then corrected, doesn't set them again, and children already under 16 when this shipped were left as they were.
Amended 21 October 2026: who can lead a group. Only a person (not a shared display or a profile), active in the group, not under 18 by any birth month on record and not counted as a child, can be made an admin or owner, whether by a transfer, by support or automatically. Before this change a guardian-linked child with no birth month on record could be made an admin. Someone counts as a child when a birth month shows they are under 18, or when they have been linked to a parent or guardian with no adult birth month on record. That second part is remembered: it stays true if the last guardian link later goes, for example when the guardian deletes their account, until an adult birth month is recorded. Our earlier plan also required a birth month on record. That part waits until adults can record one (new accounts will give one when they sign up), and our security reviewers are reviewing the difference. Nobody who already holds a role was changed.
Amended 4 October 2026. A child's and a baby's records are no longer kept to Sydney when a model reads them: every group that is not Device-only runs its AI at Vertex
global(cloud-inference §12, which records this as an accepted residual). Guardian consent, the young-member AI consent (asked again for the new wording) and Device-only are unchanged.
Amended 14 October 2026, before the code: children see a group's earlier messages and photos, once an adult has acknowledged it for them. We decided that every member of a group should see its history, children included (the key architecture assessment, §3.7). Once a group turns it on, members' phones send the group's earlier keys to every person's phone that holds the current key. A child's phone receives them only after an adult in the group has acknowledged, on the child's behalf, that members can see the group's earlier messages and photos. Five routes record that acknowledgement: the admin who turns sharing on, for the children already in the group; the adult who approves a child's request to join; the adult admin who sends a child a direct invitation; a guardian of the child who is in the group; or an admin of the group. Our database refuses every one of them from someone who is a child: under 18 by the birth month their guardian gave, or linked to a guardian with no birth month showing they are an adult. A child's own "I've read this" never counts, though they see the same sentence. Until an adult has acknowledged, our database refuses to send the child's phone an earlier key. See §10 and §11.
Status: Built. The behaviour described here has been enforced by the database and the server since 8 September 2026, and this document was revised against the code the same day. Sections marked as built describe what the database and the server now do; §5.2 says which rows are structural, which are conventional, and which two are NOT built and stand in §11 as residual risk we accept. §12A grades every Code requirement met / partly / deferred. Written: 7 September 2026 · Last revised: 30 October 2026 (deleting a group); 27 October 2026 (when an owner leaves); 22 October 2026 (staged sign-up, before release); 21 October 2026 (member types removed; a child's quiet settings set by our database, and who can lead a group; earlier: 14 October 2026, a group's earlier messages and photos, before the code; §5.3 added 30 September 2026) Nothing here is legal advice. Children's Code citations are to the exposure draft; section numbers may move on registration (due 10 December 2026).
As built, 30 September 2026. §5.3's rule — that a 16- or 17-year-old's AI and voice features stay off until they give their own consent — has been built and merged, matching this section with no deviation we found, but has not yet reached anyone: it takes effect once our next release ships. Until then, a 16- or 17-year-old still has every AI feature on the same terms as an adult, as §5.3's own finding describes.
Read our self-assessment against the under-16 social media ban first. This design is only lawful if the conclusion there holds: the Online Safety Act Part 4A has no parental-consent exception, so if GroupApp were an age-restricted social media platform, an under-16 account would be prohibited however carefully it was built.
1. Purpose and scope
What it is for. Children live in the groups this app organises. Today they appear only as subjects of records — a name on a task, a face in a photo, a baby with a feed log — and the privacy policy says in terms that they do not hold accounts. That is a real limitation: a thirteen-year-old with their own chores, their own place in the calendar and their own things to say in the family chat has no way to use the app, and the workaround is a shared adult login, which is worse for everyone.
The feature gives a child their own account, inside their own family's group, with a version of the app that is smaller by construction rather than by configuration.
In scope: how a child account comes into existence; what it can and cannot reach; who consents to what; what happens when guardians leave, are erased, or separate; and how a child ages out.
Out of scope, assessed elsewhere: the ban analysis (our ban self-assessment); anything crossing a group boundary (our assessment of cross-group events); the baby tracker's own data (our baby tracker assessment) and the photo wall's (our photo wall assessment); the consent ledger's mechanics; encryption.
Not in scope and worth saying: this design does not make GroupApp a moderated platform. A group with a guardian in it is family, supervised — it is not platform, moderated. Adults in the group can post whatever adults post, and the app does not police it. That is what keeps the app out of the content-moderation business, and it is a limitation a parent should understand rather than a gap to be closed later.
2. Data involved
2.1 New collection
| Kind | Whose | Children's? | Sensitive? | Free text? |
|---|---|---|---|---|
user_birth_months.birth_month — a month and year, never a date of birth; a ROW of its own, not a users column, because every co-member reads the whole users row (our rule that a birth month is a row of its own and never a column on the user record) |
the account holder's | yes, for a child | no | no |
allowed_emails.child_of + allowed_emails.birth_month — the guardian who created the entry, and the month they declared, at the gate (as built: written by invite_child) |
the child's, linking to an adult | yes | no | no |
child_guardians rows — child ↔ guardian, plural |
both | yes | no | no |
groups.founder_assured_at / founder_assured_by — when and by what method a group's founder was assured to be an adult. Since 20 October 2026 no app request and no request with our service key can change it, an owner included; only the step that records an assurance can |
the founder's | no | no | no |
groups.children_allowed — tri-state (undecided / yes / no) (as built) |
the group's | no | no | no |
A consent ledger row per act, with given_by_kind (self / guardian / group_admin); as built two purposes: child_account (the guardian's) and child_account_assent (the child's) |
the consenting person's | sometimes | no | no |
Birth month, not date of birth. A month is enough to derive every threshold this design uses — 13, 15, 16, 18 — and a full date of birth is a stronger identifier for no gain. This is minimisation with a concrete payoff rather than a gesture: a leaked birth month is close to useless for impersonation, and a leaked date of birth is not.
No age verification data of any kind. No government identification, no Digital ID, no
document upload, no biometric estimate, no third-party assurance provider. Two reasons: it
would be disproportionate to the risk (§8), and it is precisely the class of collection the
Act's 63DA/63DB singled out as not required of even an age-restricted platform.
2.2 What a child account then holds, that any account holds
Chat messages, task completions, screen time logged for them, calendar entries, being named on events as who an event is for (event-for-whom.md), photos they post and photos they appear in, game state, their display name and avatar colour, push tokens, and — where they use the parts of the app that have them — read receipts and reactions. All of it is a child's personal information under the Code (a child is anyone under 18, not under 16).
2.3 What is deliberately not collected
- No date of birth, no address, no phone number, no school, no location of any kind. The app has no geolocation feature at all and this design adds none.
- Screen time is a per-member behavioural record, entered by people, with no device data, ranking, pushes, AI reads or wall surface. A child sees only their own row and is told who sees it (screen-time.md). The one counted metric that exists for ban-risk monitoring (child accounts and active guardians per group — ban self-assessment §9) is a count per group, not per person.
- No child's data reaches a model at all, because a child account has no AI surface (§5). That removes the cross-border disclosure question (s 26) and the automated-decision-making disclosure (s 28(2)(g)) for children in one move, rather than answering them.
3. Flows and locations
| Data | Device | Supabase (Sydney, ap-southeast-2) | GCP (australia-southeast1) | Model provider |
|---|---|---|---|---|
| Birth month, guardian links, child flag | entered by the guardian | stored; read inside RLS predicates | no | no |
| A child's chat, tasks, photos, games | written and read on the child's device | stored, RLS-scoped to the group | no | no — the child's own surfaces have no AI |
| Founder assurance (Door A, planned) | web, not the app | groups.founder_assured_* |
no | no |
| Card details for the $0 SetupIntent (planned) | web | never — Stripe holds them | no | no |
| Consent ledger rows | — | stored | no | no |
No new boundary crossing. Everything this feature adds stays inside Supabase's Sydney project. The adults in a child's group continue to use the assistant, the insight and the allocator, and those surfaces continue to send group data to a model under the existing consents; what changes is that the child's own account never does, and that the group's task and calendar data — which is about children by nature — is being moved to inference in Sydney (planned).
One flow to state plainly because it is easy to miss. A child's data still reaches a model when an adult asks the assistant about the group: a task titled "Ada's dentist, 3pm" is a child's personal information in an adult's request. Removing AI from the child account does not remove children from AI. Our rule that group data is processed in Australia is what addresses that, and the transparency copy must not imply otherwise.
4. How an account comes into existence: assurance once, declaration per child
An earlier draft put an age question at every join. That conflated two different things, and separating them is most of this design.
| Assurance | Declaration | |
|---|---|---|
| Question | Is there a real adult responsible for this group? | Which members are children, so the right rules apply to them? |
| When | Once, at group founding | When an adult creates a member's entry |
| How | Today we allowlist people we have met and know to be adults. Planned (Door A, growth-triggered): a $0 Stripe SetupIntent plus a birth-month declaration on the web. Either way recorded on groups.founder_assured_at / _by. |
One checkbox: "This person is under 16. I am their parent or guardian." No verification. |
| Serves | The ban: a child cannot found a group, and a founder was assured | The Code: guardian consent (s 13), the child policy (s 23), the child-safe variant, PIA scope |
| Fails how | A card is possession, not age — some Australian banks issue debit cards from 14. Reasonable steps, not proof. | A guardian declares an age wrongly. Bounded by: children cannot invite anyone, and every inviter is inside an assured group. |
Why not per-member checks. They would age-verify every member of every family to catch a rare misuse; that fails minimisation, it puts an identity check between a parent and their family calendar, and it is what the Code's s 8(5) posture explicitly lets a service skip by applying child-level protections to everyone instead. The failure mode being defended against is a group founded for the wrong purpose, so the group is the right place to check. If teen-only groups appear as a real pattern, the escalation is a stronger assurance method at founding — never per-member checks (ban self-assessment §9).
The existing choke point does the work. enforce_email_allowlist_on_signup, in place since
8 August 2026, already means nobody enters without an existing member creating their entry.
Child status becomes a property of that entry, stamped at the door, unbypassable by any code
path — which is why child accounts can ship under the current invite-only regime and do not
wait on open sign-up. We never add a bypass to that trigger while this
design is in flight; it depends on being the only door.
Amended 22 October 2026, before release: staged sign-up. The trigger above is still the door
while the founder's database gate stays closed, and guardian-created child entries still
authorise their addresses. Founding and joining now also require an adult birth month or a
confirmed guardian link; a previously invited adult with no month declares one first. A new
guardian link waits for the young person's confirmation, and a founder's new assurance is
declared, not proof of age. These controls also apply after the founder opens account creation
more widely.
5. Age bands and the child-safe variant
5.1 Bands
Three legal thresholds apply to the same person and they do not line up. Storing a birth month
and deriving flags at read time — is_under_16(uid), is_under_18(uid), usable inside RLS
predicates — means nobody ages out by cron job.
| Age | What they are | What that means |
|---|---|---|
| 0–12 | Profile, no login. Modelled the way group_babies is today: a name and an avatar the group holds. Chores and screen time can be assigned to them by a parent. |
No account, so no policy to show them, no consent to obtain from them, no ban question to answer. This is deliberately the default for young children rather than a lesser account. |
| 13–15 | Child account. The guardian creates the entry and consents; the child assents. The child-safe variant applies, enforced by the database. | Under 15 the guardian holds every consent (s 13). At 15 the child may hold their own — the OAIC's presumption of capacity — but the variant does not change, because the variant is about the ban and the Code's protections, not about who clicks "I agree". |
| 16–17 | Young person. Outside the ban, inside the Code. The full app, but AI and voice off by default and enabled only by the young person's own consent with the cross-border notice. Guardian link retained to 18. | The child-directed policy is still shown. Every Code obligation runs to 18. |
| 18+ | Adult. | On the eighteenth birthday month the guardian link lapses and the account is ordinary. |
Amended 22 October 2026, before release. 13–17-year-olds come in through a guardian's invitation, whose link waits for the young person's confirmation; a 16- or 17-year-old keeps the young-person rules above. A guardian's month still prevails over any month the account gives.
13 is a floor chosen, not derived. No Australian instrument sets it; it is the conventional minimum across comparable services and it keeps the app clear of the youngest cohort, for whom the profile model is the better answer anyway. It is a decision we can move, and if it moves the reasoning here moves with it.
5.2 The variant, by surface — as built (8 September 2026)
The column that matters is the last one. Structural means the database or the server refuses it whatever the app on the phone does; conventional means the app hides or declines to offer it and a different app talking to the same database would not; not built means exactly that, and the row is carried into §11.
| Surface | Under 16 gets | Enforced by | Structural or conventional |
|---|---|---|---|
| Assistant, dashboard insight, task allocation | Nothing. Fails closed. The dashboard shows the deterministic fallback brief; allocation is the deterministic floor. | Our assistant server reads is_child_account through the caller's own client on every request to the assistant, the baby summary and the ceremony facilitator (the ceremony still runs — deterministic script) and refuses before anything is built or billed; an RPC error is a refusal, and a check pins this. The dashboard-insight and task-allocation functions answer 403 child_account the same way. Restrictive policies on chat_sessions and chat_messages refuse the transcript rows the typed screen would write. The Assistant tab is ALSO hidden, which is the courtesy and not the enforcement. |
Structural |
| Voice grants | Cannot be created; a grant paired before the month was recorded stops working on the next turn | A restrictive INSERT policy on voice_grants; the voice service refuses the pairing call, and re-reads the predicate for the grant's owner on every turn, recording the refusal as a turn. The Voice row is hidden in Settings. |
Structural |
| Baby tracker | Unchanged — the child reads and writes it as any active member does. | Nothing. Outside the scope of what shipped that day; no policy on group_babies, baby_logs, baby_feed_sessions keys on the child predicate. |
NOT BUILT — §11 |
| Public plan ratings (since 21 October 2026, stars only; dish photos and comments removed) | A star rating, as any member | Nothing needed: a rating carries no text or image and other groups see only an average | — |
| Photo wall | Yes. No likes at all — no heart, no names, no count — and that is true for every user, not a child restriction (shipped 8 September 2026). | Shipped | — |
| Chat, tasks, calendar, games, ceremonies, intentions, thanks | Full. This is the app for them. Proved: a child in the same group posts to the chat, creates a task and an event, and writes a plan nobody else can read. | The guardian invariant is the safety property, not a feature restriction. The question bank and check-ins are deterministic for everybody, so the child's motivation layer is the same surface, not a reduced one. | Structural (the invariant), and no restriction to be conventional about |
| Group founding, invites, member admin | None | create_group_secure refuses an under-18 founder (GRP08); generate_group_invite, approve_join_request, reject_join_request, update_member_role, remove_group_member and transfer_ownership refuse an under-18 caller (GRP10); invite_child is adult-only. Everyone who joins, by any invitation, joins as a member (since 20 October 2026). Only a person who is active in the group, not under 18 by any birth month on record and not counted as a child (including someone once linked to a guardian with no adult month on record, even after the link goes) can be made an admin or owner (since 21 October 2026); nobody who already held a role was changed. Since 20 October 2026 role authority is structural too: no client writes a role or a status directly, and a trigger refuses making anyone under 18 an admin or owner whoever asks, the service role and the assistant included (GRP17). A group holds one owner at most, and a pending joiner can withdraw their own request. Since 27 October 2026, when an owner leaves or erases their account, ownership passes to the longest-serving admin who may lead the group, or else the longest-serving such member, and the group is told who in its chat, never why; an owner can't leave while nobody else may lead it. Residuals: an owner's account erasure leaves the group without an owner only when nobody else may lead it, until an active adult admin asks our support team, who then make the group's longest-serving active adult admin its owner (never a child, never displacing an owner, and the group is told in its chat); a birth month added later does not re-check an existing admin row (an admin whose age was unknown stays admin until demoted, which is allowed); and the invitee's own direct-invitation redemption and the wall or profile set-up insert a membership straight to active. |
Structural |
| Cross-group event invitations (shipped) | Cannot send, preview or redeem. Sees the event on their own group's calendar once an adult accepts. | Every RPC refuses is_under_18 with code: 'under_18' (the database change of 8 September 2026); the tables are RPC-only with no client grant, so there is no table path to add a policy to. The event-code chip is hidden on a child account. |
Structural |
| Report and block (server built 27 October 2026, HQ PIA-007) | Full, like an adult, except that a child can't block a linked guardian and a guardian can't block their child (they can report them). The guardian isn't told and has no read path. A report involving anyone under 18 is urgent: looked at within 24 hours. | report_message, report_member and block_member treat 13–17s as any person; block_member refuses across child_guardians either way; no client role reads member_reports, so no guardian path exists (member-safety-reports-and-blocks.md §7) |
Structural |
| Consents | A child under 15 holds none of their own except their assent | A restrictive INSERT policy on consents: no self row from an under-15 for any purpose but child_account_assent. At 15 the presumption of capacity applies and the policy stops matching; the variant above does not move. |
Structural |
5.3 16- and 17-year-olds: AI features off until their own consent — built 30 September 2026, not yet released
A finding first. §5.1 has said since 7 September that a 16- or 17-year-old's AI and voice features are "off by default and enabled only by the young person's own consent". That is still not true of the app today: our assistant server refuses only accounts under 16, and a 16- or 17-year-old has every AI feature on the same terms as an adult. We found this while designing member types (member types and first-use consents §6, R11), and no copy in the app claimed otherwise. This section records the fix we have built; it takes effect once our next release ships.
What will be enforced, once released. Every route of our assistant server that reaches a model or builds anything for one — the assistant, voice (pairing and every spoken turn), the dashboard insight, task allocation, the baby summary, task search, goal suggestions, the ceremony facilitator and the daily brief — will ask two questions of the caller's own access, on every request, before anything is read or spent:
- Is this a child account (under 16)? If so, refused, as §5.2 already describes.
- Is this account under 18? If so, has this member turned AI features on themselves? If not, refused, with a sentence telling them where to turn them on.
Both will fail closed: if either question cannot be answered, the request will be refused. An adult refused by a passing error tries again; a young person's words sent to a model cannot be unsent.
Whose consent it will be. The answer is the young person's own setting, which only they will be
able to write — a guardian, an admin or any other member of their group will not be able to turn it
on for them, and a test proves that with another adult in the same group. Turning it on will also
write a consent record, given by the young person themselves under the existing assistant
purpose; like every consent it will lapse after twelve months, and when it does the setting will be
turned off and our server will refuse again until they say yes. Turning it off will be one tap in
Settings.
Where they will be asked. On the Assistant tab, above where they type, in the same neutral way as every first-use consent: what is sent, to whom, where, how long, how to turn it off, two equal answers, nothing pre-selected. "Not now" will record nothing. The daily brief has its own consent too (the brief's own assessment, §8): a 16- or 17-year-old's own "yes" to the brief will be accepted by the brief route as their consent for that feature, and the brief's carry-over for existing members will never apply to anyone under 18.
What this does not do. It does not age-verify anyone: the age comes from the birth month the guardian gave when inviting the child (§4). An account with no birth month is treated as an adult, as everywhere else in this document. It does not change anything for a child account, which still has no AI surface at all.
| Surface | 16–17 gets | Enforced by | Structural or conventional |
|---|---|---|---|
| Every AI feature on our assistant server | Off until the young person turns AI features on themselves; the daily brief also accepts their own "yes" to the brief | Our assistant server reads the age and the member's own setting through the member's own access on every request, failing closed; a check fails the build if any AI route asks the child question without asking this one straight after | Structural (our server) |
| The setting itself | Only the young person can change it | Row-level security: a member's own settings are theirs alone | Structural |
| Lapse after twelve months | Setting turned off, asked again | The nightly consent sweep | Structural |
| The prompt on the Assistant tab and the Settings row | Shown only when the app knows the member is 16 or 17 | The app | Conventional (the server is the gate) |
What this variant is for, corrected on 8 September 2026 against eSafety's guidance. It is a privacy-Code measure — strictly-necessary-by-default collection (s 9), best interests (ss 10–11) — and a harm-reduction measure. It is not part of the argument that GroupApp is outside the under-16 ban: the guidance's Step 7 says age-based restriction of social features "is not to be given any meaningful weight" in the purpose test. The ban question is answered by how every member uses the service.
Updated 8 September 2026. That paragraph's last sentence used to read "and the ban self-assessment's §7A stocktake is the gate on this feature". It is not, any more. The app is outside the under-16 rule at the features step — no recommender feature and no logged-in feature — so s 63D does not bind it and the stocktake gates nothing (ban self-assessment §§5.5, 7). Everything else here is unchanged: the variant is still justified on Code and harm-reduction grounds alone, and it still contributes nothing to the ban argument.
Two implementation rules that are the whole point:
- "Hidden tabs" is not enforcement. Every row above needs a database-side refusal, proven
in a test with a child account in the same group. A stranger is excluded by
is_active_group_memberno matter what the policy says, so a test written against one passes even when the policy is inert (our rule that row-level security must be confirmed switched on before a policy is written, because an inert policy looks exactly like a working one). - Restrictive policies, ANDed with the existing permissive ones. One predicate per table, additive, rather than rewriting the group-membership policies — which keeps the change reviewable and keeps the child rule in one place.
An open question this document raises and does not answer. ANSWERED 8 September 2026, and
not the way this section framed it. The question was whether a child account should lose
attributed likes, message reactions and read receipts — each a "feedback feature" within Rules
s 4A(5)(a) — which would have made the child experience free of every feature the Rules name. It
noted the cost: a thirteen-year-old's messages silently not showing as read while everyone
else's do, a strange unexplained asymmetry inside one family chat.
We removed all three for EVERY member instead (ban self-assessment §5.3). Two things follow, and the second is the more useful lesson:
- There is no asymmetry, because there is no child-specific rule. Nobody in the app can see who read a message, who liked a photo, or who reacted to anything. The cost this paragraph worried about does not arise.
- The framing was wrong, and it is the framing eSafety's guidance warns against. Asking "what should a CHILD account lose" treats an age-gated restriction as though it moved the app's position, and Step 7 says an age-restricted experience carries no weight. The question that actually mattered was whether the SERVICE has a feedback feature at all — and once it is put that way, a child-only removal is obviously the wrong answer: it leaves the feature in front of everybody else while buying nothing. §5.2's table row for the photo wall now reads the same for a child as for an adult, which is the shape to aim for whenever a row here is tempted to differ for reasons that are really about the app rather than about the child.
Corrected 31 October 2026 (HQ PIA-016): reopened at the service level, and accepted by the founder. Emoji reactions on group-chat messages are back for every member, so the service has a feedback feature again and "nobody in the app can see ... who reacted to anything" no longer holds. Children react and see who reacted on the same terms as adults, with the same reasoning as above: a child-only rule buys nothing (Step 7), and their guardian is in the same chat by the invariant in §6. The service-level question this opens, whether GroupApp is an age-restricted platform now that its position rests on purpose alone, is the ban self-assessment's §15.9 finding, accepted by the founder on 31 October 2026 (its §16). Read receipts and photo likes stay removed. §2.2 already lists reactions among what a child account holds.
Amended 1 November 2026 (HQ PIA-016 addendum, the organising reaction set). Reactions are now one reaction per member per message, from five organising answers: 👍 Got it (with an optional when: in 15 min, later today or tomorrow), ✅ Done, ❌ Can’t do it, 🙋 Need a hand and ❤️ Thanks, not up to 3 emoji. Children choose and see them on the same terms as adults.
Corrected 1 November 2026, later (HQ PIA-016 addendum A5–A8, F-b; §5.2's chat row). A reaction now notifies the message's author, and only them: a guardian gets no copy of a push about their child's message, and no push about a reaction their child added. A child gets these notifications too (F-b: a child asking for a pickup needs the answer), but with the generic body only: if the reactor or the author is under 16, or a child with no birth month on record, the push says "Sam responded to your message" and never which emoji or the message's words (
push_text_author_okfor the reactor,push_text_recipientsfor the author). The child policy v1.8 says so. Walls and profiles neither send nor receive one.
6. The guardian invariant, and the edges where it hurts
The invariant: a child account is active only in a group where at least one of their
guardians is active. A group_members trigger, not a check in the app. This is the one guarantee
in the design that is absolute, and it is why child_guardians is a table rather than a column
— separated parents are the ordinary case, not an edge, and a child is active in any group
where any of their guardians is active. Co-parenting across two homes is a child in two
standing groups with one guardian in each.
The initial schema had a child member role, migrated away on 25 July 2026, and we do not
resurrect it. Child-ness is a property of the person, not of one membership.
Departures are the hard part, and they are where a bug hurts a child. Every one of these is a fail-closed refusal, in the same family as account deletion failing closed on the erasure ledger:
- A guardian leaving a group that would strand a child there is refused — "remove [child] first". The alternative is a child account sitting in a group with no responsible adult, which is the exact state the invariant exists to make unreachable.
- Guardian account erasure checks for dependants and refuses until they are re-homed or removed. This is the awkward one: an adult exercising a deletion right is told they must do something else first. It is the right answer — the alternative is honouring one person's erasure by stranding a child — but the refusal message has to explain, not just refuse.
- A child's own erasure is requestable by the child or by a guardian (s 32) and lands in the same off-provider erasure ledger as any other, so it survives a database restore.
- A group's last guardian being removed by someone else is the same refusal from the other side.
- Graduation at 18 lapses the guardian link automatically. It is not a deletion: the account continues, the child_guardians row stops having effect. The young person is told.
What the invariant does not do. It does not make the group safe. It does not review what adults post. It does not mean a guardian is watching. It means there is always a responsible adult present who chose to be there and can act.
As built (8 September 2026). enforce_guardian_presence on group_members: a guardian's
row cannot be deleted or moved off active while a dependant under 18 in that group would be
left with no other active guardian (GRP06, "Remove GRP07); request_join_group returns no_guardian / children_not_allowed
before writing anything, uncharged. Account deletion refuses a guardian with a live dependant
(409, in words, before the storage sweep) and is the one place a LAPSED link — a child now 18 —
is removed, because the FK cannot tell lapsed from live. The lapse itself is a predicate
(is_under_18), never a sweep; the child_guardians row stays as a record. "The young person
is told" at graduation is not built: nothing notifies anybody when a month rolls somebody
past 18 (§11). Separated parents work as designed: the child's join request into a second group
succeeds once any guardian is active there, and a test pins this.
7. Groups, not households — and children_allowed
Say "group", never "household". The app is about groups: co-parents, polycules, blended families, share houses, carer teams. "Household" imports one dwelling and one family shape, and it conflates three things the schema keeps apart:
| Axis | Column | Rule |
|---|---|---|
| What a group calls itself | groups.type (exists: Family, Couple, Extended Family, Share House, Housemates, Team, Group) |
Self-description and copy only, rendered through a single naming helper. Never an eligibility rule, never sent to a model, and never extended with labels that encode relationship structure — a stored "polycule" is sensitive information the app has no need to hold. "Group" stays the catch-all so nobody must name their arrangement. |
| What a group is for, and how long it lasts | groups.kind (planned: standing, event) |
Behaviour, never a label. See our assessment of cross-group events. |
| Who founded it | founded_by, founder_assured_at / _by (planned) |
A property of any standing group |
Children per group is a switch, not a type: groups.children_allowed, tri-state (undecided /
yes / no). A consent-class group setting: admin-only by trigger, announced in the group chat,
and refused if turned off while a child is a member. Every new group starts undecided,
and the first decision is an owner's or admin's, made inside Add a child, so "the group allows
children" and "this guardian is adding one" are one screen rather than two.
Why a switch rather than a type. A share house that is also three friends co-parenting is a real arrangement, and a type-based rule would refuse it while a family group that has become a flat-share would silently keep permission it no longer wants. The switch is a decision someone made, attributable and announced; a type is a label someone picked at signup.
As built (8 September 2026). groups.children_allowed is the fourth consent-class group
setting: owner/admin only by trigger (GRP04, with the app.consent_sweep arm on the admin
check), announced by announce_setting_change in three sentences ("decided that children can be
in this group"), and refused with GRP05 naming the child when set to no while an under-18 is
a member — that refusal is NOT armed, so no process can flip it over a child's head. The "same
screen" is Manage Group → Children: the three pills, the children and their guardians, and the
add-a-child sheet, which offers the switch to an admin when invite_child answers
children_not_allowed.
Amended 20 October 2026 (epic 001 D0 + C2; HQ PIA-001 §3.6). The creation default is now
enforced by the server: both create_group_secure overloads ignore the caller's
p_children_allowed and p_type and store undecided, and a direct insert by our own service
that tries to start a group as yes, no or a named type is refused. Initial creation is
not a consent act, and a group's name or type no longer suggests a value (the client helper that
did is gone). The first decision is an owner's or admin's, inside Add a child: the sheet says the
group hasn't said yes yet, and the decision asks "Allow children in this group?", says that a
parent or guardian can then add a child's account, that everyone in the group is told in chat, and
that it can be changed under Children but not to No while a child is in the group. "Not now",
opening the sheet and typing an address change nothing. A guardian who isn't an admin is told
that an owner or admin decides, with no switch and no request button. Existing groups keep their
value: nothing was rewritten. Installed app versions still send the old arguments, which the
server ignores.
The privacy policy's "children do not hold accounts" became false the day this shipped, and the one sentence was corrected the same day: §4 of the privacy policy now describes child accounts and points at the child's page. The child-DIRECTED policy (s 23) shipped on 8 September 2026, agreeing word for word with the child's page wherever they overlap (both are built from the same source); §12A now records that as met.
8. Risks and mitigations
| Risk | Who is harmed | Mitigation | Structural or conventional | Residual |
|---|---|---|---|---|
| A guardian declares a 14-year-old as an adult, deliberately or carelessly, and the child gets the full app including the assistant | the child | The declaration is made by the person who knows; children cannot invite anyone, so a misdeclaration cannot propagate; every inviter sits inside an assured group | Conventional — a checkbox | Accepted. §11 |
| A group is founded by a 15-year-old using a debit card | children in that group; the app's ban position | Founding assurance (§4); today, we allowlist only people we have met | Assurance is structural (a recorded column); what it proves is conventional | Accepted; escalation is stronger assurance at founding (Amended 22 October 2026, before release: while the gate is closed only an authorised adult can found, and must have a birth month on record showing 18 or over; a new group's assurance is declared, not proof of age.) |
| A teen-only group forms and the app becomes what the ban was written about | the app, and the children in it | The child cannot found or invite; the guardian invariant; the per-group count metric (ban §9) | Invariant: structural. Detection: conventional | Accepted, with monitoring |
| A child's data reaches a model | the child | The child account has no AI surface, failing closed, re-checked server-side each turn | Structural | An adult's request about the group can still carry a child's name (§3). Addressed by our Australia rule, not eliminated |
| A guardian leaves and strands a child | the child | Trigger-enforced refusal (§6) | Structural | — |
| Guardian erasure orphans a child | the child, and the departing adult | Fail-closed dependant check | Structural | An adult's erasure is delayed by a step. Accepted deliberately |
| A separated parent uses the group to monitor the other parent through the child | an adult; potentially the child | Nothing in this design. The app has no location or activity feed. Screen time is a per-member behavioural record visible to everyone in the group aged 16 or over; a separated parent still in the group can see it | Conventional (an absence) | Accepted, and named. Screen time is the accepted exception: a per-member activity view entered by people, with no device data, ranking, pushes, AI reads or wall surface. The child sees their own row and is told who sees it; leaving the group deletes entries about the leaver (screen-time.md). Amended 31 October 2026: an event can now say who it's for. The member filter matches it over events the phone already holds, with no per-person page, count or export, and when its notifications ship only parents or guardians who are in the event's own group will be told (event-for-whom.md) |
| A shared, unlocked phone means the child account is used by an adult or a sibling | the child | Nothing. No app fixes this | — | Accepted. §11 |
| An adult in the group posts something a child should not see | the child | Nothing — this is family, supervised, not platform, moderated (§1) | — | Accepted and stated to parents |
| A child's record outlives their interest in it — years of chores, chat and photographs | the child, later | Per-item deletion exists; erasure by the child or a guardian (s 32); the retention sweeps that exist | Partly structural | Accepted. §10 has the reasoning |
9. Legal basis and consents
The consent ledger is planned. Until it ships there is no record of a consent act for
anything except the terms acceptance already on users; the current state lives in switch
columns. This feature must not ship before the ledger, because a guardian consenting on a
child's behalf is exactly what the ledger's given_by column exists to record.
| Purpose | Who gives it for a child | Notes |
|---|---|---|
child_account (as built) |
The guardian: subject the child, given_by_kind = 'guardian', admitted by policy only where child_guardians links the two and the child is under 18. Twelve months; the existing sweep expires it. |
Recorded from the guardian's consent screen, a screen the guardian went looking for. The s 13(2)(b) reasoning is on the screen, and it says "we have not verified". A guardian may READ a dependant's consents (a new SELECT policy) — otherwise the row they wrote would be invisible to them. |
child_account_assent (as built) |
The child, as their own self row — the ONE self purpose an under-15 may write. Separate purpose rather than a new action, so the latest-row view cannot let one mask the other. |
Recorded from the child's page by "I have read this". It gates nothing and says so. |
terms |
13–15: the guardian's child_account stands for it; the child's own terms row at signup is refused by the under-15 policy and tolerated by the signup screen. 16–17: the young person. |
The child-directed policy shipped on 8 September 2026 — §12A. |
assistant, voice, on_device_brief |
Not available under 16 at all — there is nothing to consent to. 16–17: the young person's own, off by default. | Removing the surface is better than obtaining consent for it. |
baby_summary_to_model |
The group's admins, who are the parents by construction | Group-scoped, admin-only. Not a child-account consent. |
read_receipts |
— | No writer since 8 September 2026. Read receipts were removed for every member; the purpose stays in the closed list because a purpose that was consented to is a fact and the list mirrors a CHECK constraint. Nothing asks for it, and the expiry sweep flips a column nothing reads. |
overseas_processing (planned) |
Where a child account is present, one of the child's registered guardians must be among the two confirmers, enforced in the approval RPC | The ledger row records that it was given on the child's behalf |
cross_group_events (planned) |
Never a child — under-18s cannot redeem | See our assessment of cross-group events |
Consent must be voluntary, informed, current, specific and unambiguous, must not be bundled (s 14(3)(b)), and expires at twelve months (ss 15–16). Withdrawal is one tap (s 17). A personal stance preset may set preferences and never consents — a consent is always an individual prompt on a screen a person went looking for.
What the child is told (the s 33 posture) — as built. The child's own privacy page, "What
your parent can see", is the first row of Settings on an under-16 account and reachable whenever
they want it: what is kept, why, who sees it, what is only theirs (their plan; the absent
assistant conversation; the chat being the group's), what a guardian can do (take the yes back,
remove them, ask for deletion; the admin's children_allowed, announced to the whole group; and
that the app does not tell a parent what they looked at), how long, and the s 32/36 route they
may use themselves. Two sections are GENERATED from the same settings map the app itself uses,
so the page cannot promise a privacy the switches do not keep. It names no member type (member
types were removed on 21 October 2026, and a test checks its words). Written for a ten-to-twelve-year-old and scanned for overclaims. It is not shown at setup — there is no
child setup flow yet; the deviation from this paragraph's last sentence is recorded in §12A
(s 33 "as soon as in use": partly met).
10. Best interests of the child (exposure draft s 10)
What a child gets. Their own place in their family's organisation: their own chores, their own view of the calendar, their own voice in the group chat, their own account rather than borrowing a parent's. That is not a trivial good. A thirteen-year-old who can see that Thursday is their turn, and tick it off themselves, is being treated as a participant in the household rather than a subject of it. The games hub's per-user presentation and the ledger-visible parent adjustments already fit that shape.
What it costs them. An account is a record. Chat messages, completions, photographs and game history accumulate under their name from thirteen, and they did not choose the retention policy. They are in a space their parents administer and can read. And the app is being made attractive to exactly the age group a national law has just decided should not be on social platforms — which is a reason to be careful, not a reason the app is one.
What the safer design would have been, and why it was not chosen. The safest design is the one that exists today: no child accounts, children as profiles only. It was not chosen because it is not actually safer for the child — it produces shared logins, which are worse for the child's privacy from their siblings and their parents' contacts than an account of their own, and it excludes teenagers from a tool their family runs on. The second-safest is a read-only child account, which was not chosen because a child who can see the chores but not tick them is being shown their obligations without any of the agency, which is the wrong lesson.
Where the child's interests and the parent's diverge, and who won.
- The guardian can read the group. The child cannot have a private space inside their family's group. The parent's interest won, and openly: this is a family organiser, the guardian invariant is the safety property, and a private channel for a child inside a guardian-supervised app would be a worse thing to build than not building it. The child is told, plainly, rather than left to discover it.
- The guardian declares the age. The parental-responsibility model won. The alternative is age-verifying children, which is worse for them.
- AI is removed rather than made safe. The child's interest won against the parent's convenience. An open-ended generative surface for a minor is an AI companion, which is its own regulatory and safety category, and locality does not fix it. If a child assistant is ever built it is a command interface with a fixed vocabulary and template responses — the model classifies, it never composes prose to a child (our privacy posture, §5). The moment a model composes sentences to a child, this is a different product with different rules.
- The like count is gone for everyone. The child's interest won at no cost to the parent.
- A group's history (added 14 October 2026). A child sees the group's earlier messages and photos, like any member, once an adult in the group has acknowledged it for them. The child's interest in following their own family's conversation won over keeping a newcomer out of it; the cost is that what a child posted earlier, and photos of them, are seen by people who join later. The decision sits with an adult, never with the child alone, and our database refuses an acknowledgement made by a child.
The graduation design is a best-interests decision too. A child ages into more of the app rather than being handed all of it at 16 or having a switch flipped by a parent. Sixteen is outside the ban but still inside the Code, so the young person gets the full app with AI off by default and their own consent to turn it on — their decision, informed, and reversible.
11. Residual risk we accept
- A guardian can misdeclare a child's age. There is no verification and there will not be one. This is the parental-responsibility model working as designed, and the alternative — verifying children's ages — is worse for children. Bounded by children being unable to invite anyone, and by every inviter being inside an assured group. (Amended 22 October 2026, before release: and by a new guardian link waiting for the young person's confirmation.)
- A false birth month is accepted (amended 22 October 2026, before release). A founder's
assurance is now their own declaration (
declared), not proof of age: a 13- to 17-year-old who gives a false month is treated as an adult. Accepted as a beta residual, in both phases. - A shared, unlocked phone defeats every account boundary in the app. No app fixes this and this one does not pretend to. It is worth stating to parents rather than leaving implied.
- A guardian-present group does not sanitise what adults post. The model is family, supervised, not platform, moderated. This is what keeps the app out of content moderation, and it is a real limitation.
- The whole design rests on the ban self-assessment being right. If GroupApp is an age-restricted platform, child accounts are prohibited outright and this feature is not merely risky but unlawful. Accepted on the reasoning in that document, with its review triggers as the early warning.
- A child's record accumulates from thirteen. Per-item deletion and erasure rights exist; no automatic expiry of a child's own content does. Accepted; a retention design for a graduating account is a candidate for the roadmap rather than this release.
The feedback-feature question is unresolved.Resolved 8 September 2026: likes, reactions and read receipts were removed for every member, not only for children (§5.2). No longer a residual risk here; the app-level residual risks that replaced it are in the ban self-assessment's §12, and the one that matters is the recommender reading rather than anything about children. Corrected 31 October 2026: reopened at the service level when reactions came back (HQ PIA-016), and accepted by the founder (ban self-assessment §15.9, §16): a feedback feature is present for every member, under-16s included, and the position rests on purpose. Accepted here as that same risk, with the guardian in the same chat.
Added as built, 8 September 2026. Each is a risk we accept:
- A child account can read and write the baby tracker. §5.2 said "hidden — a sibling's
health record is not a child's to browse"; nothing was built. A thirteen-year-old in a group
with a baby sees the feed log, the medicine doses and the notes, and can log a nappy, exactly as
any active member can. The fix is one restrictive policy per baby table keyed on
is_under_16(auth.uid())plus hiding the tool, a small database change; it was outside the scope of what shipped that day. Recommended before the first child account exists in a group that has a baby. A child account can submit a public review and a dish photo.Closed on 21 October 2026: reviews are stars only, shown to other groups only as an average.- Nobody is told at 18. The link lapses correctly and silently. The young person's account gains nothing visible — the variant is under 16 and they left it two years earlier — so the cost is small, but "the young person is told" (§6) is an unmet sentence.
A child made admin by an adult admin is an admin.Resolved 20 October 2026 (Settings B7): no client writes a role directly any more, and a trigger refuses making anyone under 18 an admin or owner whoever asks, the service role and the assistant included (GRP17). An invite that grants admin privileges to adults still cannot admit someone under 18 as an admin. What remains: an adult made admin whose birth month is recorded afterwards stays an admin until somebody demotes them (demoting is allowed); nothing re-checks existing admin rows when a month is added. The member-admin RPCs refuse such an admin (GRP10).- The child's page is reachable, not shown. s 33 asks that the child be told "as soon as the mechanism is in use"; the page exists from the moment they sign in but nothing presents it. A first-sign-in interstitial for an under-16 is the fix, one screen.
The child-directed policy (s 23) is not written.Resolved 8 September 2026: the child-directed privacy policy is the document — reachable from the child's page, the guardian's consent screen and Settings' Legal section, and published on the public site at/privacy/children. The adult policy's §4 now also states the guardian's own view of what they can see and do for a dependant, rather than only pointing at the child's page.- Added 14 October 2026: an adult acknowledges a group's history for a child, and the child is told but not asked. A child sees the group's earlier messages and photos like any member, and their own earlier posts and photos of them are seen by people who join later. The decision is the adult's, by one of the five routes in the amendment above, and the child sees the same sentence. We accept that the child is not asked, as for membership itself, because the group's chat is the group's (the child's page already says so) and shutting a child out of its history would make them the one member who cannot follow it. The child's own page and the child privacy policy (version 1.5, 14 October 2026) say it in their words: people who join the group later can see what was posted before they joined, including what the child posted.
- The variant refuses; it does not hide everywhere. The Assistant tab, the Voice row and the event-code chip are hidden; the baby tool and the review button are not (above). A child who finds a hidden surface by deep link is refused by the server, so the risk is confusion rather than disclosure.
Amended 31 October 2026 (HQ PIA-016, reactions and deleting your own message). A child can delete a message they sent in their group's chat, like any member, and their linked parent or guardian can delete their child's message while the child is under 18 (the link lapses at 18, as everywhere else), including after the child has left the group. Everyone in the group sees the same "Message deleted" line; only the child's own phone says "Removed by your parent or guardian", from a record nobody else can read. No other adult in the group can delete a child's message. The child policy's line about asking an adult to remove a message changes in the next policy edition.
12. Review trigger
Before the child-account work starts — this document is the gate.That work started and shipped on 8 September 2026, and the document was revised against the code as it shipped (this revision).- Before the first child account is created in a group that has a baby — the "not built" baby row in §5.2 becomes a live exposure at that moment, not before. Build them, or accept them again with that fact in view.
When the child-directed policy lands — §9'sIt landed on 8 September 2026; §9'stermsrow and §12A's s 23 line change.termsrow and §12A's s 23(6) and s 23 lines are updated in this revision.- Any change to the variant table, the age bands, the guardian invariant, or
children_allowed. - When sign-up opens — Door A replaces manual allowlisting as the assurance, and §4 is re-argued. (Amended 22 October 2026, before release: the staged code is assessed, and the database gate stays closed until a founder operation; this trigger fires on that opening.)
- If a child account ever gains an AI surface, cross-group reach, or a private channel.
- Any change to who may acknowledge a group's history for a child, or to the rule deciding who counts as a child for it (added 14 October 2026).
12A. Requirements confirmed against the exposure draft (read 8 September 2026) — graded as built
Read from our copy of the Children's Online Privacy Code exposure draft. Each is a concrete obligation the child-accounts work must carry, with the section it comes from, and — now that the work has shipped — whether it is met, partly met or deferred, and where.
- s 13(2)(b): reasonable steps to confirm the consenting person has parental responsibility. Met, on the terms the design chose. The guardian is self-declared and the consent screen says "we have not verified"; what it relies on — an adult member of an assured group, who created the entry themselves, named on the ledger row — is written on the screen, under "WHAT WE RELY ON", and a copy test asserts the word "verified" appears once and only to deny it. Whether that IS reasonable steps is the residual in §11.
- s 13(3): after a guardian consents, the child gets an age-appropriate notice listing the seven items. Met: the child's own privacy page carries what is kept, why, who sees it, how long (12 months, stated), the consequences (nothing is removed by withdrawal; the account exists because they were invited), how to withdraw and the route, how it is used, and the recipients (the group, nobody outside it), in a 10–12-year-old's register, scanned for overclaims. The two settings sections are generated from the scope map.
- s 15(4)/s 16: the consent period is stated and never exceeds 12 months. Met: the
guardian's
child_accountrow carriesexpires_attwelve months out; the existing sweep expires it; both screens state the period; the guardian's screen shows when it lapses. - s 20: a child under 15 gives assent, separately. Partly met. The child's own
child_account_assentrow, written by "I have read this" on their page, is a separate act by a separate person under a separate purpose. What it is assent TO is the whole account, not the three specific things s 20 names (sensitive information, secondary uses, contacting the guardian) — the app collects no sensitive information about a child account, has no secondary use, and does not contact guardians, so there is nothing more specific to assent to today. If any of those three appears, this becomes a per-thing assent. - s 9(2): a child must be able to control non-necessary collection, use and disclosure. Met, by absence more than by switches. A child account has no AI, no voice, no cross-group reach, so the two collections that were "non-necessary" for an adult do not exist for a child. Their personal switches remain theirs (on-lock-screen answers, the two lock-screen rows settled for every under-16 and named as such on their page). The typing indicator is no longer one of them: since 28 October 2026 our database refuses an under-16 both sending and seeing typing, and their switch is shown settled off.
- s 23(6): the child-directed policy must explain anonymity / pseudonymity. Met (8 September 2026). The child-directed policy's "You use your own name" section says plainly there is no anonymous or made-up way to use the service — a name and a picture are required to join a group — and names the one exception: a complaint may be sent without a name, the same fact the child's own page already stated.
- s 33: a child must be told, as soon as the mechanism is in use, of any guardian monitoring or
control mechanism, easily accessible. Partly met. The page names every such mechanism
(the guardian can take the yes back, remove them, ask for deletion, change the month; the
admin's
children_allowed, announced) and is the first row of their Settings — easily accessible. It is NOT presented at first sign-in ("as soon as"); §11. - s 32(1)(b), s 36(1)(c): a person with parental responsibility may request destruction or access for a child under 15; a child of any age for themselves. Met: our privacy-requests page is updated for accounts, the child's page gives the address and says they may write themselves and need no name for a complaint, the guardian's screen gives the same address. A guardian's own erasure is refused while a dependant names them (409, in words); a child's erasure goes through the ordinary path.
13. Sources
Primary: exposure draft of the Children's Online Privacy Code (ss 8, 10, 13, 14, 15–17, 23,
26, 28, 32, 33, 38–39) as summarised in docs/privacy_posture.md §4.2 — the exposure draft
itself has not been re-read for this document, so every section number here is as good as that
summary and no better. Online Safety Act 2021 Part 4A and the Rules, verified — see
our ban self-assessment §14.
In our code: the signup allowlist trigger migration of 8 August 2026 in
supabase/migrations/; constants/legalTexts.ts (the sentence that changes); our rules that invite-only is enforced in the database, that row-level security is
confirmed enabled before a policy is written, and that a retention job ships before a retention
claim; docs/privacy_posture.md §5.
Built (8 September 2026): supabase/migrations/…_ws8_child_accounts.sql;
__tests__/child_accounts_rls.test.ts; lib/childAccounts.ts, lib/childVisibility.ts,
lib/consents.ts; app/child-privacy.tsx, app/child-consent.tsx,
components/Group/ChildrenSection.tsx; agent-server/src/childAccount.ts;
supabase/functions/delete-account, generate-dashboard-insight, ai-task-allocator.
Also built (8 September 2026): CHILD_PRIVACY_POLICY and the guardian's-view paragraph in
constants/legalTexts.ts; lib/__tests__/childPrivacyPolicy.test.ts; the Legal section in
app/settings.tsx; the policy links in app/child-privacy.tsx and app/child-consent.tsx;
site/build.mjs's /privacy/children page.
Also built (19 October 2026): supabase/migrations/…_non_admin_invites_never_grant_admin.sql
(an invite made by anyone other than an owner or admin never grants admin).
Not built: the two §5.2 rows marked so, and everything in §11's "added as built" list.