Skip to content

docs: move AI SRE tab before On-call in top navigation - #287

Merged
ysyneu merged 118 commits into
feat/ai-srefrom
docs/ai-sre-tab-first
Aug 19, 2026
Merged

docs: move AI SRE tab before On-call in top navigation#287
ysyneu merged 118 commits into
feat/ai-srefrom
docs/ai-sre-tab-first

Conversation

@ysyneu

@ysyneu ysyneu commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Reorders the top navigation tabs in docs.json so AI SRE appears right after Home, before On-call — for both zh and en locales.

New order: Home → AI SRE → On-call → RUM → Monitors

Pure block move (+104/−104, no content changes); mint broken-links passes.

Fiona2016 and others added 30 commits July 28, 2026 08:55
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
UlricQin and others added 26 commits August 17, 2026 12:30
…template

fix(docs): escape entity tree template placeholders
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
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
@ysyneu
ysyneu merged commit bbb4fbc into feat/ai-sre Aug 19, 2026
1 check passed
@ysyneu
ysyneu deleted the docs/ai-sre-tab-first branch August 19, 2026 12:04
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.

4 participants