docs: move AI SRE tab before On-call in top navigation - #287
Merged
Conversation
Electron is the first RUM platform that requires a two-process
integration: `@flashcatcloud/electron-sdk` in the main process and
`@flashcatcloud/browser-rum` in renderers, bridged over IPC through the
`DatadogEventBridge` object that dd-trace injects via preload. Integrating
only one side is the failure mode these pages are written to prevent.
Adds four pages per language under `rum/sdk/electron/`, mirroring the
harmony/flutter page set, and registers the group in docs.json for both
languages:
- sdk-integration: install, the `instrument` entry point that must precede
`require('electron')`, bundler plugins (vite / webpack / esbuild), renderer
setup, and the `allowedWebViewHosts` allowlist that gates the bridge
- advanced-config: full init options, batching, proxy, manual reporting,
operation monitoring, source map upload
- compatible: support scope and v1 limits
- data-collection: per-process event types, fields, session rules, upload
behavior
Content is derived from the SDK source rather than upstream Datadog docs,
since the fork changed intake URL rules, the site allowlist, and dropped the
spans track.
v1 limits documented explicitly: no native crash symbolication (crashes are
stored and shown as raw addresses), no Session Replay, no APM/distributed
tracing, and no source map resolution for main-process stacks. The
`file://` install-path instability that breaks source map matching for
`loadFile()` builds is called out with the custom-protocol workaround.
Doc paths match the console's `utils/docs.ts` mapping for the electron
platform. Package versions are left unpinned, per npm platform convention.
Verified with `mint broken-links`.
Two factual errors from the first commit, both found by W1's staging smoke
test and confirmed against the source.
1. The bridge is not opt-in. The earlier text read `validateAllowedWebViewHosts()`
returning `[]` for `undefined` as "the bridge is disabled by default", but
that is the SDK-side config default, not the allowlist the browser SDK
actually sees. dd-trace's preload builds it as:
const allowedHosts = [...new Set([location.hostname, ...configuredHosts])]
The window's own hostname is always included, so a window's own page always
self-matches and the bridge works with no configuration. `file://` included:
`location.hostname` is `""` there, the allowlist becomes `[""]`, and
`canUseEventBridge("")` still matches. `allowedWebViewHosts` is for
additional third-party hosts in `<webview>` / `BrowserView`, not a switch.
2. Bridged renderer events keep `source: browser`. `Assembly.assembleRendererRumEvent()`
overrides only `session.id` and `application.id` and adds
`container.{source, view.id}` — the renderer's own `source` is preserved.
Main-process events are `source: electron` with
`view.url: electron://main-process`. Filtering on `source:electron` alone
therefore returns main-process events only; the correct filter is
`source:electron OR container.source:electron`.
Changes:
- Replace the "enable the bridge" sections with "the bridge needs no
configuration" plus a "what a broken bridge looks like" section, since the
real failure mode is a missing preload injection (main process not
integrated, or bundled without the plugin), diagnosable via a missing
`container.source`
- Add a source/container.source/view.url table to both the integration and
data-collection pages, and correct the verification steps to use the OR filter
- Drop `allowedWebViewHosts` from the basic init examples; it is not needed
- Decouple the `app://` custom-protocol recommendation from the bridge. It now
stands only on source map path stability, with an explicit note that the
bridge works fine under `file://`
- Mark the `file://` install-path limitation as affecting source map
resolution only, not collection
- Align the proxy section with the README: `site` stays required but is unused
for URL building once `proxy` is set, and name the self-hosted use case
Verified with `mint broken-links`.
Fiona settled the open question: normalize stack paths in `beforeSend`. This is not a new proposal — it is the workaround already given to customers — so the section states it directly rather than weighing alternatives. Restructures the source map section around the matching rule, in her framing: the uploaded minified prefix and the path in the stack must correspond. That resolves into two steps, and the whole section is organized around them: 1. Run the CLI where the source maps are and declare a prefix with `--minified-path-prefix` 2. Rewrite the stack path in the renderer's `beforeSend` to align with it Both halves are shown as copy-pasteable code, and the prefix is lifted into a `MINIFIED_PATH_PREFIX` constant so the two places that must agree are visually obvious, with a warning naming them as the only coupling point. Adds a "why the second step is needed" table: stack frames carry the runtime install path, which is unknowable at build time — the macOS install location is the user's choice, Windows embeds the user name, and Linux AppImage mounts somewhere new on every launch. Uploading an install path as the prefix would match exactly one machine. The regex was checked against the real stack shapes measured during the W5 verification (`at r @ file:///…/dist/renderer.js:1:21`), for all three platforms; `[^\s()]*?` rather than `\S*?` so a V8-format frame keeps its enclosing paren. The `app://` custom protocol drops to an optional tip under "when normalization is unnecessary", alongside dev-server and remote-page setups whose paths are already stable. It no longer leads, since `beforeSend` solves the same problem without asking anyone to restructure page loading. Main-process stacks are stated as unsupported for v1 across all six affected pages: they are raw V8 format and the backend parser extracts zero frames. Verified with `mint broken-links`.
v1 drops the hardcoded site allowlist: `site` becomes optional, defaults to `browser.flashcat.cloud`, and is only checked for non-emptiness. The docs no longer tell self-hosted users to pass a SaaS host as a placeholder and route everything through `proxy`. Self-hosted now splits into two cases, which is the part worth getting right: - HTTPS intake: just set `site` to your own domain, no proxy involved - Plain-HTTP intake: `site` cannot help, because the upload URL is built from the template `https://<site>/api/v2/rum` and the scheme is hardcoded. This needs `proxy` That second case is easy to miss once the allowlist is gone — removing it looks like it unblocks arbitrary endpoints, and it does not. It is called out in all six affected pages: as a note under the `site` parameter, as its own "when a proxy is required" subsection, and as a row in the limits table. Also aligns two details with decisions from the release work: - The console special-cases the synthetic main-process view and hides the performance section, so LCP/FCP no longer render as zero. Noted where the docs explain that the main process has no Web Vitals - Section renames moved four anchors; all inbound links updated Verified with `mint broken-links`.
…e, crash resilience Review of PR#1..#5 on `origin/publish`, which landed after these pages were written. Three capability changes and one stale claim. Main-process stacks are now symbolicatable. `ErrorCollection.formatError()` runs `toStackTraceString(computeStackTrace(error))`, so main-process stacks come out in the backend's `at <fn> @ <url>:<line>:<col>` frame format instead of V8's native shape, and frame URLs are the absolute paths of the bundled main-process code — the same key source map upload uses. The docs said the opposite in six places; all corrected, and users are now told to upload the main-process bundle's source maps too. Two caveats kept, because they are still true and easy to over-read: - Native crash stacks remain address-based and unsymbolicated - `beforeSend` is a renderer-only hook, so main-process path normalization depends on the install path being predictable. Called out in advanced-config and in the limits table rather than left implicit `ProcessGoneCollection` was entirely undocumented. Added a data-collection section and a compatibility row covering `render-process-gone` / `child-process-gone`: the full `meta` shape, `is_crash: false` and why (the host app is alive, and the backend escalates every `is_crash` to a critical alert), the absence of a stack, `container.view.id` attribution for renderers, and the deduplication rule — dump-producing reasons (`crashed`, `oom`) are left to crash collection, `clean-exit` is silent, everything else including `killed` is reported. Crash collection degradation: dumps with no exception stream are now reported with threads and binary images rather than dropped, and dumps are deleted whether or not parsing succeeded. Both documented, with the field table noting which values go missing. dd-trace's instrumentation telemetry is off by default. Documented because it is a network-behavior fact worth knowing (`127.0.0.1:8126`, and a direct Datadog fallback when `DD_API_KEY` is set), including that it is controlled by environment variable — `telemetry: false` on `tracer.init()` is silently ignored on dd-trace 5.x — and that an explicit host setting is preserved. Re-verified the `site` changes from the previous round against `config.ts`: optional, `DEFAULT_SITE`, non-empty validation only. Already accurate. The source map section keeps "why the second step is needed" as its own subsection, so the `beforeSend` flow can be demoted to an alternative once SDK-side path normalization lands without restructuring the page. zh/en section counts match on all four pages. Verified with `mint broken-links`.
…c correction Two capabilities landed on the SDK's publish branch that the Electron docs did not cover. `correctPrewarmedViewTimings` (boolean, default true): a new section explains why a window created with `show: false` and navigated ahead of time reports an FCP/LCP inflated by the whole pre-warm interval, the activationStart formula the correction applies, and a table of exactly when it fires — including the two cases that surprise people: metrics are discarded for a window that was never shown, and nothing happens for WebContentsView / <webview>. `normalizeStackPaths` (boolean, default true) and `normalizeStackPath` (callback): stacks from both processes now anchor on the application root as `app:///<relative path>`, so the source map section is restructured around "upload with the matching prefix" instead of the previous two-step recipe. Added the table of which path shapes are and are not rewritten, and made the prefix derivation explicit (app:///dist/x.js -> /dist), including the separate uploads main-process and renderer bundles need. The manual `beforeSend` rewrite is demoted from required step to an optional advanced path, with the cases that still need it and a warning that a hand-written regex typically covers a single platform and fails silently elsewhere. It is kept working: the built-in normalization is a strict no-op on already-relative paths. Also removed the two limits these features close (file:// source map matching, main-process path normalization) and replaced them with the honest ones that remain (code outside the app root, BrowserWindow-only visibility tracking). Verified with `mint broken-links` plus an anchor cross-check; zh/en heading structure is identical line for line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…m, not empty The /status-page/info operation's 200 response schema referenced EmptyResponse for the data field, contradicting the operation's own example (which shows the full status-page object: page_id, name, url_name, components, sections, subscription, ...) and the actual server response. /status-page/list already uses StatusPageItem for the same object shape. Downstream typed-SDK generation consumes this spec, so the wrong ref was producing an untyped/void return for a call that actually returns data.
…m, not empty (zh on-call) Same defect as the other three spec files, in the zh on-call module: the /status-page/info operation's 200 response referenced EmptyResponse for data instead of StatusPageItem.
fix(api-reference): status-page info response schema is StatusPageItem, not empty
Version references, four behavior changes, and five previously undocumented APIs had drifted since the 0.2.0 docs. Versions: module dependency examples, the stated module version, the upload User-Agent, and the sdk_version tag now read 0.3.1; the plugin's pluginVersion default is 0.1.2. Behavior: - Consent is owned by the application — the value passed to initialize wins on every launch. Persistence is documented only as what the deferred-upload extension process reads, and revocation now also deletes already-collected batches. - setTrackNetworkRequests(false), the default, only started disabling resource capture in 0.3.0; callers who relied on the old ignored-toggle behavior must opt back in. - error.stack carries frames only. - Upload bodies are deflate-compressed, and connectivity.status is real now (connected / not_connected / maybe with interfaces) instead of always unknown. - hvigor-plugin below 0.1.2 uploaded the previous build's symbols under the new version number. APIs: setTrackErrors, stopSession, getAttributes, clearAttributes, and initializeForDeferredUpload — the last with the extension-process contract that makes flushAndWait actually deliver. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The pre-0.3.0 behavior was a bug — the toggle was accepted and ignored — so the docs should not tell readers how to opt back into it. The configuration table already states the real contract and its default. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Same reasoning as the setTrackNetworkRequests note: the pre-0.1.2 ordering was a bug, not a documented behavior readers need migration guidance for. The pluginVersion default stays, since that is a current fact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bump the module version, upload User-Agent, and sdk_version tag to 0.3.2, and document the one behavior change the release ships. 0.3.2 attributes faults the SDK cannot observe in-process — native signal crashes and freezes — to the session and view the app actually died in, instead of replaying them into the live post-restart session at replay time. Adds a "crash attribution" section covering the view snapshot that backs it, the two documents written on replay, the retry-on-partial-write contract, and the three fallback cases (snapshot older than the 4h max session lifetime, fault older than 23h, no snapshot available), plus the crash.crashed_at_ms attribute that carries the real fault time on the fallback path. Consent revocation now also deletes that snapshot — it is a whole view event, user fields and custom context included — so the privacy section says so. hvigor-plugin stays at 0.1.2; 0.3.2 did not touch it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
docs(rum): sync HarmonyOS SDK docs to 0.3.2
…OS network tracking The network integration section explained the rcp interceptor and the FlashcatHttp wrapper but never mentioned that both need `setTrackNetworkRequests(true)`, which defaults to false. Readers who followed only that section got no resource events and had no hint why. The view and tap sections already state their own toggles, so this brings the network section in line. Also note that plain `http.createHttp()` is not hooked, and mark the manual resource API as unaffected by the toggle — it bypasses the bus path the toggle gates.
End-to-end validation surfaced three integration mistakes that produce no error at all — the app keeps running, the SDK stays quiet, and only the data is missing. Document each with its symptom, why it stays silent, and the fix: - CSP silently kills Session Replay. Recording creates a blob Worker in the renderer and posts segments straight to the intake, so a common `script-src 'self'` policy blocks the whole pipeline: `session.has_replay` stays 0 with no segments, indistinguishable from never enabling recording. Requires `worker-src blob:` plus the intake origin in `connect-src`. - Source map `--release-version` must match the renderer's `version`. Renderer events take `version` from `flashcatRum.init()` only; the main-process `init()` value never reaches them. A mismatch resolves nothing and reports nothing. - Replay segments are lost during a network outage. They bypass the main-process disk-backed retry, and the browser transport only queues a retry when `navigator.onLine === false`, so an unreachable intake on a live network drops them outright. The first segment after recovery carries no full snapshot, leaving a garbled stretch in playback. Session Replay is documented as supported (via `sessionReplayDirectUpload`) in place of the previous "not supported" entries, since both replay pitfalls depend on it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The Electron pages claimed replay segments produced "during a network outage" are lost permanently and never resent. That is not what the browser SDK does, and the sentence reads as a data-loss warning far broader than the real behavior. `sendWithRetryStrategy` keeps a 3 MiB in-memory queue and resends with exponential backoff up to one minute. `shouldRetryRequest` queues on 408, 429, 5xx, or on `status === 0 && !navigator.onLine`. So a genuine outage — adapter down, Wi-Fi off, cable pulled — is queued and resent on recovery. What is dropped on the spot is the case where the machine is online and the intake is not reachable: a blocked request, a down intake, a DNS or proxy failure. `navigator.onLine` is `true` there, so nothing is queued and no error event is produced. The round-4 e2e observation behind the original text cancelled requests through Electron's `webRequest` (`ERR_BLOCKED_BY_CLIENT`) while the machine stayed online — the second case, not an outage. Rewritten as a behavior boundary rather than a warning, with the two cases in a table, and renamed to "the intake is unreachable" in both languages. Cross-references in `compatible` and `data-collection`, the pitfalls table, and the bridge comparison row follow. Also records that the retry queue is in memory and does not survive process exit, which the previous text did not mention. zh and en carry the same structure line for line.
RumApplicationItem.created_at / updated_at are documented as "Unix epoch seconds", but POST /rum/application/list returns 13-digit millisecond epochs. Verified against the live API: 1747275529568 reads as 2025-05-15 in milliseconds, and as the year 57338 in seconds. Anything that trusts the description gets nonsense dates. go-flashduty derives its Go types from these descriptions and typed the fields as seconds because of this line (fixed there in PR #51, which will regress on the next spec sync unless this lands). Corrected in the rum split files that Mintlify serves and in the consolidated copies that go-flashduty and Apifox import. Description text only; no structural change, EN/ZH parity preserved.
…amp-unit fix(api): RUM application timestamps are milliseconds, not seconds
Covers product changes from the past five days across AI SRE, Monitors and RUM. - ai-sre/artifacts: document public (anonymous) artifact sharing — account-only vs public-link visibility, the content-snapshot model, update/revoke, and the 16 MiB cap; broaden publishable file types well beyond HTML/Markdown; correct the card type icon and title truncation - ai-sre/environments: add the degraded Runner status, its two detection signals and recovery paths, and note that degraded Runners stay selectable - ai-sre/knowledge: replace the extension allowlist with the content-based UTF-8 text rule; narrow the document-conversion list to the modern Office formats and call out legacy .doc/.xls/.ppt rejection - ai-sre/sessions: subagent/A2A child sessions are viewable read-only through a shared root link (no fork); forked dispatches always show as interrupted; HTML attachments - ai-sre/insight: entry kind scheduled -> automation, matching sessions.mdx - monitors/targets: new ServiceMap page (topology canvas, node/dependency detail fields, unresolved endpoints, host list, evidence quality) - monitors/quickstart: the data source type picker lists only configured types - rum/error-tracking: the Issue count on an application card deep-links into the error tracking list with the card's own scope
- changelog: new 2026-08-06 entry covering the artifact public-link sharing mode (snapshot semantics, update/revoke, 16 MiB cap), the broadened set of publishable artifact types, and the ServiceMap topology feature - monitors/targets/servicemap: mark the page as Beta and state the monit-agent eBPF dependency up front
…rift
Publishes 23 endpoints and corrects five places where the reference no
longer matched how the service behaves.
New endpoints
- Monitors / Service map (5): status, topology, summary, fleet and
fleet/summary. The subsystem is optional, so each page states that a
deployment without the ServiceMap store configured answers
ServiceUnavailable (503).
- RUM / Error ingestion rules (8) and Issue preset severity rules (9):
list, create, update, delete, enable, disable, reorder (severity rules
only) and the history list/revert pair.
- RUM / Resources (1): resource/info.
Corrections
- /incident/work-item/list no longer requires the On-call Pro license, so
that note is dropped. The work-item mutations stay Pro-gated.
- /incident/comment-type/{create,update,delete,reorder} are gated by the
new Comment Types Manage permission rather than Incidents Manage;
holding only the latter is rejected. The read path is unaffected.
- /member/info/reset gains the `from` field, which marks an updated phone
or email as verified when the account has member invites disabled, and
now rejects an empty `updates` object.
- /rum/facet/list is removed. It has had no backend route since the facet
model was replaced by fields, and it is no longer registered on the
gateway, so every documented call 404s. The usage note on
/rum/facet/count now points at /rum/field/list, its replacement.
- The consolidated specs were missing the AlertRule family's `timezone`
property and the cron_pattern note that goes with it. Both are synced
from the per-module spec so an exported rule keeps its timezone.
Also backfills two catalog rows for endpoints that shipped without an
index entry (post-mortem content reset, on-call license list), and stops
the generator emitting "1 requests/second" for a rate limit of one.
Review tip: the consolidated spec renders as 18 hunks with
`--diff-algorithm=histogram`, versus 4174 with the default.
…0806-014513 docs: sync doc-review findings (2026-08-06)
- error-ingestion and preset-severity `rules/delete` said the rule stops being evaluated immediately. The enabled-rule set is cached for up to 5 seconds — the same lag already documented for enable/disable. - preset-severity `rules/reorder` said only rules strictly between the two original positions shift. The target rule shifts as well. - preset-severity `rules/history/list` said a snapshot is written before every update call. An update carrying none of the mutable fields writes none. - preset-severity `rules/create` declared `minItems: 1` on `filters`, which the server does not enforce: an empty array is accepted and yields a rule that can never match. Drop the constraint and state the real behaviour instead. - `resource/info` said `no_cache` recomputes the session usage counts. It bypasses the cache of the resource record; the counts come from a separate hourly cache the flag does not touch.
docs(api): publish ServiceMap and RUM rule endpoints, fix reference drift
…0260806 docs(api): publish ServiceMap and RUM rule endpoints
Each of these contradicted itself on the rendered page: - ServiceMap fleet: the response showed a single `active` host for a request filtering on `degraded`/`stale`, while `coverage` claimed two returned and counted one of each. Now two hosts that match both the filter and the counts. - Preset-severity: the rule returned by `create` carried a priority the `list` example contradicted, and the history example's "empty" snapshot was timestamped after a rule that already existed. Rebuilt as one timeline — two creates and a disable, three snapshots, each holding the state the call that wrote it was about to change. - History `total` now equals the number of items returned, in both the preset-severity and error-ingestion examples. - Resource info: the order id encoded a date a year after the `created_at` of the resource it provisioned, and the billing window was not the 30-day span anchored at `created_at` that the field descriptions promise. - Example addresses now use the RFC 5737 documentation range, which the rest of the corpus already uses, instead of private-range ones. Examples feed no code generation — only the request-side ones reach the CLI, and none of those change here — so the generated SDK and CLI are unaffected.
docs(api): make the reference examples internally consistent
…0260806 docs(api): make the reference examples internally consistent
…template fix(docs): escape entity tree template placeholders
…rs preview/quickstart, changelog
docs: doc-review 2026-08-17 (monit-query data, op counts, monitors preview/quickstart, changelog)
The HarmonyOS SDK expressed upload pacing as a millisecond setter while the Android, iOS and Flutter SDKs used three enums, so this page taught a vocabulary readers could not carry to the other platforms. SDK 0.5.0 adopted the shared enums and removed the millisecond setter, leaving the page documenting a method that no longer exists. Replace it with UploadFrequency, BatchSize and BatchProcessingLevel, and record the two defaults that moved so readers upgrading from 0.4.0 can see them without diffing the changelog. BatchProcessingLevel is new; the table says what it is for, since bounding an upload burst is the reason to reach for it.
… exclusion, entity-tree interactions, changelog)
docs: doc-review 2026-08-18 (k8s app permissions, quick-silence label exclusion, entity-tree interactions, changelog)
…ching docs(rum): document the HarmonyOS batching configuration
An app that makes latency-sensitive requests of its own can see its own p95 rise once RUM is enabled, because SDK uploads compete for the uplink. The performance pages framed SDK cost only as CPU, memory, battery and bundle size, so a reader hitting this had nothing to act on: the Android page's "configure the reporting strategy" step was a single sentence with no code, and the equivalent settings went unmentioned on iOS. Give each platform the concrete recipe. Android, iOS and HarmonyOS share uploadFrequency, batchSize and batchProcessingLevel under the same names and values, so each page states the defaults, the suggested values and what each one changes, and points out the one divergence: iOS .low is 5 batches per cycle where Android and HarmonyOS use 1. These three settings drop no events, which is worth saying next to the options that do. Web has no upload cycle to tune -- batches live in an in-memory queue on the main thread -- so its page says so explicitly and covers what does apply there instead: compressIntakeRequests, which is off by default and the only platform where compression must be enabled by hand. HarmonyOS gets the inverse table, since vitals, long tasks and internal telemetry have no implementation there and readers arriving from Android will look for the switches. Also correct two Android snippets that could never have compiled: trackUserInteractions takes an array of attribute providers rather than a boolean, so disabling it is disableUserInteractionTracking(), and trackLongTasks takes a millisecond threshold where any value <= 0 turns tracking off.
The Chinese page tells a reader upgrading from 0.4.0 that setBatchUploadFrequencyMs is gone and that two defaults moved with it; the English page dropped straight into the new API, leaving an English reader to diff the changelog to find out why their millisecond setter stopped compiling and why uploads got more frequent without them changing anything.
The cross-platform note ended by telling the reader that the Web SDK has no equivalent settings, and linked to the Web page. A reader on the Android performance page is integrating Android; what Web cannot do is not something they can act on, and the link invites them away to a platform they are not using. The sentence was there to finish an enumeration, not to serve anyone. The Web page already carries this for the reader it belongs to: someone who arrives looking for the mobile tuning settings and needs to be told they do not exist. Keep it in that one place.
…n-tuning docs(rum): document how to keep RUM uploads off a narrow uplink
The zh/en API Reference tabs are marked hidden:true, and Mintlify automatically applies robots noindex to every page under a hidden tab and drops them from sitemap.xml. That keeps all ~674 generated endpoint pages (337 operations x 2 languages) out of search engines even though they are served publicly and linked from the API catalog pages. Set seo.indexing to "all" so hidden pages are indexed and included in the sitemap while the tabs themselves stay out of the navigation, per https://mintlify.com/docs/organize/hidden-pages.
docs: enable search indexing for hidden API reference tabs
…nks, email limit, ai-sre updates
docs: doc-review 2026-08-19 — incident timeline, alert detail deep links, email limit, ai-sre updates
Document the two-layer pattern behind "keep volume near 20% but never drop an error": collect every session so errors are never sampled out, then bucket sessions by session ID inside beforeSend so only 20% of them keep full resource, action and long-task data. Error events and failed requests are always kept. Bucketing must be deterministic on the session ID rather than random, or events within a single session are half kept and half dropped, leaving a broken picture during investigation. Also covers the trade-offs: view events cannot be dismissed so volume never lands exactly on the target, absolute counts need scaling while ratios and percentiles stay valid, and Session Replay draws independently from this bucket.
…ation The previous warning stated the mechanism (events within one session get half kept, half dropped) but not why it matters, which reads as though random sampling were statistically wrong. It is not: a per-event draw is an unbiased sample and aggregates stay accurate. Rewrite it around the actual failure: allow-listed errors and failed requests survive while the click that caused them loses its draw, so the session reads as "user did nothing, then a request failed". The gaps land somewhere different in every session, so a missing click cannot be distinguished from a click that never happened, and the session stops being usable as evidence. Also document bucketing by user as an option, falling back through usr.id, usr.anonymous_id (maintained by the SDK, trackAnonymousUser defaults to true) and session.id. It gives a stable per-user experience and genuine monotonicity when scaling the rate up, at the cost of a fixed sample whose device and geography characteristics bake into the metrics.
…sions
Two gaps in the event-level sampling recipe.
Session Replay drew independently, so a session could carry a replay yet
have no behavior data behind it. Document both ways to align it: with
user bucketing, feed the same boolean to sessionReplaySampleRate; with
session bucketing the ID does not exist at init() and the replay rate is
frozen there, so set the rate to 0, enable manual recording and call
startSessionReplayRecording({ force: true }) for sessions in the bucket.
Note the boundary — a session renewing on a long-lived page lands in a
new bucket and the SDK exposes no renewal event.
Unsampled sessions also have an inherently incomplete timeline, and a
reader could not tell a dropped click from a click that never happened.
Stamp every surviving event with a rum_sampling marker inside the same
beforeSend that makes the drop decision, so the two cannot drift; context
is an allow-listed modifiable field. Investigations can then filter for
full sessions and read gaps in errors-only sessions correctly.
The previous text called sessionReplaySampleRate an independent draw. It is not: computeSessionState chains the two, and the replay draw only runs for sessions that already passed sessionSampleRate, so natively a session with a replay always has complete data behind it. State the actual cause of the misalignment instead. This recipe sets sessionSampleRate to 100 and moves the real sampling into beforeSend, so the SDK believes every session is fully collected and draws replay across all of them — some of which fall outside the detail bucket. Restore the second-stage semantics rather than overriding them: feed the bucket into sessionReplaySampleRate so replay is drawn within detail sessions only, giving DETAIL_SAMPLE_RATE x REPLAY_SAMPLE_RATE overall, the same 2% that native 20/10 produces. The session-bucketing variant performs the second draw itself with a salted key.
The FAQ entry had grown to 142 lines with four code blocks — 1.7x the length of best practice 2 and roughly seventy times the other FAQ entries. An accordion is meant for a short answer: at that size readers cannot scan it, it stays out of the page outline, and its subsections have no anchors to link to. Promote it to "best practice 3", turning its bold labels into real subheadings so user bucketing, replay alignment and the trade-offs each get an anchor. The FAQ keeps a two-line entry that states the constraint and links to the section, preserving the question-shaped entry point. Also retarget the closing pointer in "can I report only errors" — best practice 3 is the closer fit for "errors first, but keep the evidence" than the always-sample cohort suggestion it referenced before.
Three leftovers from when this content was a FAQ accordion. The replay bullet packed four causal steps into one sentence with no connectives and read as a garden path. Spell the chain out: the recipe sets sessionSampleRate to 100, so the SDK believes every session is fully collected and draws replay across all of them; skipping the alignment step lands replay on sessions outside the bucket. That bullet also sat under "three trade-offs" even though the section right above it gives the fix, which reads as a contradiction. It is a required step, not a cost — retitle the list to "three things to know". The closing paragraph compared this against "the previous question", which no longer sits above it. Name the configuration it contrasts with instead.
…format State that outbound A2A delegation implements A2A Protocol 1.0, add a minimal 1.0 Agent Card example, note that the card's version field is the agent's own version, and summarize the 0.x to 1.0 card migration (supportedInterfaces, securitySchemes/security).
…d tabs - Split session vs user bucketing into two fully self-contained tabs, each with the complete init + beforeSend recipe and its own replay alignment, so readers follow one path end to end - Replace the prose bucketing-choice guidance with a comparison table - Fix the usr.id description: the SDK backfills the anonymous ID into usr.id by default (trackAnonymousUser), it does not require setUser() - Document the init-time key availability constraint for replay alignment under user bucketing, and recommend a business-held key (getCurrentUserId() || getOrCreateAnonId()) in both places
…-error-capture docs(rum): add best practice 3 — full error capture with proportional sampling
docs(ai-sre): document supported A2A protocol version and Agent Card format
This was referenced Aug 19, 2026
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.
Reorders the top navigation tabs in
docs.jsonso AI SRE appears right after Home, before On-call — for bothzhandenlocales.New order: Home → AI SRE → On-call → RUM → Monitors
Pure block move (+104/−104, no content changes);
mint broken-linkspasses.