Repository navigation
Conversation
Session Replay Browser E2E ResultsDetails
|
| const dialog = document.getElementById('pressure-dialog')!; | ||
| for (let i = 0; i < 12; i++) { | ||
| const tree = document.createElement('section'); | ||
| tree.innerHTML = '<span></span>'.repeat(1000); |
There was a problem hiding this comment.
🟠 High severity blocking issue identified in your code:
User controlled data in methods like innerHTML, outerHTML or document.write is an anti-pattern that can lead to XSS vulnerabilities
Why this might be safe to ignore:
This match is in a browser test and assigns a fixed string expression generated by repeating a literal, with no user-controlled input or dataflow to the sink. It is not reasonably exploitable as XSS, and the low-confidence rule matched because its exclusions do not recognize this safe expression.
To resolve this comment:
🔧 No guidance has been designated for this issue. Fix according to your organization's approved methods.
💬 Ignore this finding
Reply with Semgrep commands to ignore this finding.
/fp <comment>for false positive/ar <comment>for acceptable risk/other <comment>for all other reasons
Alternatively, triage in Semgrep AppSec Platform to ignore the finding created by insecure-document-method.
You can view more details about this finding in the Semgrep AppSec Platform.
…-review-lifecycle
…view-page-feedback
size-limit report 📦
|
- @amplitude/amp-semantic@0.2.0-codexsemantic-review-integration.0 - @amplitude/analytics-browser@2.48.2-codexsemantic-review-integration.0 - @amplitude/analytics-core@2.62.0-codexsemantic-review-integration.0 - @amplitude/analytics-node@1.5.82-codexsemantic-review-integration.0 - @amplitude/analytics-react-native@1.12.5-codexsemantic-review-integration.0 - @amplitude/plugin-autocapture-browser@1.31.0-codexsemantic-review-integration.0 - @amplitude/plugin-event-property-attribution-browser@0.2.25-codexsemantic-review-integration.0 - @amplitude/plugin-experiment-browser@1.0.0-codexsemantic-review-integration.0 - @amplitude/plugin-experiment-react-native@1.0.0-codexsemantic-review-integration.0 - @amplitude/plugin-network-capture-browser@1.10.25-codexsemantic-review-integration.0 - @amplitude/plugin-page-url-enrichment-browser@0.7.35-codexsemantic-review-integration.0 - @amplitude/plugin-page-view-tracking-browser@2.12.0-codexsemantic-review-integration.0 - @amplitude/plugin-session-replay-browser@1.37.0-codexsemantic-review-integration.0 - @amplitude/plugin-session-replay-react-native@0.5.12-codexsemantic-review-integration.0 - @amplitude/plugin-web-attribution-browser@2.2.35-codexsemantic-review-integration.0 - @amplitude/plugin-web-vitals-browser@1.2.8-codexsemantic-review-integration.0 - @amplitude/segment-session-replay-plugin@0.0.54-codexsemantic-review-integration.0 - @amplitude/session-replay-browser@1.52.0-codexsemantic-review-integration.0 - @amplitude/session-replay-dom-privacy@0.3.0-codexsemantic-review-integration.0 - @amplitude/unified@1.1.44-codexsemantic-review-integration.0 - @amplitude/unified-react-native@1.0.0-codexsemantic-review-integration.0
|
The integration draft is superseded for merging by the clean stack: #2120, #2126, #2127 (merged), then #2128 → #2150 → #2151 → #2152 → #2153 → #2154 → #2155 → #2156. Each event family now has an isolated PR with passing focused package, SDK, and browser tests. The old branch remains available as a reference. |
Summary
Complete the standalone semantic runtime and integrate interaction, lifecycle, and page-feedback capture into rrweb custom events (
type: 5,amp-semantic/*). Include shared privacy-aware target/name/state helpers, sampling and caps, versioned schemas, and the local replay inspector and browser tests. Capture remains opt-in.The stream includes user agent and visibility context, tab/document identity, visibility boundaries, lifecycle signals, approved non-character keys/shortcuts, compact resource failures, interaction states, and checkbox/radio state. Resource failures use bounded 500 ms groups. Temporary SDK/extension logs are removed; existing errors and local inspector diagnostics remain. Generated extension vendor files are excluded.
Shared click path and performance
Route semantic primary clicks through replay's existing heatmap
ClickHandlerand rrweb mouse-interaction hook. The same path works with heatmaps disabled. Preserve native modifiers, keyboard activation, trust, and composed-path targeting without serializing the native event. Reuse selectors only for the same element within one click; actionable ancestors retain separate IDs/selectors. Isolate failures between consumers and keep disabled replay's empty-hook configuration unchanged.Pin the recorder, recorder types, and console plugin to the published
2.1.5release. It includes the native-event hook extension andrecord.supportsNativeMouseInteractionfrom rrweb #142. Remove the pnpm patch and its lockfile references so downstream unbundled installations receive the same shared-click capability. Older recorders fall back to a native listener. Keep an auxiliary-click listener because rrweb does not forwardauxclick.Notice/dialog capture consumes accepted rrweb full snapshots and mutation batches through a structural host signal and mirror node resolver. Remove its separate MutationObserver, startup dialog selector query, and live-DOM discovery walks. Initial snapshots seed dialog state silently; relevant additions, text changes, attributes, removals, and moves drive the existing semantic payloads. Queue synchronous startup input until the capture runtime starts and ignore custom events to prevent feedback loops. Standalone hosts must provide the DOM signal and node resolver; there is no observer fallback.
Inspect serialized changes incrementally, resolving only relevant live elements and changed parents. Deduplicate repeated parent lookups in flat rrweb additions with a bounded set. Keep privacy-aware text/name/state helpers and clear detached dialog names while retaining recorded IDs. Track closed/hidden dialogs too so ancestor changes and moves preserve open/close detection. Do not change the wire schema.
Delivery gets the first 2 ms of each frame and alternates families; serialized processing and delivery share a cooperative 4 ms budget, capped at 1,000 work items and 50 payload candidates per frame. Retain at most 128 replay batches, 256 notice candidates/timers, 256 dialog candidates, and 256 tracked dialogs. Queued batch references retain their source data until consumed. Overflow reports a payload-free diagnostic once per limit per setup. Timers enqueue rather than construct payloads, and processing unsubscribes when both families exhaust their caps.
State/timestamps remain processing-time observations. rrweb batching and deferred enrichment may coalesce transient changes or omit nodes removed before discovery; blocked or otherwise unrecorded changes are not reconstructed. CSS-only and full-page visibility remain outside scope. Limits are cooperative, not hard per-operation deadlines.
Preflight capacity before expensive payload construction, and cache only a heading DOM candidate for 250 ms with fresh privacy/visibility/text checks. Fix autocapture's capture-phase change-listener cleanup. No cross-SDK observer broker is introduced.
amp-semantic/click-outcomeis removed from the current package scope, including its recorder, schema, types, cap, fixtures, outcome mutation observer, and per-click timers. Remove the autocapture → amp-semantic dependency introduced solely to share this logic; existing analytics dead-click behavior is retained. The local playground and v0 spec reflect the removal.amp-semantic/pageis also removed from the current scope: no page recorder, title observer, immediate/2-second/5-second page scans, schema, cap, or family toggle. Interaction URL/heading fields remain. The replay adapter forwards navigation to invalidate cached interaction headings, without emitting page events. Browser tests verify post-navigation click context and stable document identity through the remaining events.Navigation from the existing URL plugin
Add
amp-semantic/navigationwith only a templatedurlplus version/tab/document identity. Reuse acceptedamplitude/url-tracking@1rrweb events for the initial URL, subsequent history/hash or configured polling observations, and recording resume. Remove the semantic adapter's separate URL subscription. The same observations invalidate cached interaction headings even when the navigation family is disabled.Apply semantic URL normalization after the plugin's existing UGC filtering: omit origins and query values and template ID-shaped path segments. Literal path text remains subject to configured UGC rules. Do not emit title or navigation reason or restore page scans. Preserve distinct observations that share a template. Apply sampling, family switches, teardown, and a 200-events/session cap. Update the wire schema, v0 spec, fixtures, and local inspector's event guide.
Field values and accessibility metadata
Field events now include optional native input/textarea
valuewhen the current replay input policy permits it, with no length limit or whitespace normalization. Masked values are omitted; password, revealed-password (data-rr-is-password), hidden and blocked fields remain excluded. Files, checkbox/radio submitted values, selects and contenteditable contents are outside this value addition. Selection labels and checked state retain their existing contracts. No new observers or per-keystroke events are added. Long values increase serialization, deduplication memory and payload size proportionally; the event-count cap does not bound bytes.Fields and key targets now include shared event-time
states; fields, key targets and dialogs also includename_source. Native disabled state respects fieldset inheritance and the first-legend exception. Invalid state includes native constraint invalidity for participating controls plus ARIA grammar/spelling/unknown nonempty tokens. Native validity reads do not callcheckValidity()or dispatch validation events. Field validity uses the same ARIA interpretation. Privacy-suppressed names and detached dialog names reportmasked; naturally unnamed targets remainunnamed. The new fields are optional in the v1 wire schema for legacy recordings. No additional observers, listeners, scans or timers are introduced.The v0 spec retains relationship IDs, accessibility exposure, live-region enrichment and richer name/custom-widget handling as follow-up work. Lifecycle/context/resource events do not receive a blanket ARIA attribute bundle.
Review scope
This is the complete integration PR against
main, including the semantic runtime, capture families, replay adapter, schema, privacy handling, and local validation fixture. The final review tree matchescodex/amp-semanticand includes main's rrweb 2.1.5 release (491914d69).The earlier interactions #2079, lifecycle #2080, and page feedback #2081 drafts remain open as workstream references. They are not independently buildable/releasable and are no longer this PR's merge prerequisites.
Lockfiles and bundle budgets
Repair missing semantic workspace importer/dependency entries across the review branches, and reconcile their shared lockfile ancestry to avoid duplicate package/snapshot keys in PR merge commits. Preserve main's dependency graph; this PR's lockfile diff against main is 19 added lines. Frozen-lockfile checks pass on all four review branches, and a full frozen install passes on the final integration tree.
Retarget the complete PR to main so the bundle-size comparison uses a buildable baseline. Explicitly account for the added semantic capture runtime: replay's gzip budget changes from 150 KB to 160 KB and unified's from 235 KB to 245 KB. Measured on the final main-based tree: 154,825 bytes and 242,245 bytes respectively. The full root build passes for all 31 projects; docs, lint, dependency checks, and all four local size checks pass. This is a feature budget adjustment, not a download-size optimization; the capture functionality and compilation targets are unchanged. Analytics-browser and element-selector limits are unchanged.
GitHub Actions on
6d9e3428confirms Check Size Limits, Build Docs, and Check Unused Dependencies pass. The Node 22/24/26 jobs passed dependency installation and compilation and reached their test steps; their overall results are not yet confirmed.Semgrep is outside this CI repair's scope. Semantic/replay coverage gates are now satisfied; broader local test limitations are documented below.
Related: SRAI-55, SRAI-56, SRAI-64, SRAI-81, SRAI-82.
Validation and draft blockers
Node 24.22.1 / pnpm 11.28.5, complete integration tree with published rrweb 2.1.5:
build(31 projects), replay dependency build (pnpm build:semantic), semantic typecheck, rootdocs:check, rootlint(30 projects), andlint:depspass.pnpm test --concurrency 4 -- --runInBandrun passed the semantic, replay, plugin, and analytics-core suites. Analytics-node initially failed because the sandbox denied its HTTP test servers permission to bind ports (listen EPERM); rerunning outside the sandbox passes all 39 tests at 100% coverage. The root command was stopped after its Segment bundle rebuild stalled for over nine minutes. Analytics-core and React Native also reported open handles after their assertions passed. This is not a clean green full-root test result.tsc --noEmit -p tsconfig.jsoncheck still encounters an unrelated implicit-thiserror ine2e/idb.spec.ts:669; package production builds pass.test:examplesstill fails becausejest.setup.examples.jsis absent. Node 22/26 remain unverified.New deterministic regressions verify that 5,000 ordinary serialized nodes require only the relevant notice/parent lookups and that large batches of irrelevant attributes remain frame-bounded. They are operation-count checks, not a production CPU benchmark.
Local fixture measurements from the earlier performance change showed interaction dispatch p95 about 0.6 ms before versus 0.1 ms after on a 20,000-element page. These are fixture measurements, not production guarantees. Exact ±1 ms rrweb timestamp alignment, the production byte budget, accepted analytics wiring, iframe lifecycle coverage, and full accessibility/visibility reconstruction remain outside the validated scope. Actionable-ancestor IDs may differ from raw rrweb target IDs; consumers must scope IDs to their replay/document.
Deterministic analytics-core source-error tests
The existing asyncMap source-error test relied on a 10 ms wall-clock gap for a promise mapping to finish before the source errored. Control timers and promise flushing explicitly so this test verifies the intended ordering independent of runner load. Add the opposite ordering as a regression: a terminal source error suppresses a mapping that resolves later. Restore real timers in finally blocks; production observable behavior is unchanged.
Validation: focused observable suite passes (13 tests) and exits normally; all 918 analytics-core tests across 59 suites pass, with 100% statements/branches/functions/lines. ESLint and formatting pass. The full local runner reported open handles after finishing its tests and was stopped; this does not establish a clean full-suite process exit. Semantic/replay coverage blockers are resolved by the coverage completion below.
Coverage completion
Add behavior tests for privacy and naming fallbacks, malformed resource errors, shortcut modifiers, deferred form validity, recorder teardown and capacity, bounded notice/dialog queues, native heatmap/semantic clicks, host callbacks, terminal recording events, tab identity, and URL polling. Exercise analytics autocapture boolean configuration as well as object configuration.
Remove the unused base cleanup callback and redundant null checks after initialization. Keep dialog queues bounded by the tracking registry and remove detached, already-closed dialogs from both registries before admitting replacements; test a full 256-dialog replacement burst. Keep caps, wire payloads, masking, and capture enablement unchanged.
Validation: all 1,409 tests across the three packages pass with 100% coverage in all four dimensions. The full build and repository lint, docs, dependency, semantic typecheck, and bundle-size checks pass. Latest measured gzip sizes are approximately 154.75 KB for replay and 242.14 KB for unified, within the existing feature budgets. Generated extension vendor files remain excluded.