feat(sentry): Phase 11 toggle rework, metrics layer + PII scrubbers#111
Open
gmaclennan wants to merge 2 commits into
Open
feat(sentry): Phase 11 toggle rework, metrics layer + PII scrubbers#111gmaclennan wants to merge 2 commits into
gmaclennan wants to merge 2 commits into
Conversation
Implements the Sentry Phase 11 workblock (plan §11, §9b.1, §9b.5): #75 toggle rework - Rename captureApplicationData -> applicationUsageData across the JS API, native bridge methods, on-device stored key, Expo plugin field, and Node CLI flags. Deprecated aliases forward for one minor release; a one-shot stored-key migration runs on first prefs open (both platforms). - New `debug` toggle (get/setDebugEnabled, sentry.debug + sentry.debugEnabledAtMs slots, --debug argv, debugDefault plugin field) with a 24h auto-off enforced in the native debug reader. - Device classification (DeviceTags.{kt,swift}): low/mid/high by RAM + cores plus <platform>.<major>, plumbed to RN via sentryConfig.deviceTags and to Node via --deviceClass/--osMajor/ --platformTag. - tracesSampleRate now derives from debug (1.0/0). #76 metrics layer - New backend/lib/metrics.js + src/sentry-metrics.ts: wrappers that inject `platform` on every metric, attach device tags only on the .by_device mirrors, no-op when Sentry is off, and drop forbidden tags. RPC hooks split: always record the metric, span only under debug (recorded while active so it links to the trace). console integration moved behind debug; 60s memory/event-loop sampler, boot-phase durations, state transitions, storage-size bucket. #77 PII scrubbers - Shared regex list (rootKey, 22-char base64, lat/lng) in src/sentry-scrub.ts (RN) and backend/before-send.js (Node). RN wires the real beforeSend ahead of the host chain plus a host-only URL beforeBreadcrumb; Node registers the same scrub as an event processor. Walks message, exception, extra, contexts, breadcrumb message+data, span description+data; HTTP breadcrumb URLs reduce to host-only. Tests: backend metrics/before-send suites, extended sentry suites (debug branching + scrubber), native migration/24h-auto-off/device boundary tests. npm lint, tsc, jest (18), backend node --test (47) all green locally. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Implements the Sentry Phase 11 workblock (tracking #74) in one branch / one PR. Spec:
docs/sentry-integration-plan.md§11.1–§11.8, §9b.1, §9b.5, Phase 5.Part of #74 (tracking umbrella — remaining children #78–#83 stay open)
Closes #75
Closes #76
Closes #77
#75 — Toggle rework (§11.1, §11.5, §11.6, §11.7, §11.2.b)
captureApplicationData→applicationUsageDataeverywhere: JS get/set, native bridge methods, the on-device stored key, the Expo plugin field, and the Node CLI flags.get/setCaptureApplicationData, nativesetCaptureApplicationData,--captureApplicationDataargv, plugincaptureApplicationDataDefaultwith a warn-don't-error path).debugtoggle:get/setDebugEnabled(JS),setDebugEnabled(native),sentry.debug+sentry.debugEnabledAtMsslots,--debugargv,debugDefaultplugin field.debug=falseif switched on >24h ago and queues acomapeo.debug.auto_disabledbreadcrumb; re-enable refreshes the window. Both platforms.DeviceTags.{kt,swift}bucket the device low/mid/high by RAM + cores and compute<platform>.<major>. Passed to JS viasentryConfig.deviceTagsand to Node via--deviceClass/--osMajor/--platformTag.tracesSampleRatenow derived fromdebug(1.0/0).#76 — Metrics layer (§11.2, §11.3, §11.6, §11.8)
backend/lib/metrics.js+src/sentry-metrics.ts: wrappers aroundSentry.metrics.*injectingplatformon every metric + units, attachingdevice_class/os_majoronly on the.by_devicemirrors, no-op when Sentry is off.debug, recording the metric while the span is active so it links to the trace (§11.3).src/ComapeoCoreModule.ts(onRequestHook) +backend/lib/sentry.js(rpcHook).tracesSampleRatedriven bydebug; backendconsoleIntegrationmoved behinddebug.beforeSendMetricforbidden-tag filter on the JS + Node metrics paths (shared regex list). Native SDKs: see deferral note.#77 — PII scrubbers (§9b.1, §9b.5, Phase 5)
src/sentry-scrub.ts) and Node (backend/before-send.js), each pointing at the other.beforeSendbefore the host's chain; URL-scrubbingbeforeBreadcrumb.backend/before-send.jsregistered as aSentry.addEventProcessorinlib/sentry.js's init.Scrubber false-positive trade-off
The substring scrubber over-redacts by design — leaking a real project secret costs far more than a stray
[redacted]:aGVsbG8td29ybGQtMTIzNA→[redacted](real rootkey shape)bm90LWEtcmVhbC1rZXktMQ→[redacted](harmless, false positive)latitude: -12.34→latitude: [redacted]; evenlongitude: unknown-style prose loses its value.https://cloud.comapeo.app/projects/abc?token=x→https://cloud.comapeo.app— path/query detail lost, "all requests to host X failing" diagnosability kept.The same patterns gate the metrics
beforeSendMetricfilter (forbidden tag names + base64-22 / lat-lng tag values).Checks run locally
npm run lint— pass (0 errors, 0 warnings)npx tsc --noEmit(src) — passnpm test(jest, src) — pass (18/18)npm --prefix backend ci --ignore-scriptsthennode --test 'lib/**/*.test.mjs'— pass (47/47)rolldownbuild — pass; verifiedloader.mjskeeps@sentry/node-corebehind the gated dynamic import.Could NOT run locally (rely on CI)
ComapeoPrefsTest,SentryConfigTest, newDeviceTagsTest) — no Android SDK / Gradle here. Cover the stored-key migration, 24h auto-off boundaries, and device-classification boundaries (exactly 3 GB RAM, exactly 4 cores). Need the CI emulator/Gradle to execute.ComapeoPrefsTests,SentryConfigTests, newDeviceTagsTests) — no Xcode here. Same coverage. Need CI/Xcode to execute.backend npm run typesis red onmainalready (pre-existingpolywasmdeclaration gap, unrelated); the new production files type-clean.Deferred (called out explicitly)
beforeSendMetricon the native (Android/iOS) SDKs is not yet wired — only the JS + Node metric paths run the forbidden-tag filter today. The native exit metric is the only native metric currently emitted and is already low-cardinality by construction; the native hook is a small follow-up.metrics.jshelpers exist; sync-session lifecycle plumbing is a Phase 5 item). The always-on RPC, boot, memory, state, and storage metrics are wired end-to-end.🤖 Generated with Claude Code