Consent-safe shared-site analytics
Honesty artifact
Assumptions: GA4 property G-L6CXTTSPV2 remains the intended measurement
property, the normal shared layouts plus the three named standalone funnels are
the active measurement scope, and GitHub Pages deploys the rendered includes.
Known gap: production deployment and real GA4 receipt remain unproved until the
merged Pages SHA is observed. No analytics improvement or commercial impact is
claimed before that evidence.
Pre-merge verification on 27 August 2026 used an isolated Ruby 3.2 / GitHub
Pages 232 toolchain on the local non-Tailscale volume. The real Jekyll build
passed. Rendered /, /player-diagnostic/, /session-plan/,
/which-product/, and /privacy-policy/ each contained exactly one analytics
loader, with the default-denied consent command before it. Focused unit tests
passed and the executable browser suite passed 3/3, including no Google request
before consent, idempotent accept/config/page-view, unsafe legacy-event
suppression, withdrawal cookie expiry, and an unmodified outbound navigation.
The static 360TFT site declared GA4 but had no deployed consent mechanism or
loader, so existing gtag callers were inert. The shared contract now defaults
all analytics and advertising consent to denied, loads GA4 only after an
affirmative choice, and provides a persistent Cookie Settings control for
withdrawal. Rejecting analytics leaves the site fully usable.
Outbound events contain only the current pathname and a bounded destination
category. Query strings, link text, form content, email addresses and user IDs
are never included. The gateway drops all legacy events except bounded
cta_click and begin_checkout schemas, and initialises GA4 once, preventing
duplicate page views.
Production completion requires independent review, merge, observed Pages SHA, and browser proof that reject sends no Google requests, accept sends one page view plus a bounded outbound event, and withdrawal stops subsequent events.
The first production check at SHA e48e59a found that the Google library loaded
but did not collect: sanitized commands had been queued as ordinary arrays, not
the arguments-shaped commands used by the gtag protocol. That deployment is
not credited. The follow-up uses an arguments-preserving queue adapter and must
show a real Google collection request after consent before this PRD can close.
Production proof
Completed 27 August 2026 at Pages/main SHA
0e3b5c479eba09db28739a524858e150cc630024 after independent review passed
the follow-up commit. The normal Action was a billing non-start, so the direct
GitHub Pages build API was used; Pages reported the exact SHA as built.
Live checks found exactly one loader, ordered after default-denied consent, on
/, /player-diagnostic/, /session-plan/, /which-product/, and
/privacy-policy/. A clean production browser produced zero Google requests
before consent and after rejection. Acceptance produced the Google loader GET
and a region1.google-analytics.com/g/collect POST. A bounded outbound click
queued only route, destination category, and beacon transport and produced a
second collection POST; withdrawal suppressed the next click. This proves the
production collection path, not downstream GA reporting, customer conversion,
or revenue impact.