← All privacy impact assessments
PIA: Ceremonies — the family scrum, facilitated by the assistant
Status: Built — WS23 shipped 2026-09-08 (#344: #347, then #353 for the outcomes wiring). Written before the code, per s 38(3); status raised to built 2026-09-09. Written: 2026-09-08 · Author: Brendan Patch · Issue: #344 Nothing here is legal advice. Children's Code citations are to the exposure draft; section numbers may move on registration (due 10 Dec 2026).
Every mechanism described below is planned unless the sentence says it ships in this PR. Where this document says "the sweep", "the RPC" or "the policy", it means the one landing in the same pull request as this assessment; nothing here describes an existing surface.
1. Purpose and scope
A group runs a small set of bounded rituals — a weekly Huddle, an optional Morning minute, a weekly Wrap, and Show and tell — and the app carries the mental load of the meeting: remembering it exists, holding the agenda, keeping time, taking the turns in order, writing down what was agreed, and carrying that forward to next week. The family keeps the part that is worth keeping, which is the attention paid while somebody speaks.
In one sentence: the app runs the meeting so the family can be in it.
In scope: the ceremony thread (a third kind of conversation, distinct from the group chat and from the private assistant transcript), the facilitator's turns, the structured outcomes, the two modes (in thread / in person), the retention sweep, the home indicator, and what reaches a model from any of it.
Out of scope, assessed elsewhere:
- Intentions, beneficiaries, thanks and claims — WS22,
docs/pia/intentions.md. Ceremonies capture outcomes that post through WS22's own paths; WS23 owns none of those tables. - Child accounts, the guardian invariant and the child-safe variant —
child-accounts.md. This assessment assumes children take part today as profiles answering through a guardian's device, and says what changes when they hold accounts. - Whether the app is an age-restricted social media platform —
2026-09-ban-self-assessment.md. §5 below records what this feature does not build so that assessment's §5 stays true. - The group chat, which a ceremony thread deliberately does not touch.
2. Data involved
| Kind | Whose | Children's? | Sensitive? | Free text? |
|---|---|---|---|---|
ceremony_threads — group, kind, opens_at, closes_at, mode, status, closed_at |
the group's | no (no person named) | no | no |
ceremony_messages.body — what a member wrote in the thread |
the author's, about whoever they mention | yes, both ways — a child may be the author, and is very often the subject | possibly — free text, so a member can type anything into it | yes |
ceremony_messages.payload — the facilitator's prompt card, turn marker, or the tapped outcome |
the group's | indirectly | no | no — closed shapes only |
ceremony_messages.author_user_id / author_kind |
the author's | yes, where the author is a child | no | no |
ceremony_outcomes.text — "we'll try eating earlier on Wednesdays" |
the group's | often about a child | possibly | yes |
ceremony_outcomes.actor_user_id, target_*_id |
a member's | yes | no | no |
group_ceremony_settings — per-kind mode, display name, day/time, enabled, updated_by |
the group's | no | no | the display name is (a group may rename a ceremony) |
What is deliberately NOT collected, and could have been:
- No attendance. Nothing records who was in the room, who opened the thread, or who did not. A skipped week leaves no row, and next week's ceremony cannot mention it.
- No per-person counts of anything — not turns taken, not words written, not outcomes claimed, not ceremonies attended. There is no streak.
- No transcript beyond the window. The messages are deleted seven days after the thread closes (§3, §5). Outcomes persist; the words that produced them do not.
- No audio and no speech. The phone shows its prompts and never reads them aloud (owner decision, 8 Sep). There is no TTS on this surface and no microphone use; the optional short sound that marks a turn or the end of the timer is a bundled tone, off by default.
- No read marks, no reactions, no "seen by". §5, and
2026-09-ban-self-assessment.md§5.3. - No evaluation. Nothing stores or displays a judgement about a member's contribution, and the facilitator is forbidden from writing one (§5, §6).
Strictly necessary (s 38(2)(b)), per item. The free text in ceremony_messages.body is the
ritual itself — a ceremony where nobody may say anything is not a ceremony — and it is the one
item that is collected because the feature is it, not because it is convenient. Everything
else is either a schedule (opens_at / closes_at / mode), an identifier needed to attribute a
turn to the person who took it, or an outcome the group asked to keep. body is also the only
item with a retention window, precisely because it is the only one whose necessity ends when the
meeting does. author_user_id is nullable and empty for facilitator rows, so an unattributable
turn is stored as unattributed rather than as somebody.
3. Flows and locations
| Data | Device | Supabase (Sydney, ap-southeast-2) | GCP (australia-southeast1) | Model provider | Region |
|---|---|---|---|---|---|
| A member's thread post | typed, held in state | stored, RLS-scoped to the group | — | in thread mode only, fenced, one bounded generation per ceremony trigger | model provider's, per the AI Model Strategy table |
| The facilitator's script (agenda, turn order, prompt cards, timer, closing summary) | rendered | stored as ceremony_messages rows written by an RPC |
— | never — it is deterministic text from lib/ceremonies/ |
n/a |
| The facilitator's prose turn | rendered | stored | agent-server composes the request | yes, in thread mode; never in Device-only groups | as above |
| In-person conversation | spoken in the room | nothing | nothing | nothing | n/a |
| Tapped outcomes (in person) | tapped | stored as ceremony_outcomes |
— | may be read by a later ceremony's prose call as last week's outcomes | as above |
| Last week's outcomes | rendered | read | passed to the model as context | yes, fenced | as above |
The two modes have genuinely different disclosure, and that is the reason the setting exists rather than a default being chosen for everyone.
- In thread: people write into the thread over the day it is open. When a member's session triggers the facilitator's prose turn, everyone's free text in that thread is sent to the model, fenced as untrusted data. That is the honest description and it is what the setting's copy says.
- In person: the phone sits on the table. The facilitator posts its deterministic script into the same thread, and whoever holds the phone taps the outcomes in. The conversation itself never touches a server — nobody types it, nothing records it, and there is no microphone involved. The model receives, at most, the app's own script and the tapped outcomes: closed shapes and short text somebody chose to keep.
That asymmetry is why in person is the default for three of the four ceremonies (Huddle, Wrap, Show and tell) and why it is the better default where children take part. Morning minute defaults to thread because it is asynchronous by nature — its whole point is that people are not in the same room — and it is the shortest and least sensitive of the four.
What reaches a model at each step of the privacy ladder (WS16's group privacy level; where that column does not yet exist the predicate is stubbed to "not Device-only" with a comment naming WS16, and the ladder answer below is what it will return):
| Level | Facilitator prose | What is sent |
|---|---|---|
| Device-only | no model call at all — the app's own wording from lib/ceremonies/ |
nothing leaves the device beyond the ordinary row writes |
| Australia | one bounded generation per ceremony per trigger | the current thread + last week's outcomes, fenced |
| Default | same | same |
The deterministic script is the same text in every case, so a Device-only group loses prose polish and loses nothing else: the agenda, the turns, the timer, the prompt cards and every captured outcome are identical. That is the property that lets this feature exist at every rung of the ladder rather than being switched off at the bottom of it.
Logs. The endpoint logs outcomes and counts, never bodies — AGENTS.md → Identifiers In LOGS Are Data An Erasure Cannot Reach. A thread id is a group-scoped identifier and is logged; a member's post is not.
Group boundary. Nothing crosses one. A ceremony thread belongs to exactly one group and its
policies are is_active_group_member(group_id); there is no cross-group surface here and none is
planned.
Erasure. ceremony_messages.author_user_id and ceremony_outcomes.actor_user_id are
on delete set null against public.users, so a departed member's account deletion leaves the
thread coherent and the words unattributed rather than deleting a meeting other people took part
in. This is a deliberate difference from chat_messages.user_id, which cascades because null
there means "the assistant said it" (AGENTS.md → Erasure Has To Be Tried Before It Can Be
Claimed). Here null means "we no longer say who", which is what an erasure should produce. The
messages themselves are gone within seven days of the thread closing in any case.
4. Legal basis and consents
No new consent purpose, and that is a decision rather than an omission. The prose turn is the
assistant writing sentences about the group's own data, which is the purpose assistant in the
ledger's closed list already covers (WS2, lib/consents.ts). Adding a ceremonies purpose would
be a purpose with no separate question anybody could be asked — the disclosure that matters is
mode, and mode is a group setting with its own copy, not a consent.
- Who decides. The per-ceremony mode is a group setting, attributed and announced through
WS18's primitive (
20260907232948), and any active member may change it. It is deliberately not consent-class: switching a ceremony from in person to in thread does not by itself send anything anywhere — nothing is sent until somebody writes free text into a thread and a facilitator turn is triggered — and gating a family ritual's format behind an admin would put an authority question where a scheduling question belongs. What makes it safe to leave open is that it is announced: the change writes asetting_changedsystem row into the group chat naming who made it, so a member cannot find the format changed under them with nothing able to say by whom. That is the same callgroups.timezonealready carries. - What they are told at the moment they change it. The setting's copy states the disclosure difference in the words of §3: in thread the facilitator receives everyone's free text; in person it receives only its own script and the tapped outcomes, and the conversation never touches a server.
- Withdrawal is the same switch, and a per-instance override exists ("we are apart this week, do it in thread") because a ritual that cannot bend to one week away gets abandoned rather than adapted.
- Expiry. The
assistantconsent is subject to the twelve-month currency sweep (sweep_expired_consents) like every other; a group whose assistant consent lapses gets the deterministic script, which is the Device-only behaviour and is a working ceremony.
Where a guardian answers for a child (s 13): today a child takes part as a profile, so the guardian is holding the phone and the post is the guardian's own act — there is no separate consent to record because there is no separate account. What the child is told is §7. When child accounts ship (WS8) the child posts through the same policy as any member and this section is re-run: the guardian's consent to the assistant covers the model call, and the child's own understanding of who reads the thread becomes the s 33 question rather than a hypothetical.
5. Risks and mitigations
| Risk | Who is harmed | Mitigation | Structural or conventional? | Residual |
|---|---|---|---|---|
| The grievance archive. A retro is a record of complaints. Kept, it becomes a searchable history somebody can be shown ("you said the same thing in March"), and a model that can re-read it can compose one. | Any member, most sharply a child or the member with least power in the group | Three things, not one: (a) only outcomes carry forward — the next ceremony is given last week's ceremony_outcomes and never a previous thread's messages; (b) messages are deleted seven days after close by sweep_ceremony_threads, shipping in this PR; (c) the facilitator prompt is given only the current thread and last week's outcomes, and the check asserts it cannot be handed a previous thread. |
(a) prompt-construction + a check — conventional, test-pinned; (b) structural — a pg_cron sweep; (c) conventional, check-pinned | A member can screenshot a thread while it is open. Nothing prevents that and nothing should pretend to. |
| The facilitator names who has not spoken. "Sam hasn't shared yet" is the single most natural sentence for a meeting assistant to write, and it turns a ritual into a summons. | Whoever is quiet — disproportionately a child, or someone having a bad week | The prompt is given only the members who have posted, so the absent are not in its context to name; a banned-vocabulary scan over the deterministic script rejects naming-the-absent grammar; turn order is round-robin over the roster, never ordered by who has done or said least. | The context restriction is structural in the prompt builder (the roster is filtered before the string is built, not instructed away); the vocabulary scan is conventional, test-pinned | A model can still invent a name. It is not given one to invent from, and the deterministic script — which is all a Device-only group ever sees — cannot. |
| The facilitator evaluates somebody. "Ada's tasks were late three times" is a true sentence the app could compose from data it holds. | The person evaluated, and the relationship | The facilitator asks and records and never evaluates; "what could go better" is held as a question and only people answer it; the facilitator never drafts a grievance from task data — completion data is not in its context at all. | Conventional, pinned by the banned-vocabulary scan and by what the prompt builder is allowed to read | A person can still say something unkind in the thread. That is a conversation between people, which is not this app's to police. |
| A child's words are read by a model. In thread mode a child's free text is sent for prose. | The child | In person is the default for the three ceremonies children take part in; the mode setting says plainly what each does; Device-only groups make no model call; a child answering a prompt gets a deterministic card with choices and never a one-to-one exchange with a model (the command-interface-never-companion rule). | Mode default and the no-conversation rule are conventional; the Device-only branch is structural (no call is made) | A group that switches Show and tell to thread mode does send a child's words to a model. It is disclosed, it is their choice, and it is recorded here as the choice they are making. |
| A private assistant writes into the shared thread. The member's own assistant knows their intentions and calendar; it would be trivially "helpful" for it to post on their behalf. | The member, whose private plan becomes group knowledge without a decision | The private assistant may only draft a "post my update" card (the AGENT_DRAFT pattern); the person posts it. Nothing private reaches the thread uninvited. | Conventional today (no client can be stopped from calling the ordinary insert) — the card is the mechanism, the discipline is the rule | A future surface that posts a draft automatically breaks this. Named in §9 as a review trigger. |
| A member forges a facilitator turn and puts words in the app's mouth — announcing an outcome nobody agreed. | The whole group | author_kind = 'facilitator' is refused by the INSERT policy to every client; the only writer is post_facilitator_message, a SECURITY DEFINER RPC callable with a member's session for that group. Same shape as group_messages.system_payload — except that this RPC is granted to authenticated and takes the text as an argument, because agent-server holds no service key and posts with the member's own token. |
Structural as to GROUP (a stranger cannot reach the thread; the db suite asserts the denial message) and conventional as to CONTENT: an active member could call the RPC directly through PostgREST with any sentence. Unlike system_payload, which only a trigger writes, this is not the systemhood rule in full. |
A member of the group can put words in the facilitator's mouth in their own family's thread. Accepted for now (they can already write anything in their own voice, and the audience is their own household); the upgrade path is a facilitator secret minted the way mint-voice-token is, so the RPC refuses a call agent-server did not make. Recorded in §8 and §9. |
| The thread becomes a feed. A shared, model-read conversation is the shape a "seen by 3" or a reaction gets added to. | Every member, and the app's legal position | The ceremony directories join components/Chat/__tests__/noFeedbackFeatures.test.ts's scanned set in this PR; a thread is bounded by construction (opens, fills, closes) and renders a visible "This ceremony is closed" end. 3 of 4 answered is allowed — it is a coordination count like an RSVP — and naming who has not is not. |
The scan is conventional-but-loud; the bounded thread is structural (closes_at and a status the RPC sets) |
A count of four is a small number, and in a group of four "3 of 4" plus knowing three people is an inference. Accepted in §8 with the reason. |
| Retention claimed but not enforced. | Everyone, and the honesty of the privacy copy | The window is stated only because the sweep ships in the same PR (AGENTS.md → Ship The Retention JOB Before The Retention CLAIM). The sweep is idempotent, deletes messages of threads closed more than seven days ago, and leaves outcomes. | Structural — pg_cron, and a db test that runs it twice | pg_cron is inside the same database as the data, so a point-in-time restore restores un-swept rows. The sweep re-applies for ever, which is the same answer sweep_baby_history_deletions gives. |
| A child is the subject of an adult's post. "Ada didn't help with the dishes again." | The child, who may not be in the room | Nothing structural, and it would be dishonest to invent something. The mitigations are the retention window (it is gone in seven days), the absence of evaluation by the app, and the fact that the outcome carried forward is a thing to try, not a complaint. | Conventional, and thin | Carried in §8 as accepted residual risk. |
6. Structural versus conventional
Structural — the database or the absence of a grant proves it:
- A ceremony thread is readable and writable only by active members of its group. RLS on all
three tables,
is_active_group_member(group_id), with a second member of the same group used in the tests (a stranger proves nothing — AGENTS.md). - No client can INSERT a facilitator row, and no stranger can reach the RPC that does. The
INSERT policy requires
author_kind = 'member' and author_user_id = auth.uid();post_facilitator_messageis SECURITY DEFINER,revoke execute ... from public, anonthen granted toauthenticated, and it checks the caller's active membership of the thread's group itself. The db suite asserts the denial message, not the bare42501, becauseauthenticatedholds table grants underneath. What is NOT structural: the content. The RPC takes the sentence as an argument and any active member holds EXECUTE, so a member of the group can call it by hand and post as the facilitator. See §5's forgery row and §8. - Messages of a thread closed more than seven days ago do not exist.
sweep_ceremony_threads, pg_cron, idempotent, outcomes untouched. - A member cannot write into a closed thread. The INSERT policy requires
status = 'open'. - Nothing crosses a group boundary. There is no policy arm that reaches another group, and no
security definerfunction that takes a group id from a client without checking membership. - The
owns_chat_sessionpolicies and thegroup_messagespolicies are untouched. This is a third kind of conversation with its own tables. The private assistant transcript stays private and the group chat stays out of the assistant's reach. - Device-only makes no model call. A branch, not an instruction.
- Spend is bounded.
consume_agent_tokenson the caller's own client (soauth.uid()resolves), zero-delta pre-flight, billed outside thetry,max_tokensalways set, one generation per ceremony per trigger. - The mode setting is attributed and announced.
updated_byis written by a BEFORE trigger and is not in any client UPDATE grant; the announcement trigger writes asetting_changedsystem row that no client can forge.
Conventional — held by copy, a prompt, a source scan, or everyone remembering:
- The facilitator does not evaluate and does not name the absent. A prompt rule and a vocabulary scan. The context restriction (only posters are in the roster handed to the prompt) is stronger than a rule but is still a property of one function.
- Only outcomes carry forward. A property of the prompt builder, asserted by a check.
- Turn order is round-robin. A pure function with a test; nothing in the database enforces it.
- No scrum vocabulary in user-facing copy. A copy scan.
- In person is the default for three of four ceremonies. A default, changeable by any member.
- The private assistant only drafts. Discipline plus the AGENT_DRAFT card pattern.
- The host badge is decorative. Nothing tracks it because nothing stores it — arguably structural by absence, but it would take one column to change that, so it is listed here.
A test that pins a conventional property is not proof and does fail loudly; every one named above is written for that purpose and is named after its reason rather than its mechanism.
7. Best interests of the child
Required: children are participants, subjects and — after WS8 — authors.
What it gives a child. A predictable, bounded moment where they speak and are listened to, in their own family, with the adults' phones face-down rather than in hand. The family-rituals literature reports exactly this as the mechanism behind the effects (cohesion, fewer chore arguments, children who feel heard) — a repeated, time-boxed occasion where everyone gets a turn. Show and tell is child-led by design. The rotating host badge is a real role a small child can hold — they deal the prompt card and say "go" — and it is decorative on purpose: a role that is tracked becomes a performance.
What it costs them. Two things, and neither is nothing. In thread mode a child's words are sent to a model. And a child is talked about in a family meeting — that is what family meetings are, and it is the cost of being in one. Both are bounded rather than removed: the mode default for the ceremonies children are in is in person, so the ordinary case sends nothing; and the words are deleted seven days after the thread closes, so being talked about does not accumulate into a record.
The safer design, and why it was not chosen. The safest ceremony is one with no free text at all — taps only, closed shapes, no model. It was considered and rejected: a retro where nobody may say what could go better is not a retro, and a family that cannot write a sentence to each other will not use it. What was taken from that design instead is the part that carries the harm — the permanence. The words are transient; the outcomes, which are the group's own agreed plans, persist. That is the trade, stated so it can be argued with.
Where the child's and the parent's interests diverge, whose won. The parent's, once, and narrowly: a parent wants the meeting to work, which means being able to say what is not working, including about a child. The child's interest in not having that written down for ever won the retention question outright — the owner's first draft kept threads for the facilitator's benefit and was reversed on 8 Sep, on the reasoning that a record the subject cannot see but the service uses is the shape both the Code and the Privacy Act dislike. The model does not need it, and a retained retro a model can re-read is the grievance archive moved into its hands.
What the child is told. The thread header says the facilitator reads this thread — in those words, on the surface, in both modes, so a child who can read can find out. The in-person setup screen says the conversation stays in the room. Nothing tells a child that the app cannot read what they write, because it can; the copy tests assert the overclaims stay out (no "private", no "only you", no "we cannot read").
8. Residual risk accepted by the owner
- "3 of 4 answered" is a count, in a small group. In a group of four, knowing that three
have answered and knowing three people is knowing the fourth. The rule is that the app never
names who has not, and the count is a coordination fact of the same kind as an RSVP tally —
which
2026-09-ban-self-assessment.md§4 already accepts as not a feedback feature, because it answers a question the group needs answered ("are we ready to close this?") rather than reporting how anybody responded to what somebody posted. Accepted, and the boundary is the naming, not the number. - A child is talked about by adults, and nothing structural prevents it. §5's last row. The mitigations are the seven-day window and the absence of app-generated evaluation. Accepted; there is no design in which family members cannot discuss a child in a family meeting.
- A thread can be screenshotted while it is open. The retention window bounds what the service keeps, not what a person keeps. Accepted, and no copy claims otherwise.
- Most of the facilitator's restraint is conventional. Not naming the absent, not evaluating, only outcomes carrying forward — these are prompt properties with checks behind them, not CHECK constraints. The strongest available guard is that the absent members are not in the context at all, which is a property of one function that a future edit could widen. Accepted, and named in §9 as the review trigger most likely to be tripped by a change nobody thought of as a privacy change.
- In thread mode sends the whole thread, including other people's words, on one member's trigger. A member who posts and leaves has their text sent when somebody else opens the thread later. That is inherent to a shared conversation being summarised at all; it is disclosed in the mode copy rather than mitigated. Accepted.
- WS16's privacy ladder is not built. The Device-only branch is written against a stubbed predicate with a comment naming WS16. Until that column exists, every group is treated as not Device-only, which is the less protective answer — recorded here rather than left to be discovered, and it is the reason WS16 is in §9.
- A member can forge a facilitator line in their own group's thread.
post_facilitator_messageis callable by any active member with any text, because agent-server posts with the member's own token and holds no credential of its own. The audience is the member's own household, who can already read anything that member writes in their own voice. Accepted; the upgrade path is a facilitator secret in themint-voice-tokenshape (a bootstrap-managed secret the RPC verifies), which is an owner-applied infrastructure change and is not in this PR. - This is the app's own reasoning, not advice (#330). Accepted; the register exists so a review starts from a draft.
9. Review trigger
Re-read this document when any of these becomes true:
- The facilitator's context grows. Anything added to what the prose call is given — task completion data, a previous thread, the full roster rather than the posters, another group's outcomes. This is the one most likely to arrive as a helpful-looking improvement.
- The retention window changes, or the sweep is disabled. The window is stated in user-facing copy; the claim and the job move together or not at all.
- A ceremony surface displays anything about how members engaged — a count of who read it, a
reaction, a streak, an attendance record, "you have not answered in three weeks". §5's
features-step row, and
2026-09-ban-self-assessment.md§10 item 0. - Ordering by anything other than time or the round-robin. Turn order by who has spoken least is the specific temptation, and it is a characterisation of members.
- Child accounts ship (WS8). Children become authors in their own right and §4's guardian reasoning is replaced rather than extended.
- WS16's privacy ladder lands, so the stubbed Device-only predicate becomes real.
- The private assistant gains the ability to post into a thread rather than to draft a card.
- A facilitator proposes who might claim an unclaimed item. That is a fourth automated decision and goes on the disclosure page beside the other three, in the same PR.
- WS15 lands and the thread is envelope-sealed at Tier 2, or somebody proposes device-sealing it — which would make the facilitator unable to read a thread it is designed to read, so the answer is Tier 2 and the reason belongs here.
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 of the handling | §§1–3 |
| (b) | why collection of children's personal information is strictly necessary | §2, final paragraph — per item |
| (c) | collection by lawful and fair means | §4 — a group setting, attributed and announced, with the disclosure difference stated at the point of choice |
| (d) | consistency with the best interests of the child, with reasoning | §7 |
| (e) | how the entity complies with the Code and the Act | §4 and §6 |
| (f) | risk of harm to, and impact on, children | §5 and §7 |
s 38(3): this assessment is written and committed before the code, in its own commit. s 39:
the register is published on the public site (WS17); until that exists, docs/pia/README.md
records the obligation as outstanding.
11. Sources
Primary — law and regulator. As cited in 2026-09-ban-self-assessment.md §14, which holds
the verified copies: the Online Safety Act 2021 s 63C, the Online Safety (Age-Restricted Social
Media Platforms) Rules 2025 s 4A, and eSafety's self-assessment guidance (saved under
docs/sources/). The Children's Online Privacy Code exposure draft ss 10, 13, 14(3)(b),
15–17, 33, 38, 39 — section numbers may move on registration.
Design and evidence. Bruce Feiler's agile-family work is the origin of the four-ritual shape and of the wrap's three questions; the family-rituals literature is the basis for the claim in §7 about cohesion and children feeling heard. Neither is cited here as a legal proposition and neither has been re-verified against a primary text for this document — they inform the design, not the compliance argument.
In-repo.
AGENTS.md→ Check RLS Is ENABLED Before Writing Policies (the assistant transcript stays private; a card can be a household object; this thread is a third kind), A Household Setting Has A Named Author (systemhood is the column), The App Shows Nobody How Others Engaged, The History Has To Visibly END, The Deal Counts. It Does Not Characterise, Untrusted Text Gets A Fence, Spending Money Needs A Ceiling, Ship The Retention JOB Before The Retention CLAIM.docs/pia/2026-09-ban-self-assessment.md§§4, 5.1–5.3, 10, 12.supabase/migrations/20260907232948_ws18_settings_attribution_and_announcements.sql— the attributed-and-announced settings primitive this feature's mode setting uses.- The migration, the RLS suite
__tests__/ceremonies_rls.test.ts, the script modulelib/ceremonies/, the prompt checkagent-server/checks/ceremonies.check.ts, and the copy scans — each named in §6 beside the property it pins.