This repository was archived by the owner on Jul 27, 2026. It is now read-only.
Add Privacy Policy and Terms of Service scaffolds - #1
Open
grantfowler wants to merge 1 commit into
Open
Conversation
App Store Connect and the Play Data Safety form both require a reachable policy URL before a build can be submitted, and Stripe expects terms at checkout. Neither existed anywhere. These live here rather than in the app because the URL is a compliance artifact third parties open on their own schedule -- it must not depend on a Vercel deploy being healthy, and legal text changes on a different cadence than the product. The routes, layout, links, and publish machinery are complete; the section BODIES ARE DELIBERATELY EMPTY. Each section carries a note describing what it must cover, derived from the data flows that actually exist in the product (label photos to Anthropic for OCR, numbers to Twilio, billing to Stripe, the 60-day pre-checkout trial, the consent obligation that sits with the store). Counsel writes the prose. Publishing is all-or-nothing and enforced at build time: a document with any unwritten section, or without an effective date, throws rather than shipping counsel notes as operative policy text. src/legal-docs.mjs is the single source of truth for publish state, so the sitemap exclusion derives from the same flag instead of a second hand-maintained list that could drift. Until published, both pages render a draft banner, emit noindex, and stay out of the sitemap. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FxVqvypw6Y1GmeVKr44XgR
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
App Store Connect and the Play Data Safety form both require a reachable policy URL before a build can be submitted, and Stripe expects terms at checkout. Neither document existed anywhere. This is one of four launch blockers being cleared; the other three are in
samplify-app#launch-blockers.They live here rather than in the app because the URL is a compliance artifact third parties open on their schedule — it must not depend on a Vercel deploy being healthy, and legal text changes on a different cadence than the product.
What this is — and is not
The routes, layout, links, and publish machinery are complete. The section bodies are deliberately empty. Each section carries a note describing what it must cover, derived from the data flows that actually exist in the product — label photos going to Anthropic for OCR, numbers to Twilio, billing to Stripe, the 60-day pre-checkout trial, the consent obligation that sits with the store. Counsel writes the prose.
Privacy has 11 sections, Terms has 14.
Publishing is all-or-nothing, enforced at build time
The first version of this had a real hole, caught in review:
publishedgated only the draft banner andnoindex, while the body/note fallback keyed offbodyindependently. Writing 9 of 11 sections and flipping the flag shipped an indexable, banner-free "Privacy Policy" whose remaining sections rendered their internal counsel notes as operative policy text.Now the build throws if a document is published with any unwritten section, or without an effective date. Verified three ways:
noindex, no banner, no note leakagesrc/legal-docs.mjsis the single source of truth for publish state, imported by both the pages andastro.config.mjs, so the sitemap exclusion derives from the same flag rather than a second hand-maintained list. Previously those drifted silently in both directions — a live policy missing from the sitemap, or a noindexed draft advertised in it.To publish
src/pages/privacy.astro/terms.astropublished: trueand aneffectivedate insrc/legal-docs.mjsThat's it — the sitemap follows automatically, and a half-finished attempt fails the deploy.
Merging publishes the drafts
This repo auto-deploys to GitHub Pages on push to
main, so merging makes/privacyand/termspublicly reachable immediately — asnoindexpages carrying a visible "Draft — not a published policy" banner, excluded from the sitemap. That is the designed behavior and it is safe, but it is a real decision: you may prefer to hold this merge until counsel supplies the copy.Also fixed from review
.prose-legalgaveh3weight but not size — Tailwind preflight makes headings inherit, so subheads in injected policy HTML would have rendered flat> * + *is direct-children-only, so paragraphs inside a list item collapsed togetherrole="alert"on load-time static content →role="note"witharia-labelledbyVerification
npm run buildclean. Checked in generated output: both pages emitnoindex, sitemap contains only/, canonicals correct, every ToC anchor matches a section id, footer links resolve.🤖 Generated with Claude Code
https://claude.ai/code/session_01FxVqvypw6Y1GmeVKr44XgR