Privacy-safe Session Replay
Poolstatis Core ships real rrweb DOM session replay: sanitized full snapshots and
mutations, finite navigation and viewport context, cursor movement, clicks, and scroll. Recording
is a separate opt-in path with versioned consent, exact-host approval, masking, 1–30-day retention,
withdrawal, and a scriptless sandboxed player. The separate opt-in replay entrypoint is published
in @poolstatis/sdk@0.4.0.
Availability: source, packages, and managed production shipped
The implementation is present in Poolstatis Core commit
b76b0fe728cf42f53b8aae627dfc2d2291aacfd9.
Published @poolstatis/sdk@0.4.0 includes a separate ./replay export and exact optional
@rrweb/record@2.1.1 peer dependency.
Registry read-back on 2026-08-16 confirms the exact published version:
npm view @poolstatis/sdk@0.4.0 version
pnpm add @poolstatis/sdk@0.4.0
Managed production also runs that exact Core commit through Cloud commit
827609e600d1fe6e40a7d7cd2d88ba7f08014807. The 2026-08-16 release applied replay migrations
042–044, mounted the dedicated replay volume, created an encrypted continuity backup, and
completed an isolated restore drill before activation.
Source, npm publication, Cloud deployment, and consumer migration remain separate proof gates; each passed for this release. This site pins the published 0.4.0 tarball for Browser analytics but deliberately does not start replay; an integrating product must opt in and supply its own consent flow and exact-host policy.
What the recorder captures
The explicit ReplayRecorder.start() path records rrweb full snapshots and DOM mutations plus
viewport and bounded navigation metadata, clicks, scroll, and pointer movement. Navigation uses a
developer-provided finite route key. Raw URL, path, query, hash, and browsing history are not part
of the replay contract; captured href values are replaced with a safe replay route.
Replay is separate from Browser Experience. Browser Experience emits developer-labelled analytics signals and powers interaction maps plus a compact session timeline. Replay events use dedicated create/chunk/complete/withdraw endpoints, object storage, retention, auditing, and playback. They are never ordinary analytics events and do not broaden the normal event autocapture property model.
Consent and host policy fail closed
The host product must supply affirmative, versioned replay consent. Poolstatis does not invent a consent UI or infer permission from another analytics setting. The recorder also requires an exact current hostname in a finite allowlist; schemes, ports and wildcards are rejected.
Both gates and the privacy policy are validated before manifest delivery and before rrweb is
dynamically imported. A denied, unsampled, wrong-host, or withdrawn-before-start session does not
start the recorder. Calling withdraw() stops recording and retries the same deletion tombstone
if an earlier attempt was ambiguous or interrupted.
Masking and unsafe-DOM exclusions
The default text: "masked" policy masks visible text, all input and textarea values,
contenteditable content, and human-readable attributes. Password, payment, authentication-token,
hidden and one-time-code targets are blocked. Explicit block and mask markers remain enforced in
addition to configured selectors.
An integrating host may explicitly choose the bounded visible-text policy, but that never exposes
form/contenteditable values, secret-like content, human-readable attributes, or unsafe/network DOM.
Scripts, forms, nested iframes, embeds, handlers, data-* attributes and network-bearing
attributes are removed or blocked. IDs and classes become structural tokens; CSS is reduced to a
layout-only allowlist. The server independently sanitizes the recording again before object storage
and again before playback.
Delivery, completeness and retention
Normal chunks are bounded to 500 rrweb events and 512 KiB. One replay is bounded to 120 chunks,
50,000 events, 20 MiB, and 30 minutes. Stable sequence numbers and checksums make exact retries
idempotent. A gap, missing initial full snapshot, invalid timestamp order, oversized payload, or
interrupted final delivery leaves the manifest incomplete; the player does not present it as a
complete recording.
Retention defaults to seven days and accepts only 1–30 days. Consent withdrawal and expiry first tombstone the manifest so reads return an unavailable state, then retry physical object deletion and identifier scrubbing. Self-hosted deployments persist replay objects in a dedicated volume alongside, not inside, the normal analytics event stream. Back up and restore Postgres and the replay object volume as one retention-aware system.
REST, MCP metadata and the sandboxed player
Current Core and managed production expose dedicated replay ingest endpoints for create, chunk upload, complete, and withdrawal. Authenticated platform endpoints list manifests, read one manifest, stream validated events to the admin player, and delete a recording. Reads are tenant- and environment-scoped, checksum-verified, bounded, re-sanitized, and audited.
The Experience admin screen lists recordings and plays only playable sessions with
@rrweb/replay. Reconstruction happens in rrweb's supported scriptless iframe sandbox:
sandbox="allow-same-origin" without allow-scripts. Player interaction and unsafe canvas
replay are disabled. This is not an opaque-origin sandbox, and Poolstatis does not claim one.
Published @poolstatis/mcp@0.7.0 includes list_session_replays and
get_session_replay MCP metadata tools. They
return bounded manifest data and an admin viewer path, never DOM/event bytes, pointer samples, or
object keys.
Deliberate replay limits
Poolstatis replay reconstructs sanitized DOM state; it is not screen video. It deliberately excludes gaze, audio, canvas pixels, synchronized console/network payloads, raw URLs, executable content, and cross-origin iframe contents. Browser Experience still provides the lower-sensitivity labelled timeline when DOM replay is unnecessary. Poolstatis also still lacks a general dashboard builder and full issue-oriented error tracking.
Read the exact Core replay contract or compare the surrounding product boundaries in Poolstatis vs PostHog.