Skip to content

✨ [RUM-17990] add a path scrubber for serialized payloads - #240

Draft
bcaudan wants to merge 3 commits into
mainfrom
bcaudan/scl-path-scrubber
Draft

bcaudan wants to merge 3 commits into
mainfrom
bcaudan/scl-path-scrubber

Conversation

@bcaudan

@bcaudan bcaudan commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Motivation

Stack traces and URLs collected in Electron apps contain installation-specific paths (file:///Users/alice/…/app.asar/dist/main.js, C:\Users\alice\AppData\…). They prevent source maps from resolving, leak the user's home directory, and split aggregations per installation. This PR adds the component that replaces the app path in serialized payloads. It is not wired yet: the next PR in this stack injects it where payloads are written.

Changes

  • New PathScrubber (src/tools/pathScrubber.ts), created with await PathScrubber.init(): the app path (and its .unpacked folder) becomes /, so frames read /dist/main.js and match source maps uploaded with a /dist/ prefix.
  • It works on the serialized JSON, right before payloads are written, so every field of every payload type is covered. The app path compiles one regex matching its usual notations (raw path, Windows path, file:// URL).
  • A path is replaced wherever it appears, but never when glued to a longer file or folder name (MyApp2).
  • The main purpose is consistent paths for source maps. Masking the user's home directory is best effort, not exhaustive (data folders such as userData are not masked; the other known limits are listed in the class JSDoc). A false positive only costs misleading data, a miss leaves the path as is.
  • scrub() keeps valid JSON valid and never throws: on an internal error it returns its input and reports once.

Things to look at:

  • The regexes match the serialized JSON, with structural guards so a match never starts inside a JSON escape and the scan stays linear.
  • Covered by table-driven tests plus seeded property tests (random payloads stay valid JSON; near misses stay byte-identical).
  • Benchmark: a few ms to about 12 ms per 10 MB (budget: 50 ms), to be measured again under Electron's V8.

Test instructions

  1. yarn vitest bench --run src/tools/pathScrubber.bench.ts: every case stays well under 50 ms
  2. Read the it.each tables in src/tools/pathScrubber.spec.ts: each row is an input payload fragment and its scrubbed form
  3. End-to-end checks come with the next PR, once the scrubber is wired into the payload writers

Checklist

  • Tested locally (playground)
  • Added unit tests for this change.
  • Added e2e/integration tests for this change.
  • Updated related documentation.
  • Agentic code review findings addressed or explicitly dismissed.

@bcaudan
bcaudan added this pull request to stack #239 October 7, 2026 08:57
@bcaudan bcaudan changed the title bcaudan/scl path scrubber ✨ [RUM-17990] add a path scrubber for serialized payloads Oct 7, 2026
@bcaudan

bcaudan commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-07T12:52:24.075622Z 9203612 Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@bcaudan
bcaudan force-pushed the bcaudan/scl-path-scrubber branch from 7db4b11 to 90594b3 Compare October 7, 2026 09:03
@bcaudan
bcaudan force-pushed the bcaudan/scl-path-scrubber branch from 90594b3 to 07654b7 Compare October 7, 2026 09:04

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7db4b11be6

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/tools/pathScrubber.ts Outdated
Comment thread src/tools/pathScrubber.ts
Comment thread src/tools/pathScrubber.ts

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

PR Review — Quality: 3.0 / 5 · Review load: Focused (~30–45min)

POSIX paths and C:\... paths match the description: one regex per sdk path, longest match first, JSON stays valid and byte-identical off the match. Request changes. A UNC userData is kept at init and then left in the payload, with no skip error, so the home directory this component exists to remove still ships.

Customer impact: Low — PathScrubber has no production caller, so payloads stay as they are until a later PR calls scrub.

Concern
Serialized payload scrubbing Risky

Quality — 3.0: POSIX and drive-letter paths are correct, and the tables, property checks, and linear-time test match that risk. The class JSDoc covers this internal type; there is no public API to document. One compiled regex per path, applied longest first on the serialized string, will take another notation or a new sdkPaths entry cleanly. The caller still has to pass plaintext JSON, including a replay segment before compression, because the on-disk replay batch is metadata plus base64. The UNC miss is what holds this at 3.0.

Review load — Focused (~30–45min): One risky boundary: which bytes scrub rewrites. Almost all of the time is pathScrubber.ts (notations, nested paths, JSON validity). The bench and coverage exclude belong to that same boundary. Windows matching landed in 2aa7793 and is the same boundary.

Findings

  • [Blocking] UNC paths are never scrubbed — src/tools/pathScrubber.ts:163 (2aa7793) sends \\server\\share\\... through the POSIX lookahead [/f], so a path whose JSON form starts with \ never matches and is never logged. Compile UNC like a drive path, and include the raw pattern's first character in the lookahead.
  • [Minor] Windows segment case stays in the payload — src/tools/pathScrubber.ts:166 (2aa7793) folds only the drive letter, and the near-miss table treats C:\\users\\... like a different path. Fold each segment, or confirm stacks always reuse app.getPath's casing.
  • [Nit] Scrub failure drops the thrown error — src/tools/pathScrubber.ts:79 wraps a fresh Error, so the one addError stack points at the catch. Pass the caught error through.
Open in Web View Automation 

Sent by Cursor Automation: electron-sdk reviews

Comment thread src/tools/pathScrubber.ts Outdated
Comment thread src/tools/pathScrubber.ts Outdated
@bcaudan
bcaudan force-pushed the bcaudan/scl-path-scrubber branch from 07654b7 to 616b7bb Compare October 7, 2026 09:58
@bcaudan

bcaudan commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator Author

[Nit] Scrub failure drops the thrown error — src/tools/pathScrubber.ts:79 wraps a fresh Error, so the one addError stack points at the catch. Pass the caught error through.

The fixed message is deliberate. The caught error could carry part of the unscrubbed payload (e.g. a value in a TypeError message), which is what this component is meant to keep out of telemetry.

@bcaudan

bcaudan commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 616b7bb5aa

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/tools/pathScrubber.ts
Comment thread src/tools/pathScrubber.ts

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

PR Review — Quality: 4.5 / 5 · Review load: Focused (~30–45min)

This is ready to merge. POSIX paths and Windows paths, including a different case, match the description: one regex per sdk path, longest first, valid JSON in and out. Approve. One file-URL encoding is still open, on the line below. e2e and integration were still running when I posted.

Customer impact: Low — PathScrubber has no production caller, so payloads stay as they are until a later PR calls scrub.

Concern
Serialized payload scrubbing Risky

Quality — 4.5: The scrubber matches its contract on the paths I checked: raw stacks, forward-slash file URLs, nested crashDumps, and Windows case. The tables, property checks, and linear-time test cover that risk in proportion. The class JSDoc is the right doc for this internal type; there is no public API. One compiled regex per path, applied longest first, will take another notation or a new sdkPaths entry cleanly, and the next caller still has to pass plaintext JSON, including a replay segment before compression. The opposite-case non-ASCII file URL is what holds this below 5.0.

Review load — Focused (~30–45min): One risky boundary: which bytes scrub rewrites. Almost all of the time is pathScrubber.ts (notations, case, JSON validity) together with the tables that pin it. The bench and the coverage exclude sit on that same boundary. Windows matching is 79991d1.

Findings

  • [Minor] Opposite-case non-ASCII file URLs stay in the payload — src/tools/pathScrubber.ts:212 (79991d1) percent-encodes only the sdk path's own code point, so José does not match JOS%C3%89. Also encode that other simple case, or list it next to the %61 limit if nothing emits it.
Open in Web View Automation 

Sent by Cursor Automation: electron-sdk reviews

Comment thread src/tools/pathScrubber.ts
@bcaudan
bcaudan force-pushed the bcaudan/scl-path-scrubber branch from 616b7bb to 0e3d8c9 Compare October 7, 2026 12:01
@bcaudan

bcaudan commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale comment

PR Review — Quality: 5.0 / 5 · Review load: Focused (~30–45min)

This is ready to merge. PathScrubber replaces sdk paths in serialized JSON, the app path with / and data folders with <userData> / <crashDumps>, including the Windows notations, and it is not wired into the writers yet. Approve. The percent-encoded non-ASCII case limit is now in the class JSDoc, with the other limits. Integration was still running when I posted.

Customer impact: Low — PathScrubber has no production caller, so payloads stay as they are until a later PR calls scrub.

Concern
Serialized payload scrubbing Risky

Quality — 5.0: The scrubber matches its contract: raw stacks, file URLs, nested crashDumps, and Windows case come out as the tables say, and a near miss stays byte-identical. Those tables, the property checks, and the linear-time test are proportionate to the regex. The class JSDoc keeps pace for this internal type; there is no public API to document. The design is sound: one compiled regex per path, longest first, will take another notation or a new sdkPaths entry. Wiring it later means passing plaintext JSON, including a replay segment before compression, since the on-disk replay batch is metadata plus base64.

Review load — Focused (~30–45min): One risky boundary: which bytes scrub rewrites. Almost all of the time is pathScrubber.ts (notations, case, JSON validity) together with the tables that pin it. The bench and the coverage exclude sit on that same boundary.

Open in Web View Automation 

Sent by Cursor Automation: electron-sdk reviews

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0e3d8c933b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/tools/pathScrubber.ts
Comment thread src/tools/pathScrubber.ts Outdated
Comment thread src/tools/pathScrubber.ts
@bcaudan

bcaudan commented Oct 7, 2026

Copy link
Copy Markdown
Collaborator Author

@codex review

Please focus on issues likely to happen in real Electron apps. The main purpose is consistent paths for source maps; masking user paths is best effort, and its known limits are listed in the class JSDoc. Skip edge cases that need unlikely setups (unusual characters in install or data folder names, hand-crafted URLs, folders packagers never create), and don't raise again points already answered in resolved threads.

@bcaudan
bcaudan force-pushed the bcaudan/scl-path-scrubber branch from 0e3d8c9 to 9203612 Compare October 7, 2026 12:48

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR Review — Quality: 5.0 / 5 · Review load: Focused (~30–45min)

This is ready to merge. PathScrubber replaces sdk paths in serialized JSON, the app path with / and data folders with <userData> / <crashDumps>, including the Windows notations, and it is not wired into the writers yet. Approve. The named start constants on this head compile the same lookaheads as before. e2e and integration were still running when I posted.

Customer impact: Low — PathScrubber has no production caller, so payloads stay as they are until a later PR calls scrub.

Concern
Serialized payload scrubbing Risky

Quality — 5.0: The scrubber matches its contract: raw stacks, file URLs, nested crashDumps, and Windows case come out as the tables say, and a near miss stays byte-identical. Those tables, the property checks, and the linear-time test are proportionate to the regex. The class JSDoc keeps pace for this internal type; there is no public API to document. The design is sound: one compiled regex per path, longest first, will take another notation or a new sdkPaths entry. Wiring it later means passing plaintext JSON, including a replay segment before compression, since the on-disk replay batch is metadata plus base64.

Review load — Focused (~30–45min): One risky boundary: which bytes scrub rewrites. Almost all of the time is pathScrubber.ts (notations, case, JSON validity) together with the tables that pin it. The bench and the coverage exclude sit on that same boundary.

Open in Web View Automation 

Sent by Cursor Automation: electron-sdk reviews

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

Reviewed commit: 92036123be

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Replaces the installation-specific app path with `/` in serialized payloads, so source maps resolve whatever the install folder.
Windows paths appear JSON-escaped, with forward slashes, a long-path prefix or as file URLs, and must resolve the same way.
Payloads must stay valid JSON whatever surrounds a path, and scrubbing a full replay segment must stay within budget.
@bcaudan
bcaudan removed this pull request from stack #239 October 7, 2026 16:41
@bcaudan
bcaudan force-pushed the bcaudan/scl-path-scrubber branch from 9203612 to 7b73f73 Compare October 7, 2026 16:45
@bcaudan
bcaudan changed the base branch from bcaudan/scl-sdk-paths to main October 7, 2026 16:45
@bcaudan
bcaudan added this pull request to stack #242 October 7, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant