maniator / maniator/verticopolis
[Feature]: [P3] Stand up a public /privacy page, readable before installing anything
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
- A
/privacyroute following the established pattern: asrc/privacy.htmlentry in the ViterollupOptions.input, avercel.jsonrewrite to/privacy.html, and a permanent redirect from/privacy/. - It renders
helpPrivacyBody()and forks nothing. A containment test asserts the page's normalized text contains the shared body's rendered text, mirroringsrc/helpPage.test.ts. /help#privacystill resolves to the same body, its existing containment test unchanged.- Page-unique
<title>, description, and<link rel="canonical" href="https://verticopolis.com/privacy">; added to thesharedHead()page set and tosrc/public/sitemap.xml. - An effective date and the app version are displayed. The date comes from a
PRIVACY_UPDATEDconstant exported fromhelpContent.tsbesidehelpPrivacyBody, so a diff touching the body shows the date sitting next to it. A test asserts the rendered date is a valid ISO date. - 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. - Excluded from the service worker precache and the navigation fallback exactly as
/helpand/galleryare, 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. - Names a contact route the shell's existing external-link policy already permits: the GitHub issue tracker, alongside
SECURITY.md. No email address invented. - No version history page and no policy changelog. Git is the history and the repository is public.
- The desktop first-run notice still links to nothing and its no-web-anchor test stays green. Linking it to
/privacyis a SHELL-stage criterion:shell.openExternalmust widen to allowhttps://verticopolis.com/privacy, which is a different policy fromconnect-srcand from theonBeforeRequestallowlist and lives in the other repository. Recorded there now so it is not discovered on submission day. - 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/privacyand 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
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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