diff --git a/PLAN.md b/PLAN.md index 17800c5..5ee7e25 100644 --- a/PLAN.md +++ b/PLAN.md @@ -264,6 +264,7 @@ somewhere other than the thing it decided. The count of record is **eighty-four* | D80–D81 | §16, "How phase 18 built it" | A name in a screenshot is a role; the Rust captures' players are mock data | | D82–D83 | §15, "How the site reaches it" | `/beta` lists the demo's sign-ins as the demo publishes them; a demo deep link names its game and shows only for the games the mounted `demoGames` lists | | D84 | §9, "How phase 6 built the legal pages" | The Data Safety answers say "collected, not shared" for everything the app sends, amending D33 | +| D85–D86 | §9, "`/delete-account/`" | The deletion page is linked from the footer, `/privacy` and `/app/`; someone who cannot sign in is sent to their community's operator, never to us | --- @@ -1086,6 +1087,34 @@ form's security questions. D33's test now asserts the part of the premise that i **nothing is shared**. `/privacy` section 2 keeps saying none of it reaches us, and `lastUpdated` moved with it. Report, block and hide (Android M8 step 3) adds its rows when it lands. +### `/delete-account/` (2026-10-30) + +Play needs one account-deletion address from whoever publishes the app. The platform gained +self-service deletion on the website and in the app (`docs/website/ACCOUNT_DELETION.md`, AD1), and +this page is the address Play is given (AD2, §4.5 there). It cannot delete anything: we hold no +account, so it explains where the button is in the app and on the website, what goes and what stays +and for how long, and who to ask when you cannot sign in. + +**The facts are one row.** What a deletion takes is the `deploy-account-deletion` row in +`src/data/collection.mjs`, whose `deletion` field holds the website's own words for what goes and +what stays (`client/src/lib/accountDeletion.js`, which the app's strings repeat) plus how long each +kept thing is kept, which Play asks and the screens do not say. `/privacy` section 3 renders the row +as prose, the page renders its lists, and `PLAY_DATA_SAFETY.md` prints them under the console's +deletion questions, so the three cannot disagree. `deletionRow()` throws when the row is missing, +and `test/legal.test.mjs` fails a kept entry with no retention. The app rows that deletion touches +(the session, the trust token, push and the inbox snapshot) say so, and `lastUpdated` moved. + +**D85 — The page is linked from the footer, `/privacy` and `/app/`** (org lead, 2026-10-30). The +footer's legal bar reads Privacy · Terms · Delete account, because a player looking for it looks +where the privacy link is; `/privacy` sections 2 and 3 and the bottom of `/app/`'s "Two ways to get +it" link to it as well. + +**D86 — Someone who cannot sign in is sent to their community's operator, never to us** (org lead, +2026-10-30). The page offers "Forgot your password?" first, which works when the account has an +email address and the site can send mail, and then the operator, who can delete any account from the +admin panel. It says plainly that we cannot do it: we hold no account and have no access to any +community's site. Offering our contact address to help find an operator was considered and declined. + **What phase 6 also closed.** `/privacy/` and `/terms/` were the last two entries in `checkLinks.mjs`'s `PLANNED_ROUTES`; building them emptied the list, and its reverse check is what forced the deletion. The list itself stays, because §10's documentation routes land in phases 7 and 8 @@ -1111,6 +1140,7 @@ Organised by what a reader is trying to do. A reader should never need to know t | `/beta/` | The closed-beta signup (§8). The one page that handles its own POST (D28) | | `/community/` | Discord (`discord.gg/t2Jav8yT4g`) as the front door, the Gitea org for code and contributions, the `brand.json` contact address for vulnerabilities (D13) — the split in §14 N3 | | `/privacy/`, `/terms/` | §9 | +| `/delete-account/` | §9: how to delete an account you use in the app, and what it keeps. The address Play is given (D85, D86) | **Feature grouping**, using project terminology: diff --git a/PLAY_DATA_SAFETY.md b/PLAY_DATA_SAFETY.md index dc8cd4a..6b0abfc 100644 --- a/PLAY_DATA_SAFETY.md +++ b/PLAY_DATA_SAFETY.md @@ -1,7 +1,7 @@ +

+ Done with it? How to delete the account you use in the + app, and what deleting it keeps. +

@@ -335,6 +341,12 @@ const downloadBase = `${releasePage}/download/${release}`; padding-top: 0.4rem; } + .app-delete { + margin: 1.25rem 0 0; + color: var(--muted); + font-size: 0.95rem; + } + .app-get__foot { margin: 1rem 0 0; padding-top: 0.85rem; diff --git a/src/pages/delete-account.astro b/src/pages/delete-account.astro new file mode 100644 index 0000000..b48d6eb --- /dev/null +++ b/src/pages/delete-account.astro @@ -0,0 +1,327 @@ +--- +import Base from '../layouts/Base.astro'; +import PageHeader from '../components/PageHeader.astro'; + +import { deletionRow } from '../data/collection.mjs'; +import { legal } from '../data/legal.mjs'; +import { brand } from '../lib/brand.mjs'; + +/** + * `/delete-account/` — the page Google Play is given for account deletion + * (docs/website/ACCOUNT_DELETION.md §4.5, AD2). + * + * --------------------------------------------------------------------------------------- + * IT EXPLAINS; IT CANNOT PERFORM + * --------------------------------------------------------------------------------------- + * Play needs one deletion address from whoever publishes the app, and that is us. But we + * hold no account: every community runs its own site, and the account lives there. So this + * page says where the button is on the website and in the app, what goes and what stays, + * and who to ask when you cannot sign in, which is that community's operator and never us + * (D86). We have no access to any community's site, so offering to help would promise + * something we cannot do. + * + * What goes and what stays is not written here. It is the `deletion` row in + * `src/data/collection.mjs`, the same row `/privacy` section 3 renders, so the two pages + * cannot disagree about what a deletion takes. + */ +const title = 'Delete your account'; +const description = + `How to delete an account you use in the ${brand.siteName} Android app or on a ` + + `${brand.siteName} community site, what is deleted, and what is kept.`; + +const row = deletionRow(); +const { goes, stays, staff } = row.deletion; + +const surfaces = [ + { + id: 'on-the-website', + eyebrow: 'On the website', + heading: 'Your community’s site', + steps: [ + 'Sign in to the site.', + 'Open “Account”. Staff open “Account” in the admin panel instead.', + 'Scroll to the bottom, to “Delete my account”, and press “Delete my account…”.', + 'Type your username, then your password, and a two-factor code if the account has two-factor sign-in on.', + 'Press “Delete my account”. You are signed out everywhere, and the site says the account has been deleted.', + ], + }, + { + id: 'in-the-app', + eyebrow: 'In the app', + heading: `The ${brand.siteName} app`, + steps: [ + 'Sign in, if you are not already.', + 'Open the menu and choose “My account”.', + 'Scroll to the bottom and tap “Delete my account…”.', + 'Type your username, then your password, and a two-factor code if the account has two-factor sign-in on.', + 'Tap “Delete my account”. The app forgets the account and returns to sign-in, saying it has been deleted.', + ], + }, +]; +--- + + + +

+ For the {brand.siteName} Android app, and for the community sites it connects to. We + are {brand.siteName}, the project that makes both. +

+

+ You can delete your account yourself, on the website or in the app. It is deleted at + once: there is no waiting period and nothing to cancel. +

+
+ + + +
+
+

Your account is with your community, not with us

+

+ The app ships pointed at nothing. On first run it asks for the address of a + {' '}{brand.siteName} site, and that site is run by whoever runs that community. Your + account lives there, under their control. We hold no account for you and have no + copy of one, so the deletion happens on that site, and you are the one who does it. +

+
+
+ +
+

How to delete it

+

+ The same steps on both, and either one deletes the account everywhere: deleting it in + the app also deletes it on the website, and the other way round. +

+ +
+ { + surfaces.map((surface) => ( +
+

{surface.eyebrow}

+

{surface.heading}

+
    + {surface.steps.map((step) => ( +
  1. {step}
  2. + ))} +
+
+ )) + } +
+ + +
+ +
+
+
+

Deleted

+

What goes with the account

+
    + {goes.map((item) =>
  • {item[0].toUpperCase() + item.slice(1)}.
  • )} +
+

{row.retention.detail}

+
+ +
+

Kept

+

What stays, and for how long

+
    + { + stays.map((entry) => ( +
  • + {entry.what} + + How long + {entry.keep} + +
  • + )) + } +
+

{staff}

+
+
+
+ +
+
+

If you cannot sign in

+
    +
  1. + Use “Forgot your password?” on the sign-in page, on the website or in the app. It + works if your account has an email address and the site can send email. +
  2. +
  3. + Otherwise, ask the community that runs the site. Its operator can delete any + account from the admin panel, and the result is the same as deleting it yourself. +
  4. +
+

+ We cannot do it for you. We hold no account, and we have no access to any + community’s site. +

+
+
+ + + diff --git a/src/pages/privacy.astro b/src/pages/privacy.astro index 17e9b35..2d0bc62 100644 --- a/src/pages/privacy.astro +++ b/src/pages/privacy.astro @@ -66,6 +66,8 @@ const sections = [ 'the app happens between your phone and their server, and there is no account with ' + 'us, no service of ours in the middle, and no copy of anything on our side — because ' + 'we do not operate one.', + /* The deletion page Play is given (D85). The app is where most people will look. */ + link: { href: '/delete-account/', text: 'How to delete the account you use in the app' }, rows: collectedIn('app'), }, { @@ -79,6 +81,7 @@ const sections = [ 'and their policy — this page is not it. What follows is an inventory of what the ' + 'software collects, so that an operator can see plainly what they are taking on, ' + 'and a player can see what to ask their operator about.', + link: { href: '/delete-account/', text: 'What deleting an account takes, and what it keeps' }, rows: collectedIn('deployment'), }, ]; @@ -131,6 +134,11 @@ const sections = [

{section.heading}

+ {section.link && ( + + )}