WhoAmI is the visible counterpart to a quietly opinionated architecture. Every byte of data on the page comes from one of two pipelines, gated by an explicit consent state stored in Zustand with localStorage persistence.
**Server tier — always rendered.** When a request hits /lab/whoami, the React Server Component reads x-forwarded-for and User-Agent from the headers, then runs two parallel jobs: getIpIntel(ip) and parseUserAgent(ua). The IP intel call goes to ipwho.is first (10-second timeout) and falls back to ipapi.co if the primary returns 4xx, success:false, or throws — both providers are whitelisted in the CSP connect-src directive. Private IPv4 ranges (10.0.0.0/8, 127.0.0.0/8, 192.168.0.0/16, 172.16.0.0/12) and IPv6 link-local addresses short-circuit before any network call to avoid wasting upstream quota. The IP shown on the IP & Network card is masked (last octet stripped); the unmasked IP is hashed with SHA-256 + a daily salt before any log line writes it.
**Basic client tier — first consent.** When the user clicks "Enable browser inspection", the consent store flips fingerprintBasic from "pending" to "granted", which mounts a FingerprintProvider context. The provider runs collectBasic() inside useEffect — that function reads navigator.platform, languages, hardwareConcurrency, deviceMemory, the connection effective-type API, and screen dimensions. It also tries to grab the WebGL renderer string by creating a throwaway canvas and querying the WEBGL_debug_renderer_info extension. None of this fires before consent.
**Deep client tier — second consent.** A separate "Reveal deep fingerprint" button opens a modal that exists for one purpose: to make the user opt in twice. After confirming, fingerprintDeep flips to "granted" and a dynamically-imported DeepFingerprintProvider mounts. It runs three probes in parallel: a canvas hash (drawing identical text + a coloured rectangle, then hashing the dataURL with subtle.crypto.digest), an audio hash (creating an OfflineAudioContext, sampling 500 frames of a triangle wave through a dynamics compressor, hashing the result), and a battery query (navigator.getBattery, often unavailable on modern browsers). Each is wrapped in try/catch and reports null on failure rather than throwing — Brave and Tor block these on purpose.
**WebRTC leak detection.** The WebRtcLeakCard creates an RTCPeerConnection pointed at Google's public STUN server (stun:stun.l.google.com:19302), opens a data channel, then watches onicecandidate events. The first non-private candidate IP that comes back is the user's real public IP — even when they're behind a VPN, unless that VPN explicitly blocks WebRTC traffic. The probe is itself the leak; that's the point. The discovered IP stays in the browser and is never reported back to our origin.
**What the snapshot saves.** When the page renders, we build a Snapshot object with capturedAt, masked IP, country code, ISP, browser string, and OS string. The VisitComparison card writes this to localStorage on mount and diffs against the previous snapshot. The Share Profile card lets you Copy JSON or Download .json — both are pure clipboard / Blob operations with no network call. The schema for the snapshot deliberately stores country code (not city) so persisted records stay coarse-grained.
**Why two consent tiers instead of one.** The basic tier collects fingerprintable signals but doesn't run anything that could identify you uniquely across cookie clears. The deep tier (canvas + audio) produces hashes stable enough to cross sessions even in incognito mode — that's qualitatively different, and warrants the second prompt. The educational moment in the modal ("notice we asked you twice — most fingerprinting libraries don't ask at all") is the actual feature.
**Where the code lives.** The full module is at apps/web/src/components/tools/whoami/ (17 components) plus apps/web/src/lib/whoami/ (5 helpers: ipwho client, UA parser, fingerprint collectors, comparison, performance metrics). The two implementation plans are docs/superpowers/plans/2026-04-19-plan-04-whoami.md (V1) and 2026-04-20-plan-05-whoami-v2.md (V2). The V2 spec lives at docs/superpowers/specs/2026-04-20-whoami-v2-design.md.