Every app's terms, privacy, refunds and subprocessors pages are rendered from the commercial facts, and the countersigned copy is pinned by hash
rank: decision outranks: []
Section titled “rank: decision outranks: []”Every app’s terms, privacy, refunds and subprocessors pages are rendered from the commercial facts, and the countersigned copy is pinned by hash
Section titled “Every app’s terms, privacy, refunds and subprocessors pages are rendered from the commercial facts, and the countersigned copy is pinned by hash”Date: 2026-10-30 Status: closed Supersedes: none Superseded-by: none — current MR-compliance: MR-4, MR-7, MR-9
Context
Section titled “Context”estate/commercial-facts.yaml landed on main in #605 (gate G-1-2), carrying
the wider fact set that 2026-10-29-commercial-facts-legal-page-fields.md
added for legal pages. traceo is live and taking payment with no terms or
privacy page (traceo.cat/terms returned 404 on 2026-10-29); chronicle has
none either. Both apps are Next 15 with no markdown renderer.
Decision
Section titled “Decision”petrova legal-render (cli/src/legal-pages.ts) renders four pages per app
— terms, privacy, refunds, subprocessors — from the facts file alone, into
estate/legal/<app>/<slug>.md (the text a human reads and signs) and
estate/legal/<app>/pages.json (the same sections as data, for the app to
render without new dependencies). estate/legal/manifest.json records the
effective date, the hash of the facts and the sha256 of every file. A cli test
fails when the committed files differ from a fresh render, so a facts change
without a re-render, or a hand edit to the output, turns spine CI red.
This countersign approves the copy as rendered at manifest sha256
513fc0191cf3167aef93366a74279ae54b310eaac7180a9c0084d9a80584fa61, effective
2026-10-30. An app may publish only a pages.json whose sha256 matches the
manifest entry for that app.
Alternatives considered
Section titled “Alternatives considered”- Hand-written pages in each app — the per-app legal copy that the 2026-10-24 rail decision (F8) set out to end; the facts would drift from the pages the first time either changed.
- Apps fetch the facts at build time and render themselves — petrova-codes is private, so every app build would need a token, and each app would carry its own copy logic; one renderer and committed output keeps one text to sign.
- Markdown only, apps add a markdown renderer — a new dependency in every app for four static pages; the JSON twin is the same content with no parser.
Consequences
Section titled “Consequences”For code:
- New
cli/src/legal-pages.ts,cli/src/verbs/legal_render.ts,petrova legal-render [--effective] [--check], andcli/tests/legal-pages.test.ts(14 tests, including the drift check). - Follow-up PRs in
traceo-cat/traceo-mcp-server(landing app) andchronicle-cat/appadd/terms,/privacy,/refundsand/subprocessorsfrom the vendoredpages.json, with footer links. They are opened only after this doc is countersigned.
For docs:
estate/legal/is generated; edit the facts or the renderer, never the output.
For in-flight phases:
- RS-DL-004 R-09: app legal blockers point at
repo:petrova-codes:G-1-2; this is the copy those blockers were waiting for. - traceo M-23: the processor list was checked against traceo production on 2026-10-30.
traceo:engineandtraceo:mcpcarrysentry-sdkand theopenaiextra, but neitherSENTRY_DSNnorOPENAI_API_KEYis set, so both are inert.ANTHROPIC_API_KEYis set ontraceo:mcp, but no code on main reads it (traceo.petrova/gates.yaml: “inert until the vendor decision (F-23-1)”). Whichever of these is turned on first must be added toprocessorswithapplies_to: [traceo], re-rendered and countersigned before it receives customer data. - Railway’s location (
European Union (Netherlands)) was added to the facts in this PR: both the TRACEO and CHRONICLE Railway projects run ineurope-west4-drams3a.
For invariants:
- None. No MR is added, changed or repealed.
What this decision does NOT do
Section titled “What this decision does NOT do”- It is not legal advice and does not replace a solicitor’s review; it records that the operator approved this copy for publication.
- It does not change any fact. Corrections go through
estate/commercial-facts.yaml, a re-render and a new countersign. - It does not decide on a DPO, an EU representative, or an ICO registration number on the pages.
References
Section titled “References”docs/decisions/2026-10-29-commercial-facts-legal-page-fields.md(the fields this renders)docs/decisions/2026-10-24-toll-is-the-estate-payment-rail.md(single home for legal facts; F8)estate/commercial-facts.yaml,.petrova/gates.yamlG-1-2- devarno-cloud/plays
specs/RS-DL-004.mdR-02, R-09
Sign-off
Section titled “Sign-off”- Subagent: Claude Opus 5.5, 2026-10-30 (renderer, tests and rendered copy in the same PR)
- Human countersign — the rendered terms, privacy, refunds and subprocessors copy for traceo and chronicle at the manifest sha256 above, for publication on traceo.cloud and chronicle.cat — flight@arno.host, 2026-10-30 (jzero.run T1)
Countersigned by human:flight@arno.host on 2026-10-30 — box ticked in commit fc235ace, authored by the human (jzero.run T1): the rendered copy at manifest sha256 513fc019… accepted as drafted. Published by traceo-cat/traceo-mcp-server#411 (landing) and chronicle-cat/app#54, each pinning its pages.json hash from estate/legal/manifest.json.
Status flipped open→closed on 2026-10-30 by an agent as scribe (MR-7).