← All privacy impact assessments
PIA: intentions, beneficiaries and the motivation layer
Status: Built — WS22 shipped 2026-09-08 (#342). Written before the code, as the gate requires; every mechanism below is marked planned or built as it stood at review — read the marking, not the tense. Status raised to built 2026-09-09. Written: 2026-09-08 · Author: WS22 · Issue: #342 Nothing here is legal advice. Children's Code citations are to the exposure draft; section numbers may move on registration (due 10 Dec 2026).
This assessment is unusual in one respect and it is worth naming at the top. Every other PIA in this register is about data a household already produces — a feed, a photograph, a message — and asks who can see it. This feature asks people to type something the app has never held before: why they are doing something, and who for. That is a statement about a relationship, and about a child in a large share of cases. The interesting risks here are not access-control risks. They are the risks of holding a motive at all, and of a screen that reads a household's own answers back to it in the wrong voice.
1. Purpose and scope
What it is for, in one sentence. People do the work when they can see who it is for, so every task can carry a beneficiary and a reason, each member gets a private plan for today and tomorrow, and thanks travels as a message from one person to another.
What it is deliberately not. It is not a scoring system. Nothing in WS22 writes a
game_ledger row, awards a point, counts a streak, or ranks anybody. That is a design constraint
taken from the psychological literature this feature is built on — extrinsic rewards for caring
work reduce the caring (the crowding-out finding) — and it is also what keeps the feature clear of
the ban self-assessment's feedback-feature line (§6, and
2026-09-ban-self-assessment.md §5.3).
In scope: the beneficiary and reason on a task; the private intentions table; the question bank; the rewritten daily brief; thanks as an addressed message; claiming an unclaimed need; the assistant check-in; the child's own record page; the monthly invisible-work prompt.
Out of scope, covered elsewhere: the child-account model itself
(child-accounts.md, which gates WS8 and consumes the record page built
here); the group privacy levels and the Device-only tier (WS19/WS20, planned — §4 states what
WS22 owes them); Tier 1 encryption of intention text (WS14, planned — §3); the games hub, which
is a separate optional layer and is untouched.
2. Data involved
| Kind | Whose | Children's? | Sensitive? | Free text? |
|---|---|---|---|---|
group_tasks.beneficiary_kind — member / baby / pet / everyone |
the group's | when the beneficiary is a child, yes | no | no — a closed CHECK list |
group_tasks.beneficiary_user_id / beneficiary_baby_id — real foreign keys, on delete set null |
the group's | yes when it names a child | no | no |
group_tasks.beneficiary_label — a pet's name, or nothing |
the group's | no | no | yes |
notes_meta.why — one line: what will be better once this is done |
the author's, about the beneficiary | yes when it is about a child | possibly — "so Ada can get to physio" is health information a parent typed | yes |
user_intentions.text — a free-text goal, or a copy of a task title |
the member's own | when the author is a child, yes | possibly | yes |
user_intentions.why, .obstacle, .when_text — the question bank's answers |
the member's own | as above | possibly | yes |
user_intentions.day / .week_key — a calendar date or week in the group's zone |
the member's own | as above | no | no |
user_intentions.beneficiary_kind / _id / _label |
the member's own, about another person | yes when it names a child | no | the label only |
user_intentions.status — planned / done / dropped |
the member's own | as above | no | no |
user_intentions.shared_message_id — the chat row, when the member chose to post their plan |
the member's own | as above | no | no |
A thanks — an ordinary group_messages row, from one member, naming the doer |
the thanker's | when a child sends one, yes | no | yes — the member may edit the canned note |
What is deliberately not collected, which is the more useful list:
- No count of anything. Not thanks received, not intentions kept, not tasks done for a person, not a rate, not a streak, not a "most thanked". There is no column that could hold one and no aggregate anywhere in the feature.
- No record of a decline. "Not this time" on a carry-over and "Not this time" on an assistant check-in both write nothing — not a row, not a flag, not a timestamp. This is the rule The Deal already keeps for a declined handoff, for the same reason: a refusal in a durable history is a receipt somebody can be shown later.
- No record of who was asked. The assistant check-in's round-robin cursor is a per-group position, not a per-member log of invitations and answers.
- No inferred motive. The
whyis only ever a member's own words or their tap on a fixed question. Nothing in the app derives, guesses, or proposes a reason a person does something for their family. §4 makes this structural. - No cross-member visibility of intentions. Owner-only RLS; a second member of the same group reads nothing, and that is proven in the db suite rather than asserted here.
Strictly necessary (exposure draft s 38(2)(b)), per item. None of this is necessary to provide GroupApp, and the honest answer is that it is optional and inert until a member uses it:
- A task with no beneficiary is an ordinary task; the columns are nullable, no screen requires them, and a household that ignores the feature produces none of this data.
user_intentionshas no rows until a member taps "add to today". There is no backfill, no seeding, and no migration that writes one.- The question bank asks at most one question a day, only about an item the member already created, and every question is skippable with no record of the skip.
- The monthly invisible-work prompt is opt-in and its answers become the member's own tasks.
So the strictly-necessary claim is not "we need this to run the service". It is that nothing is collected until the person it belongs to chooses to create it, which is the form of necessity available to an optional feature. Where a child is the subject rather than the author — a task "for Ada" — the data collected about Ada is a name already in the group and a line about what she needs, which is the minimum the feature can work on.
3. Flows and locations
| Data | Device | Supabase (Sydney, ap-southeast-2) | Reaches a model? | Crosses a group boundary? |
|---|---|---|---|---|
| Beneficiary kind / id / label | rendered as a face on the card | stored plaintext on group_tasks |
yes — via the brief, as a first name or "everyone" | no |
notes_meta.why |
typed, rendered under the title | stored plaintext in the existing jsonb column | yes — via the brief, under the same consent as any task note | no |
user_intentions rows |
the member's own plan screen | stored plaintext, owner-only RLS | yes, and only the reader's own — the brief is generated per user | no |
| Question-bank answers | tapped | written to the columns above | as above | no |
| A thanks | composed on the thanker's device | an ordinary group_messages row |
as any chat message does today — which is to say the brief does not read chat | no |
| A claim | tapped | group_tasks.assigned_user_ids — an ordinary assignment |
as any assignment does | no |
| The assistant check-in | the question is rendered on the asked member's device | reads that member's own intentions and the group calendar | yes — that member's own plan only | no |
Three flow facts that carry the weight:
- The brief is already a per-user generation.
useDashboardInsightkeys its cache per reader, so adding the reader's own intentions to it does not create a new disclosure path — nobody else's copy of the brief can contain them. Adding another member's intentions to any brief would, and nothing does. - The question bank never calls a model. It is a fixed list of questions whose answer buttons are the group's own roster. This is what lets a child, and a Device-only group once WS19 lands, have the whole motivation layer with no inference in it at all.
- Nothing here reaches a log. The feature writes no log line naming a member, a beneficiary
or an intention (AGENTS.md → Identifiers In LOGS Are Data An Erasure Cannot Reach).
user_intentions.user_idandgroup_idare foreign keys that cascade on account and group deletion, so an erasure reaches every row.
A note on the beneficiary's shape, because building it turned up something worth recording.
The beneficiary is two foreign-keyed id columns rather than one polymorphic uuid, precisely so an
erasure reaches it: a single untyped id could carry no key, and a departed member's id would have
sat in group_tasks for ever. The first version then made the natural mistake of also requiring
the id ("kind member implies a user id"), which makes on delete set null produce a row that
violates its own constraint — so Postgres refuses the deletion, and a constraint written to
describe the data blocks the erasure it was meant to enable. The constraint now says which column a
kind may use and not that the subject still exists; a named kind with no id is the erased state,
and the client renders no face for it. Caught by the db suite rather than by review, and the test
that caught it is kept as the assertion.
Encryption, stated honestly. Intention text and the why are plaintext at rest today.
They are Tier 1 content by the rule in AGENTS.md → Encryption Is Two Tiers (large mute content a
person typed), and they are named in WS14's scope. Until WS14 ships, nothing in the app's copy may
say otherwise, and this document is the record that it does not.
4. What reaches a model, and when
The gate is the one that already exists. WS22 adds no new consent purpose and no new switch.
| Surface | Gate | Fails to |
|---|---|---|
| The daily brief (now including the reader's own intentions and beneficiaries) | user_tool_settings.dashboard_insight — the existing per-user tool setting, consentClass: true in lib/settingsScope.ts, ledger purpose assistant |
the deterministic fallback brief, which is written in the same voice and needs no network |
| The on-device brief | user_tool_settings.dashboard_insight_on_device, purpose on_device_brief |
the server brief, then the fallback |
| A baby named as a beneficiary, in the brief | group_babies.show_recent_summary as well, read through showsRecentSummary, which fails closed on an absent value |
the baby's name is replaced by nothing — the item is described without the beneficiary |
| The assistant check-in | user_tool_settings.dashboard_insight (it is the same reader, the same consent, the same brief pipeline) |
no check-in; the need still appears on the shared list, which is deterministic |
| The question bank | no gate, because no model is involved | n/a |
| Thanks, claims, sharing a plan | no model at all — they are chat rows and assignments | n/a |
Two absolute rules, both of which are the reason this section is short:
- The model never writes state. It receives a digest and returns prose. No answer it produces
sets a beneficiary, a
why, an intention, an assignment or a status. That is what makes "a wrong guess about why somebody does something for their family" structurally impossible rather than a prompt instruction. - The model never proposes a motive. The
whyin a prompt is text the member typed. The prompt's own rules forbid inventing one, and the banned-vocabulary test pins the register, but the load-bearing property is the first rule, not the prompt.
Children and Device-only groups see no model. Today the first half is a WS8 property that does not yet exist (there are no child accounts) and the second is a WS19 property that does not yet exist (there is no group privacy level). What WS22 owes them, and builds now, is the deterministic half: the question bank, the fallback brief in the same voice, the deterministic needs list and a deterministic check-in card. When WS8 and WS19 land, routing a child or a locked group to those paths is a routing decision with the destination already built. This document is the record that the destination was built first; if WS8 ships a child account whose home screen calls the model brief, that is this rule being broken.
5. Risks and mitigations
The first two rows are the ones this feature exists to be careful about. They are harms to a person's motivation and to their relationships, not to their data, and the Code asks about emotional and developmental impact (s 38(2)(f)) in exactly those terms.
| Risk | Who is harmed | Mitigation | Structural or conventional? | Residual |
|---|---|---|---|---|
| Crowding out. The app attaches a reward to caring work, and the caring becomes about the reward — the finding this feature is built to avoid reproducing | every member, and the children who are the beneficiaries of the work | Nothing in WS22 is scored: no game_ledger write, no points, no streak, no count of any kind. Thanks is a message, not a tally |
Structural for the ledger (a game_ledger row needs a kind in the game_ledger_delta_scope CHECK, and WS22 adds none) and test-pinned for the rest — a copy scan and the extended features-step scan reject thanksCount, streak and their relatives |
A future workstream adds a counter in good faith. The scan is what fails |
| Guilt. A member opens the app and is told what they failed to do. A carry-over is the sharp case: the app knows they planned it and did not do it | every member; most acutely a parent already short of sleep, and a child who is learning what the adults around them think of effort | A carry-over shows once, worded "still on your list", with a one-tap "not this time" that asks no question and records nothing. The brief's banned-vocabulary test rejects should have, failed, didn't, again, only and comparatives, in the model prompt and in the deterministic fallback both | The vocabulary is test-pinned (a scan, mutation-tested); "shows once" is structural (it is date arithmetic on the row, not a counter) | A sentence that shames without using any of the banned words. Accepted — §8 |
| A member's private plan becomes visible to the household | the member | Owner-only RLS on user_intentions; sharing is an explicit act that posts an ordinary message the member composed |
Structural, and proven with a second member of the same group rather than a stranger | — |
| The household learns who was asked to cover a need and declined | the person who declined | A decline writes nothing. The round-robin cursor is a position, not a log. The household sees only "claimed by Sam" | Structural — there is no column | Somebody infers a decline from a silence. Accepted; it is the same inference an unanswered text message carries |
A why about a child records health information |
that child | Nothing filters it, and nothing should — "so Ada can get to physio" is what the parent needs to write | Conventional: the field's copy asks what will be better, not what is wrong | Accepted and disclosed. Same shape as the cross-group RSVP note |
| A child's own record page becomes a performance review | that child | Own record only, no comparison, no streak, no points, no total. Faces and what was done, for whom | Conventional — a component's contents, pinned by a copy scan | A guardian reads it as one anyway. Accepted; §7 |
| The beneficiary face turns a task list into a picture of who does most for whom | every member; the person doing least | Per-person counts are never shown. Coverage is stated ("Thursday: covered"), the number of people is not | Test-pinned by the copy scan; The Deal's balance view remains the only surface where load is compared, and it compares from the last deal | Accepted — the app deliberately keeps exactly one such surface |
| An intention naming a child reaches a model in the reader's brief | that child | The assistant consent gates it; a baby beneficiary additionally needs show_recent_summary, failing closed; the digest carries a first name, never a note about the child |
Gate is structural; what the digest carries is conventional, pinned by the prompt test | Region is wherever the assistant runs until WS20. Must be stated in copy |
| Intention text is plaintext at rest | the member | None today. It is named in WS14 | — | Accepted and disclosed — §3, §8 |
| A thanks becomes a way to nag: "thanks for finally doing it" | the doer | Canned notes only, scanned for shaming grammar; the member may edit, and then it is an ordinary message they wrote and own | The canned set is test-pinned; an edited one is conventional — it is a person's own speech in a chat, which the app does not police | Accepted |
| A thanks is read by the whole group, not only by the person thanked | the doer, who may not want the attention | The app has no direct message, so the group chat is the only channel a message can travel on. The sheet says so before it is sent, in those words | Structural that it is an ordinary chat row; the disclosure is test-pinned | Accepted and disclosed. Building a private channel is a much larger change than a sentence, and inventing one for this would be a new messaging surface with its own assessment |
| A child is thanked for work an adult assigned them, teaching that care is transactional | that child | Thanks names the act and the person, never a count; nothing accumulates | Structural — nothing accumulates | Accepted; §7 |
6. The features-step rule, re-run for this feature
The app's position under the under-16 rule is settled at the features step: it has no
recommender feature and no logged-in feature (Rules s 4A), so its purpose is never argued. WS22 is
the first feature since WS21 removed read receipts, likes and reactions that plausibly touches
4A(5)(a) — displaying to a member information about the extent to which other end-users have
engaged with material posted by them — so the test is re-run rather than assumed.
| Candidate | Is it a feedback feature? | Why |
|---|---|---|
| A thanks | No — and this is the sharp one | It is a message from one person to another, rendered as an ordinary message and nowhere else. It is not displayed on the task, it is not counted, and there is no "most thanked". A member never learns how many people responded to anything they did. A private message of thanks is the same object as any other chat message, which the assessment already treats as content rather than feedback |
| The beneficiary face on a card | No | It says who the work is for. It reports nobody's response to anything |
| A claim | No | It is an assignment — a coordination fact, the same class as an RSVP, which §5.3 of the assessment already keeps |
| Coverage ("Thursday: covered") | No | It is a fact about the week, not about a person, and it carries no number of people |
| The child's own record | No | It is that child's own record of their own acts, shown to them. Nobody else's response to it appears |
| A carry-over | No | It is the member's own plan, shown to themselves |
What would make one. A thanks count on a task; "you've been thanked 4 times this week"; a
"most helpful" list; a reaction on a thanks; a viewer list on a shared plan; a streak of kept
intentions. Each is a natural product idea and each changes what the app is in law. That is a
conversation with the owner and a revision of the ban self-assessment, not a PR — and
components/Chat/__tests__/noFeedbackFeatures.test.ts gains thanksCount, streak and their
relatives so it fails first.
The endless-feed and ranking limbs (s 4A(4), and the recommender limb) are untouched. The dashboard's intentions section is the member's own list, bounded by the horizon and ordered by time; the needs list is the group's own unclaimed tasks, ordered by when they are due. Nothing is ordered by predicted interest or by anything inferred about the reader.
7. Best interests of the child (exposure draft s 10)
Children appear here in two roles and they carry different arguments.
As beneficiaries — the common case. A task says it is for Ada. Ada's name and face are already in the group; what is new is a line about what she needs, written by a parent. What the child gets: work that is more likely to be done, by a household that can see who it is for. What it costs: a durable record, in a family app, of a child as the object of other people's effort — including during a period the child has no view about. The safer design was a beneficiary that is a role ("the youngest") rather than a person. It was not chosen because a role does not do the thing the feature is for: contact with a specific person is what raises effort, and a household that has to translate "the youngest" back into Ada every time gets neither the effect nor a clean record.
As authors — WS8's case, arriving here. A child can set an intention, answer the question bank, claim a need and send a thanks. All four are good for a child: a plan they made themselves, a reason in their own words, a choice to help rather than an assignment, and an act of gratitude addressed to a person. Three properties protect them, and they are the reason the deterministic half of every surface exists:
- No model touches a child's words. The question bank has no inference in it, the fallback brief is deterministic, and the check-in card for a child account is deterministic. Under the privacy ladder no under-16 account talks to a model at all; WS22's job was to make sure that costs the child nothing, and it does not — they get the same questions and the same plan.
- Nothing a child does is scored. No points, no streak, no comparison with a sibling. A child learning that care is what you do for people you love is the entire design goal; a child learning that care is what earns points is the failure mode the crowding-out finding predicts.
- The record page is the child's own. Own acts, own beneficiaries, no ranking. A guardian can see it, because a guardian can see the group's tasks; what a guardian cannot get anywhere is a number to compare one child with another.
Where the child's interest and the parent's diverge. A parent would find a "who is pulling their weight" view useful, and several of the components here are two lines from producing one. The child's interest won: per-person counts do not exist, and The Deal's balance view — which compares load between adults, from the last deal, never all time — stays the only comparison surface in the app.
What the child is told (the s 33 posture). On the intentions screen, in plain words: your plan is yours, the others in your group cannot see it unless you share it, and thanks is a message you send. On the record page: this is what you did, and only you and the grown-ups in your group can see it. WS8 owns the wording of the child-facing variant; this document owns the requirement.
8. Residual risk accepted by the owner
- A sentence can shame without using a banned word. The vocabulary test is a floor, not a proof. Accepted, with the prompt's own rules and the deterministic fallback as the mitigation.
- Intention text, the
why, and the free-text goals are plaintext at rest until WS14. Accepted and disclosed; no copy anywhere may imply otherwise. - A
whycan carry health information about a child, and nothing filters it. Accepted — it is the information the parent needs — with the field's copy asking what will be better rather than what is wrong. - A beneficiary name reaches the model in the reader's own brief, in whatever region the
assistant runs in until WS20. Accepted, gated by the existing
assistantconsent, and to be stated in the transparency copy rather than left to be discovered. - A silence can be read as a decline. Accepted; the alternative is recording declines, which is worse.
- The no-counting property is mostly test-pinned rather than structural. There is no column to hold a thanks count today, which is the strongest available form, but nothing in the database stops a future migration adding one. Accepted, with the extended features-step scan as the loud failure.
- The child-facing routing does not exist yet. WS22 builds the deterministic destinations; WS8 and WS19 do the routing. Until both land, a child using an adult's account on a shared phone gets the adult experience — which is the app's standing position on shared devices, not a new risk.
9. Review trigger
- Anything in WS22 gains a count, a total, a rate, a streak or a ranking — the crowding-out and features-step arguments both turn on their absence.
- A model is given the ability to write state — a beneficiary, a
why, an intention, an assignment. §4's first absolute rule. - Another member's intentions become readable by anyone but their author, for any reason.
- WS8 ships child accounts: re-read §7 against what was actually built, and check the deterministic routing.
- WS19 ships the group privacy levels: check that Device-only routes the brief and the check-in to the deterministic paths.
- WS14 seals intention text: §3 and §8's second bullet stop being true, and the copy may change.
- A thanks becomes anything other than a chat message.
10. Checklist against exposure draft s 38(2) (verified 2026-09-08)
| s 38(2) | Requires | Answered in |
|---|---|---|
| (a) | nature, scope, context, flow and purposes | §§1–4 |
| (b) | why collection is strictly necessary | §2, per item — the honest answer is that it is optional and inert until used |
| (c) | lawful and fair means | §4 — the existing consents, no new bundled ask, no dark pattern; every question skippable with no record |
| (d) | consistent with the best interests of the child, with reasoning | §7 |
| (e) | how the entity complies with the Code and the Act | §4 and the structural/conventional column throughout §5 |
| (f) | risk of harm — physical, emotional, developmental, material | §5, first two rows especially: crowding out is a developmental harm and guilt is an emotional one |
s 38(3): conducted before the feature is made available — this document is committed before any
WS22 code. s 39: listed on the published register (docs/pia/README.md; publication itself is
outstanding until WS17's site exists).
11. Sources
Primary: Children's Online Privacy Code exposure draft ss 10, 13, 14–17, 33, 38, 39 — via
docs/privacy_posture.md §4.2; not independently re-read for this document, which is recorded
here rather than left to be assumed. Online Safety (Age-Restricted Social Media Platforms) Rules
2025 s 4A — quoted and verified in
2026-09-ban-self-assessment.md §14.
The psychology this feature is built on is summarised in the WS22 specification (implementation intentions; the fresh-start effect; beneficiary contact; gratitude expressed from one person to another; autonomy over assignment; and the crowding-out finding). The individual studies were not retrieved or verified for this document. They are cited here as the design's stated rationale, not as established fact, and no user-facing copy anywhere in WS22 makes a claim about them.
In repo: AGENTS.md → The Deal Counts. It Does Not Characterise, And It Never Ranks (the
no-comparison rules this feature inherits and the copy-scan pattern it reuses), The App Shows
Nobody How Others Engaged With What They Posted (§6), The Home Brief Is Promoted and The Home
Horizon Is The Model's INPUT (§4), A Marker Is Only A Marker When Its Payload Has A SHAPE (why
why goes in notes_meta and never into a new notes marker), Check RLS Is ENABLED Before
Writing Policies, A Loader Must Refuse To Write For A Group That Is No Longer Current,
Switching Group Is A Single Write; lib/settingsScope.ts; lib/consents.ts;
docs/pia/child-accounts.md; docs/pia/2026-09-ban-self-assessment.md §5.3.
Planned, not built at the time of writing: everything in §§1–8 that this document assesses; child accounts (WS8); group privacy levels and Device-only (WS19/WS20); Tier 1 encryption of intention text (WS14); the consent ledger's use for a new purpose — WS22 adds none.