Parent account · child profiles · server-side entitlement gate. Access is decided only on the server (RLS + has_entitlement()) — never in the browser.
Fed by completion_events — the engine's chapter-complete records (chapters finished, accuracy stars, vocabulary mastered). A parent can only ever read events for their own children (RLS).
Locked games call has_entitlement() on the server; chapter HTML is served by the gated get-chapter function. Unlocks are written only server-side — never the browser.
A confirmation link is sent to the new address; the change applies once confirmed.