crash-reporting-and-observability
Wires Sentry crash reporting behind a port: start on consent, PII scrubbing, releases, source maps per build and update.
Skill by zakariaf
Chalk Labs
Need help deploying crash-reporting-and-observability?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/zakariaf-crash-reporting-and-observability
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: data
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md and code. Checked Oct 26, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Node.js package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/crash-reporting-and-observability
What's inside
- Skill name
crash-reporting-and-observability- Description
- Wires Sentry crash reporting behind a port: start on consent, PII scrubbing, releases, source maps per build and update. Use when adding Sentry or a DSN, or stacks are minified. Not for analytics (analytics-and-consent).
- License
- MIT
- Instructions
- 205 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
Agent Skills spec issues
- files: referenced but missing: scripts/metro/metro-kits.ts
Files (46)
- SKILL.md
- shared.json · assets/
- app.config.ts · examples/
- create-root-kits.ts · examples/
- settings-schema.ts · examples/
- error-flow-breadcrumbs-and-tracing.md · references/
- privacy-consent-and-scrubbing.md · references/
- releases-symbols-and-sourcemaps.md · references/
- setup-and-wiring.md · references/
- testing-and-checker-rules.md · references/
- check-crash-reporting.mjs · scripts/
- check-lib.mjs · scripts/
- crash-scan.mjs · scripts/lib/
- object-literal.mjs · scripts/lib/
- source-scan.mjs · scripts/lib/
- selftest.mjs · scripts/
- react-native.ts · templates/__mocks__/@sentry/
- crash-reporting.json · templates/contracts/
- crash-reporting.schema.json · templates/contracts/
- metro-kits.ts · templates/scripts/metro/
- crash-reporting-config.test.ts · templates/src/config/
- crash-reporting-config.ts · templates/src/config/
- crash-reporting-env.d.ts · templates/src/config/
- use-crash-reporting-consent.test.ts · templates/src/hooks/
- use-crash-reporting-consent.ts · templates/src/hooks/
- use-route-breadcrumbs.test.tsx · templates/src/hooks/
- use-route-breadcrumbs.ts · templates/src/hooks/
- crash-forwarder.test.ts · templates/src/services/crash-reporter/
- crash-forwarder.ts · templates/src/services/crash-reporter/
- crash-reporter-port.ts · templates/src/services/crash-reporter/
- crash-reporting-root-kit.test.tsx · templates/src/services/crash-reporter/
- crash-reporting-root-kit.tsx · templates/src/services/crash-reporter/
- crash-scrubber.test.ts · templates/src/services/crash-reporter/
- crash-scrubber.ts · templates/src/services/crash-reporter/
- fake-crash-reporter.test.ts · templates/src/services/crash-reporter/
- fake-crash-reporter.ts · templates/src/services/crash-reporter/
- sentry-crash-reporter-adapter.test.ts · templates/src/services/crash-reporter/
- sentry-crash-reporter-adapter.ts · templates/src/services/crash-reporter/
- dot-gitignore · tests/bases/app/
- dot-npmrc · tests/bases/app/
- eas.json · tests/bases/app/
- metro.config.js · tests/bases/app/
- package.json · tests/bases/app/
- CASES.json · tests/fixtures/check-crash-reporting/
- SUITE.json · tests/fixtures/check-crash-reporting/
- EXPECT.txt · tests/fixtures/check-crash-reporting/good/
SKILL.md (first lines)
# Crash reporting and observability
Makes an Expo app report its crashes to Sentry through one port and one adapter, plugged into the
canonical root skeleton as a root kit (one registry entry, no root file edited): nothing leaves the
device before the person's choice, nothing personal leaves at all, every error reaches exactly one
issue, and every store build and OTA update can be read in TypeScript source. One zero-dependency
checker proves it on the real code and configs.
## Rules that must hold
1. **`@sentry/react-native` is imported only by `src/services/crash-reporter/sentry-crash-reporter-adapter.ts`
(never the root entry file, where Sentry's manual setup puts `Sentry.init`); the app reports through `CrashReporterPort`** (`setConsent`, `captureException`, `addBreadcrumb`,
`flush`, `status`), created once by the root-kit registry (`src/services/create-root-kits.ts`, part of
the composition root), tests through `createFakeCrashReporter()`, and Jest gets the root mock.
`sentry-expo` is never installed. *Why:* one file decides what leaves the device, and the real
SDK in Jest leaks a timer that keeps workers alive.
2. **Nothing is sent before the person's choice, and never from development or tests.** The adapter
does no I/O when created (no `Sentry.init` in the factory body); `Sentry.init` runs inside `setConsent(true)` only, which
`useCrashReportingConsent` calls from the crash reporting kit's effects, mounted beside the root
Stack after the splash release (never the registry, the composition root or the root layout); the
choice comes from a consent source over the settings field (or `fixedCrashConsent(false)` until the
app has the row); earlier reports wait in a bounded queue and a refusal drops them; the
development variant and an empty DSN never start the SDK. The settings default follows the
contract's `consentModel` (`opt-in` by default). *Why:* crash data is personal data under most
privacy laws, and startup must open no connection before the first frame.
3. **The options are the privacy-first set.** `sendDefaultPii: false` written; no screenshots, view
hierarchy, Session Replay, feedback widget, logs or failed-request capture. *Why:* each of those
sends what the person typed, saw or requested; Sentry's own Expo snippet turns several on.
4. **Every event and breadcrumb passes the scrubber, and no report names a person.** `beforeSend`,
`beforeSendTransaction` and `beforeBreadcrumb` call `crash-scrubber.ts`; there is no `setUser`
(only `setUser(null)`), and the port has no member for it; the developer turns on Sentry's
server-side scrubbing. *Why:* `beforeSend` never sees native crashes, but the JavaScript scope is
synced into them, so identity set anywhere ends up in reports the scrubber cannot touch.
5. **Each error reaches Sentry exactly once.** The error net keeps Hermes' rejection tracker
(`reactNativeErrorHandlersIntegration({ onunhandledrejection: false })`), Sentry keeps the global
handler (it flushes fatal errors, and both native SDKs drop React Native's fatal-JS crash expecting
it), and the root skeleton's error sink records everything locally and hands each report to the
kit's `forward: createCrashForwarder(crashReporter)`, which sends exactly `render` and
`unhandled-rejection` (the reports of the first moments included: the sink replays them). *Why:*
Hermes keeps one tracker (last caller wins), and a forwarded `global-handler` report would
duplicate every uncaught exception.
6. **Breadcrumbs carry route patterns and fixed event names, never content.** Route crumbs come from
`useSegments()` (`tasks/[id]`), never `usePathname()` or search params; console, touch and UI crumbs
are dropped; no `Sentry.wrap` or `TouchEventBoundary`. *Why:* paths, console lines and pressed
labels hold ids, search text and titles.
7. **Release and dist come from the native build; environment is the variant.** No `release` or
`dist` in the options (`<id>@<version>+<build>` and `<build>` come from native);
`environment: config.environment`. *Why:* a JavaScript release splits one build into two releases
and no longer matches the uploaded symbols; without `environment` every preview crash is filed under
production.
8. **Every bundle reports its debug ID and every reporting build uploads its maps and symbols.** Metro
uses `getSentryExpoConfig`, as the crash reporting Metro kit in `scripts/metro/metro-kits.ts` (the
canonical `metro.config.js` composes it; never edited); `app.config.ts` lists `@sentry/react-native/expo` with `organization`
and `project`; profiles in the contract's `uploadProfiles` never set `SENTRY_DISABLE_AUTO_UPLOAD`,
`SENTRY_ALLOW_FAILURE` or a debug-upload switch; installs keep optional dependencies (the
`sentry-cli` binary). *Why:* Expo's default config writes a debug ID into the map only, and a
build without uploads ships crashes nobody can read.
9. **Every OTA update uploads its source maps.** Each script or workflow that runs `eas update` also
runs `npx sentry-expo-upload-sourcemaps dist`; each EAS Workflows `type: update` job sets
`upload_sentry_sourcemaps: true` (or uploads in its `after_update` hook); ota-updates' restart
path awaits `crashReporter.flush()` before reloading (that skill owns the step). *Why:* an update's bundle was never built natively, so nothing else uploads it.
10. **The upload token is a build secret.** `SENTRY_AUTH_TOKEN` lives in EAS (secret visibility) or CI
secrets; never in the plugin options, the app config, a committed `.sentryclirc` or
`sentry.properties`; `.env.sentry-build-plugin` is git-ignored. *Why:* the plugin writes an
`authToken` option into the native projects, and the token grants write access to the org.
11. **Tracing is off by default, capped and declared.** `TRACES_SAMPLE_RATE` and
`PROFILES_SAMPLE_RATE` are literals in `src/config/crash-reporting-config.ts`, at most the
contract's `maxTracesSampleRate`, no `tracesSampler`; a rate above 0 declares `performance-data`.
*Why:* tracing multiplies volume and is a separate data type in both stores' declarations.
12. **`contracts/crash-reporting.json` states the facts and the store declarations match them**:
provider, consent model, tracing cap, upload profiles, and `collects` (`crash-data`,
`other-diagnostic-data`, `performance-data`), never linked to the user or used for tracking; the
`@sentry/react-native` rows of `contracts/privacy.json` copy them (`privacy-sync`). *Why:*
privacy-and-store-declarations turns these facts into App Privacy, Data safety and privacy-manifest answers.
13. **The developer owns the Sentry account; prove it on a release build.** Ask for the org, project
and DSN (never invent them), hand over the `eas env:set` commands and server-side settings, and
stop and ask before anything that sends data to their project or changes their account. *Why:*
those are outward-facing actions on someone else's service.
## Workflow
1. **Decide with the developer.** Read [references/privacy-consent-and-scrubbing.md](references/privacy-consent-and-scrubbing.md)
(sections 6 to 9) and agree the consent model, whether tracing is on, the upload profiles and the
org/project slugs. Copy `templates/contracts/crash-reporting.json` (+ schema) and fill the facts.
2. **Install:** `npx expo install @sentry/react-native` (never `@latest`); keep optional dependencies;
rebuild the development client. Details: [references/setup-and-wiring.md](references/setup-and-wiring.md).
3. **Copy the templates** at the paths their first lines name: `templates/src/services/crash-reporter/`
(port, adapter, scrubber, forwarder, fake and the root kit), `templates/src/config/` (the config,
its reader and the DSN's type in `crash-reporting-env.d.ts`), `templates/src/hooks/use-crash-reporting-consent.ts`,
`templates/src/hooks/use-route-breadcrumbs.ts` (each with its test), `templates/scripts/metro/metro-kits.ts`
and `templates/__mocks__/@sentry/react-native.ts`. The root skeleton's slots come from
app-startup-and-bootstrap; set them up with it first.
4. **Register the kit** in app-startup-and-bootstrap's registry `src/services/create-root-kits.ts`
([examples/create-root-kits.ts](examples/create-root-kits.ts)): create the adapter from
`readCrashReportingConfig()` and add `createCrashReportingKit({ crashReporter, consent })` to the
list. The root files stay unchanged: the kit's `forward` reaches the error sink and its effects
(the choice applied after the splash, route breadcrumbs) mount beside the root Stack.
5. **Give the person the choice** ([examples/settings-schema.ts](examples/settings-schema.ts)): add
`crashReportsEnabled` the settings-and-preferences way (default from the consent model) with its
settings row, whose hint says that turning it back on after turning it off applies at the next
launch, and pass the kit a consent source over that field (the example's `settingsCrashConsent`).
Until the row exists, pass `fixedCrashConsent(false)`. Read
[references/error-flow-breadcrumbs-and-tracing.md](references/error-flow-breadcrumbs-and-tracing.md).
6. **Build config** (`templates/scripts/metro/metro-kits.ts`, [examples/app.config.ts](examples/app.config.ts)):
the Metro kit builds the base config with `getSentryExpoConfig` (the canonical `metro.config.js`
composes it and keeps `cacheVersion`); the plugin entry with `organization` and `project`;
`SENTRY_DISABLE_AUTO_UPLOAD=true` only in non-reporting eas.json profiles; append
`&& npx sentry-expo-upload-sourcemaps dist` to every `eas update` script. Read
[references/releases-symbols-and-sourcemaps.md](references/releases-symbols-and-sourcemaps.md).
7. **Hand over the human steps** and stop until the developer confirms: the `eas env:set` commands
(DSN plain text per reporting environment, `SENTRY_AUTH_TOKEN` secret), Sentry's server-side
scrubbing settings, and the declarations for privacy-and-store-declarations (App Privacy, Data
safety, `ios.privacyManifests` entries).
8. **Run the tests:** `npx jest src/services/crash-reporter src/hooks src/config scripts/metro --ci --maxWorkers=2`,
then the app's typecheck and lint.
9. **Run the checker:** `node ${CLAUDE_SKILL_DIR}/scripts/check-crash-reporting.mjs .` (multi-package:
`--app-dir apps/<app>`). Fix every `FAIL` line ([references/testing-and-checker-rules.md](references/testing-and-checker-rules.md)
explains each rule) and rerun until `RESULT: PASS`.
10. **Before the first store release:** the device proof on a preview build and a named simulator andFrom zakariaf/ReactNative-Skills, MIT.
More from zakariaf/ReactNative-Skills
- 0.606score
debug-menu-and-test-hooks
zakariaf
Gates test-only code behind one literal TEST_ONLY switch: debug menu, debug link, simulated clock and offline.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
accessibility-as-code
zakariaf
Enforces a11y labels, 44pt targets, 200% text, VoiceOver, TalkBack.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
adaptive-layout
zakariaf
Lays screens out by window, not device: breakpoints, master-detail panes, readable widths, grids.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
admob-ads-and-consent
zakariaf
Builds AdMob ads behind a port - banners, interstitials, rewarded, UMP consent then ATT, pacing, ADS_MODE test IDs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
analytics-and-consent
zakariaf
Gates analytics on opt-in consent: no SDK before a yes, typed events without personal data, ATT.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
android-release-play
zakariaf
Ships Android App Bundles to Google Play: upload key, Play App Signing, AAB gate, versionCode, tracks, rollout.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
architecture-and-boundaries
zakariaf
Places app code in the src/ layout and checks import boundaries: one-way zones, pure core, ports with fakes, one composition root.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
async-safety
zakariaf
Prevents silent async bugs: effect races, stale results, lost promises, leaked listeners and timers, AbortSignal gaps.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
audio-and-haptics-feedback
zakariaf
Builds SFX and haptics behind ports.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
auth-and-secure-storage
zakariaf
Builds sign-in - tokens in expo-secure-store, shared refresh, protected routes, OAuth PKCE, Apple sign-in.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
background-tasks
zakariaf
Builds expo-background-task jobs: idempotent, budgeted runs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
canvas-gestures-and-hit-testing
zakariaf
Turns canvas taps, swipes, drags and aim into typed intents: one gesture module, hit-testing on the drawn layout.
SkillAFreshness: A★ 11Claude Code +9
Signals
- Stars
- 11
- Forks
- 2
- Open issues
- 0
- Last commit (this folder)
- Oct 17, 2026 (13 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/zakariaf/ReactNative-Skills
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from zakariaf
- 0.606score
admob-ads-and-consent
zakariaf
Builds AdMob ads behind a port - banners, interstitials, rewarded, UMP consent then ATT, pacing, ADS_MODE test IDs.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
accessibility-as-code
zakariaf
Enforces a11y labels, 44pt targets, 200% text, VoiceOver, TalkBack.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
canvas-gestures-and-hit-testing
zakariaf
Turns canvas taps, swipes, drags and aim into typed intents: one gesture module, hit-testing on the drawn layout.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
adaptive-layout
zakariaf
Lays screens out by window, not device: breakpoints, master-detail panes, readable widths, grids.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
debug-menu-and-test-hooks
zakariaf
Gates test-only code behind one literal TEST_ONLY switch: debug menu, debug link, simulated clock and offline.
SkillAFreshness: A★ 11Claude Code +9 - 0.606score
analytics-and-consent
zakariaf
Gates analytics on opt-in consent: no SDK before a yes, typed events without personal data, ATT.
SkillAFreshness: A★ 11Claude Code +9
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get crash-reporting-and-observability running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
crash-reporting-and-observability skill. Agent Mart. https://agentmart.dev/skills/zakariaf-crash-reporting-and-observability (last updated 2026-10-24)