Skip to Content
EngineeringDecisions (ADRs)ADR 0026 The public site: preview posture, first-party inquiries and cookieless analytics

ADR 0026: The public site: preview posture, first-party inquiries and cookieless analytics

Status
Accepted
Date
Deciders
Founder

Context

The live site was honest but read like a design document: no metadata, no path to a person, no company page, duplicate hosts, no security headers, empty “None available today” tiers, and a hero that said nothing is available while a console ran live in the dev environment. Three expert critiques and an honesty check produced the specification in PRODUCT-PLAN.md Part 6.

Decision

  • Posture: “private preview for design partners” once the two measurements of contract 10.12 are registered (status flip in one commit); until then every status word is data from site/lib/content.ts stamped with a date; forbidden phrases and speed words are linted.
  • Lead capture through POST /api/v1/public/inquiries (first-party, rate-limited, honeypot and time gate, e-mail via the verified mail identity, rows retained 24 months); no third-party forms.
  • Analytics through POST /api/v1/public/events from a 1 KB first-party beacon: aggregate counts only, no cookies, no identifiers, no IP persistence, no banner; described on /privacy. This aggregate table is the one deliberate exception to “every mutation writes an audit row”.
  • New pages /contact, /contact/sent, /company (founder-supplied slots), /privacy, /terms (fixed headings, slots, noindex until filled); nav label “Security”; real console screenshots framed and labelled; metadata (Open Graph, social card, canonical, JSON-LD, sitemap, robots, manifest); security headers and the www redirect in the deploy bundle; subset fonts; CSP report-only for one release.

Consequences

  • Routes 155 -> 157; three tables; Settings inquiry_notify_to, public_rate_salt, public_cors_origin.
  • Lighthouse results and live-audit reports are review evidence, never copy.

Alternatives considered

  • Third-party form or chat widget: inquiry data would leave the account and a vendor name would appear; rejected.
  • Cookie analytics with a banner: more data than the site needs; rejected.
  • Publishing company facts as placeholders: invented content; rejected, slots render nothing.

Follow-ups

  • Fill the company, privacy and terms slots with founder-supplied facts, then remove noindex.
  • Move CSP from report-only to enforced after one clean release.
Last updated on