maniator / maniator/verticopolis

[Feature]: [P3] Stand up a public /privacy page, readable before installing anything

Open
#806 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
5
Forks
1
PR merge metrics
No merged PRs in 30d

Description

Ruled by a party convened on the desktop analytics disclosure questions. Scheduled on a trigger rather than built now.

Why the page exists

Not because a storefront demands it. That premise, carried in the #781 ruling, turned out to be unsourced and is corrected there: neither Steam's nor itch's public documentation describes a privacy policy URL field or a data questionnaire.

The real reason is stronger. A player deciding whether to install a binary that posts counts across the internet cannot read the terms of that decision until after installing and launching it, because both the consent question and the disclosure live behind first launch. On itch especially, most downloads never touch the itch app: a player clicks a zip, unzips, and double-clicks. The store page is the only screen that exists before the binary.

What it is

A dedicated /privacy route rendering the same shared helpPrivacyBody(), with /help#privacy kept as a working deep link.

Two alternatives were rejected. /help#privacy alone loses on dating: a policy needs an effective date a reader can trust, and /help's last-updated moves whenever the elevator advice changes, so the date is either noise or actively misleading. It also has the wrong title and canonical for a reviewer following a privacy link, and its service-worker caching story is already delicate. PRIVACY.md on GitHub was tempting (stable URL, git-dated, and github.com is already the one host the shell's external-link policy allows) but loses on the copy fork: no test can hold a markdown file to a lit template, and this area drifted once already, which is exactly why the shared-body-plus-containment design exists.

Acceptance criteria

  1. A /privacy route following the established pattern: a src/privacy.html entry in the Vite rollupOptions.input, a vercel.json rewrite to /privacy.html, and a permanent redirect from /privacy/.
  2. It renders helpPrivacyBody() and forks nothing. A containment test asserts the page's normalized text contains the shared body's rendered text, mirroring src/helpPage.test.ts.
  3. /help#privacy still resolves to the same body, its existing containment test unchanged.
  4. Page-unique <title>, description, and <link rel="canonical" href="https://verticopolis.com/privacy">; added to the sharedHead() page set and to src/public/sitemap.xml.
  5. An effective date and the app version are displayed. The date comes from a PRIVACY_UPDATED constant exported from helpContent.ts beside helpPrivacyBody, so a diff touching the body shows the date sitting next to it. A test asserts the rendered date is a valid ISO date.
  6. Readable with JavaScript disabled. The policy text is present in the served HTML, or a <noscript> block carries it in full, with a test asserting the load-bearing phrases are in the no-JS path. This is the requirement the in-app text has no analog for and the one most likely to be skipped: a policy URL that returns an empty shell to a crawler, a text browser, or a locked-down profile is a defect.
  7. Excluded from the service worker precache and the navigation fallback exactly as /help and /gallery are, with a comment saying why: a stale cached policy answering the canonical URL is this page's worst failure mode. Everything else being wrong is a copy bug; that one silently serves last year's promise.
  8. Names a contact route the shell's existing external-link policy already permits: the GitHub issue tracker, alongside SECURITY.md. No email address invented.
  9. No version history page and no policy changelog. Git is the history and the repository is public.
  10. The desktop first-run notice still links to nothing and its no-web-anchor test stays green. Linking it to /privacy is a SHELL-stage criterion: shell.openExternal must widen to allow https://verticopolis.com/privacy, which is a different policy from connect-src and from the onBeforeRequest allowlist and lives in the other repository. Recorded there now so it is not discovered on submission day.
  11. Before the page is written, whoever holds the store account records the actual data and privacy questions on the real submission form. That record supersedes the party's documentation-only read. If the form does present a privacy policy URL field, it is filled with https://verticopolis.com/privacy and nothing else.

Trigger

The earlier of: a Steam or itch store page being created, or the first desktop artifact leaving the repository, playtest builds included. That is deliberately the same trigger as the helpPrivacyBody copy revert, because they are the same moment.

Back to the owner, not resolvable by a party

Who signs the store data declaration and in whose name the policy is published; whether the text is legally sufficient in any jurisdiction (controller identity, lawful basis, retention, data subject requests, and whether GDPR or CCPA attach at all); whether a real contact email is required rather than the issue tracker; and whether any jurisdiction requires an operator identity or address on a public page, which is a personal decision rather than an engineering one. The party wrote copy that is true. Whether true is sufficient is a question for counsel.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the established /help route pattern, src/helpContent.ts, src/helpPage.test.ts, vercel.json, the Vite rollupOptions.input, and src/public/sitemap.xml. Implement the /privacy entry and shared-body containment, metadata, date, no-JavaScript content, routing, and caching behavior described by the acceptance criteria, then run the related page tests; done means every listed test and route requirement passes without forking the privacy copy.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vite
Domain
documentation, testing, web-dev
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.