D56 — full-platform telemetry: GA4 + Hotjar on every surface, content masked (3.26.0) - #705
Merged
Merged
Conversation
…otjar on every surface, content masked (3.26.0)
Operator: "ultimate privacy isnt what web10 is about ... we should just put
on max tracking like hotjar the shit out of the whole platform, we can blur
photos and text ... it is the wrong platform for you if you arent ok with
that" — "hotjar and google analytics" — "we do alot of telemetry to
compete with meta tik tok, to have the most competitive user experience."
Every user-facing surface is tracked (GA4 + Hotjar on marketing-ui,
web10-social, and the authenticator ui/). Supersedes the old
"platform surfaces stay recording-free" rule. The recording is
content-blind by construction: Hotjar initialises with maskAllText +
blockAllImages (text blurred, images blocked — cursor + layout + timing,
never words or pictures); GA4 events stay content-free by convention.
Max tracking, one exception: advertising_id OFF (we don't feed Google's
ad network — the only sponsors a fan sees are the creator's, D50/D55).
The trade is terms-level, not a consent popup.
- web10-social: masked Hotjar (canonical static.hotjar.com snippet +
hj('init', {hjid, maskAllText, blockAllImages})); GA4 moves to the
max-tracking config (drops anonymize_ip, keeps advertising_id OFF);
hotjarIdentify(username) on login
- marketing-ui: gains GA4; Hotjar moves from the old script.hotjar.com
+ hj('initialize', id, version) to the canonical masked init
(VITE_HOTJAR_VERSION retired)
- ui/: new src/lib/analytics.ts (GA4 + masked Hotjar + trackPageview),
installed in main.tsx with one pageview per load (query-parameter-
driven, no router)
- deploy: VITE_GA4_MEASUREMENT_ID + VITE_HOTJAR_SITE_ID baked at build
time (Dockerfile ARG/ENV x3, compose passes GA4_MEASUREMENT_ID /
HOTJAR_SITE_ID per env, empty = off; env examples updated)
- KB: new knowledge-base/web10-v3/telemetry.md (the why, the use case,
the technical how, the line it does not cross, logistics) + README
links; D56 in decisions.md; plan.md + platform-telemetry lane
- tests: new/extended unit suites per app (no-op without env, script
load, masking config pinned, idempotency, identify); marketing-ui's
existing beacon tests restored + merged
… — the docs stop reading anti-analytics (3.26.1) Operator: "can you updated the decisions the knowledge base, everything? because it as very anti analytics, but now that we arent doing the encryption privacy angle, we are trying to be influencer friendly, give them a better deal than these garbo social platforms, it changes the game!" The reframe: web10 is a data-policy platform that tracks hard. The incumbents' UX is the output of a decade of aggressive telemetry, and web10 now runs the same engine (GA4 + masked Hotjar, D56) with a data policy they can't offer — content never tracked, never sold, never fed to the ad machine; the only ads are the creator's (D50/D55). - thesis.md: new "and it tracks hard (D56)" section — the data-policy frame is not a no-telemetry frame; the line (content is never tracked; advertising features off; the trade stated in the terms, not a consent popup) - manifesto.md: "nobody is mining you" narrowed to what it was always about — the creator's content and the fan's words/pictures are never scanned, sold, or fed to an ad machine — plus the candid parenthetical (we watch how people use the place, that's how it stays this good) - AGENTS.md: Telemetry (D56) paragraph in "What web10 is" — the operating rule: do not tighten or privacy-wash tracking without re-reading D56 - README.md: premise table gains the "Built like the best, owned like yours" row - design.md: self-hosted-fonts rule drops the stale "privacy-first product" justification (fonts are a core rendering dependency — reliability + control; telemetry scripts are a different category); FontAwesome retirement drops the "privacy leak" framing - plan.md + platform-telemetry lane ticked (3.26.1)
…acking-not-privacy
…g-ui) + fix(ui) + docs(kb): telemetry IDs runtime-configurable from the Node Config UI (3.27.0)
Operator: "you need to make it addable from the auth ui right? to change
those ids!"
3.26.0 baked the GA4/Hotjar IDs at build time (Vite env -> Dockerfile
ARG), so changing them required a redeploy. Now the IDs live in
node_config (ClickHouse, same table as every other node setting) and are
resolved at runtime.
- API: NodeConfig + ConfigUpdate gain ga4_measurement_id +
hotjar_site_id; effective_config() defaults them to ""; new public
GET /telemetry endpoint (no token — the IDs are public identifiers, not
secrets; CORS is wildcard so every surface reads it pre-login)
- Auth UI: a Telemetry card in the Node Config panel (GA4 + Hotjar
inputs, blank = off, applies live on next page load)
- All three surfaces: resolveTelemetryIds() (GET /telemetry; node
authoritative, build-time env is the dev fallback) + loadGa4/loadHotjar
(idempotent) + installTelemetry(); the authenticator fires its one
pageview after GA4 is ready
- Fix (exposed by the feature): the Node Config save was broken —
saveConfig + saveAdmins sent a flat body but POST /config/update takes
two body models (token: Token + update: ConfigUpdate) and expects
{token:{token}, update:{...}}, so every save 422'd. A configUpdate
helper builds the correct nested shape; pinned by new UI tests
Tests: 5 new API tests + new/extended unit suites per app + new
configTelemetry.test.tsx. 801 API + 205 social + 235 marketing-ui + 122 ui
green, tsc clean, builds clean. KB: telemetry.md updated + D56 addendum.
…acking-not-privacy
…v collision dev assigned its own 3.26.0 (social feed e2e) + 3.26.1 (ad dissemination) in parallel. Per the union-merge renumber procedure, the already-merged (dev) entries keep their numbers; mine move to the next free numbers strictly above dev's max (3.26.1). My 3.27.0 (runtime config) is unchanged. Updated the [✓ x.y.z] refs in plan.md + the platform-telemetry lane to match. dev's 3.26.0 feed ref (parallel-execution.md:223) untouched.
…acking-not-privacy
…27.3 dev landed 3.26.2 (Trending) + 3.26.1 (ads) in parallel, colliding with my renumbered 3.26.2/3.26.3. Per the union-merge renumber procedure, dev's entries keep their numbers; mine move to the next free numbers strictly above dev's max (3.26.2): telemetry build 3.26.2->3.27.1, positioning 3.26.3->3.27.2, runtime config 3.27.0->3.27.3. Updated the [✓ x.y.z] refs in plan.md + the platform-telemetry lane. dev's 3.26.2 Trending ref (parallel-execution.md:228) untouched.
…acking-not-privacy
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
What
D56: web10 tracks hard. GA4 + Hotjar on every user-facing surface (marketing-ui, web10-social, the authenticator ui/). Supersedes the old "platform surfaces stay recording-free" rule.
The recording is content-blind by construction: Hotjar initialises with
maskAllText: true+blockAllImages: true(text blurred, images blocked — the operator sees cursor + layout + timing, never words or pictures); GA4 events stay content-free by convention (paths, actions, counts — never post text, media URLs, or PII). Max tracking, one exception: GA4advertising_id: 'OFF'— we do not feed Google's ad network (the only sponsors a fan sees are the creator's, D50/D55). The trade is terms-level, not a consent popup: "it is the wrong platform for you if you arent ok with that."Why
We compete with Meta and TikTok for the same attention, and their UX is the output of a decade of aggressive telemetry. A node that can't see its own usage is a blog from 2003. The telemetry exists to build the most competitive user experience — for the fan, and for the influencer whose audience it holds.
Changes
static.hotjar.com/c/hotjar-<id>.js?sv=6snippet +hj('init', {hjid, maskAllText, blockAllImages})); GA4 moves to the max-tracking config (dropsanonymize_ip, keepsadvertising_id: 'OFF');hotjarIdentify(username)on loginscript.hotjar.com+hj('initialize', id, version)to the canonical masked init (VITE_HOTJAR_VERSIONretired)src/lib/analytics.ts(GA4 + masked Hotjar +trackPageview), installed inmain.tsxwith one pageview per load (query-parameter-driven, no router)VITE_GA4_MEASUREMENT_ID+VITE_HOTJAR_SITE_IDbaked at build time (Dockerfile ARG/ENV x3, compose passesGA4_MEASUREMENT_ID/HOTJAR_SITE_IDper env, empty = off; env examples updated)knowledge-base/web10-v3/telemetry.md(the why, the use case, the technical how, the line it does not cross, logistics) + README links; D56 indecisions.md; plan.md +platform-telemetrylaneVerification
No visual change — tracking is invisible by design (no screenshots applicable).