splitchAlpha

DocsSDKsentry.md

Sentry.

Feed both halves of Sentry's suspect-flag detection: change tracking and evaluations.

Sentry's feature-flag support has two independent halves, and its suspect-flag detection ("this Flag flipped four minutes before this error spike") only works when both are fed. Change tracking is server-side and needs no code. Evaluation tracking is a one-line option on your client.

HalfDirectionWhere you set it up
Change trackingsplitch → SentryControl Panel, once per Organization
Evaluation trackingyour app → Sentry@splitch/sdk/sentry in your app

Set up change tracking first. An evaluation-tracking-only install shows Flags on the error event but has nothing to correlate them against.

Change tracking

Sentry's Generic provider form has no "generate secret" button: it asks the provider to supply one. splitch is the provider, so splitch mints the secret and you paste it back. The exchange is two copy-pastes, in this order:

  • Copy the webhook URL out of Sentry's **Settings → Feature Flags → Change Tracking → Add New Provider** form.
  • Paste it into **Organization → Integrations → Sentry change tracking** in the Control Panel and press **Connect Sentry**. The minted signing secret appears once, the same treatment an API Key gets.
  • Paste that secret into Sentry's Secret field and save.

One installation binds one splitch Organization to one Sentry organization and carries every App and Environment under it. That is Sentry's shape, not a simplification of ours: Sentry keeps a single signing secret per provider type per organization, so two Environments wiring up the same Sentry organization would each mint a secret and the second would silently invalidate the first.

The table below the form carries delivery health, **Rotate secret** for when Sentry's copy is lost or compromised, and **Disconnect**, which revokes the installation and stops delivery. Regional hosts (us.sentry.io, de.sentry.io) are accepted. Every operation is also available on the CLI and over MCP, so an agent can wire this up too.

Evaluation tracking

npm install @sentry/core

@splitch/sdk/sentry keeps @sentry/core external rather than bundling it, because a second bundled copy would not share a client with the one your app already initialized. Add Sentry's own integration first, then pass the reporter to the SDK's `onResolution` hook.

import * as Sentry from "@sentry/browser";
import { createSplitchClient } from "@splitch/sdk";
import { sentryResolutionReporter } from "@splitch/sdk/sentry";

Sentry.init({
  dsn: "...",
  dataCollection: {
    userInfo: false,
    cookies: false,
    httpHeaders: false,
    httpBodies: [],
    urlQueryParams: false,
    genAI: { inputs: false, outputs: false },
    graphQL: { document: false, variables: false },
    databaseQueryData: false,
    queues: false,
    stackFrameVariables: false,
    frameContextLines: 0,
  },
  integrations: [Sentry.featureFlagsIntegration()],
});

const splitch = createSplitchClient({
  clientKey: "pk_...",
  onResolution: sentryResolutionReporter(),
});

Every resolution the real user path produces now lands in Sentry's flag context, so an error event carries the Flags that were active when it happened. peekVariant and verify are never reported: they fire no Exposure, and recording them would claim a resolution the user never received.

How a Variant is encoded

Sentry's flag buffer stores { flag, result: boolean } and its addFeatureFlag is a documented no-op for any other value type. That single constraint drives the mapping:

  • A boolean resolution passes straight through as new-checkout = true.
  • A multivariate Flag becomes one boolean per served Variant: checkout:treatment = true. Two Variants of the same Flag never collide because the Variant is part of the name.
  • An ERROR resolution is not recorded. The Default Variant was served because evaluation failed, and claiming it as a resolution would be exactly the disguised default splitch refuses.
  • A non-boolean resolution with no Variant name cannot be encoded at all, so it is logged through your logger once per Flag Key rather than dropped silently.

If Sentry's featureFlagsIntegration() is missing from Sentry.init, the reporter says so once per Flag Key with the remediation attached, rather than discarding resolutions into a sink that is not there.