Skip to content

Split platform-induced API calls out of the control telemetry category - #322

Open
archandatta wants to merge 1 commit into
mainfrom
archand/kernel-1870/telemetry-control-platform-split
Open

Split platform-induced API calls out of the control telemetry category#322
archandatta wants to merge 1 commit into
mainfrom
archand/kernel-1870/telemetry-control-platform-split

Conversation

@archandatta

@archandatta archandatta commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Summary

  • every operation in openapi.yaml declares x-telemetry-category; categorygen emits the operation → category map next to the event-type map, so a new endpoint without a classification fails generation instead of landing somewhere silently
  • browser-control operations (computer actions, executePlaywrightCode, screenshot, clipboard) keep emitting api_call under control; VM-management operations emit a new platform_api_call under a new platform category
  • platform is opt-in: in UserCategories, not DefaultCategories, so enabling telemetry without per-category settings now captures strictly less than before
  • BrowserApiCallEventData gains code, recorded for executePlaywrightCode and capped by the same helper and constant as every other captured string
  • operation_id description corrected — the value on the wire is the generated handler name (ProcessExec), and categorygen rejects any operationId that isn't lowerCamelCase, since that assumption is what makes the mapping safe

Why

api_call fired for every documented operation and always landed in control. Most of that traffic is the platform acting on the VM, not an agent acting on the browser: listRecorders polling, profile save and restore (downloadDirZstd, deleteDirectory, processExec), replay lifecycle, telemetry publishing itself. Reading control to see what an agent did meant paging past all of it, and the one event worth reading — executePlaywrightCode — didn't include the code that ran.

Classification calls worth a second look

takeScreenshot and readClipboard/writeClipboard are control: an agent uses them to see and to move data. patchDisplay, chromiumConfigure, patchChromiumFlags and uploadExtensionsAndRestart are platform — browser configuration issued at session setup. processExec is platform even though a customer can call it directly, because it isn't browser control. An operation the generated map doesn't know falls back to platform, so an unclassified route can't dilute the stream callers read to see agent behavior.

Sequencing

control narrows here with no opt-in path back until the control-plane half lands (kernel#3086), so anyone reading control for profile-save or replay calls needs platform after this release. CDP-level control events are #323, stacked on this branch and shipping in the same release. Docs are kernel/docs#474.

Captured-string cap

code reuses what already existed rather than adding a second convention. truncateBody and the 8 KB structured-body cap moved out of lib/cdpmonitor into lib/events as TruncateCaptured and CapturedFieldCap, so response bodies and submitted source now share one helper, one constant and one marker (...[truncated]), and the constant carries the reason for its value: three orders of magnitude below maxS2RecordBytes, so no single field can push an envelope past the record limit and null the whole payload. A clipped value is marked in the string, so truncated on the envelope keeps meaning only what truncateIfNeeded sets it to. The helper had no tests before; it has them now.

Generated handler names

categorygen no longer derives the handler name from the operationId by uppercasing the first letter, which assumed how oapi-codegen spells a name and needed a lowerCamelCase guard to be safe. It now reads the generated ServerInterface, whose methods each document the route they serve, and joins that to the spec on method and path. Nothing about naming is assumed, and generation fails if a classified route has no handler, if a handler has no classification, or if the two counts disagree. The regenerated map is byte-identical to the derived one.

Testing

  • make test-unitgo vet ./... clean, unit suite green
  • test-server-unit green on this commit in CI
  • new: unit coverage for TruncateCaptured (cap, rune boundary, marker, sub-marker caps), for the operation → category map, and for the code cap end to end through the middleware
  • categorygen failure modes exercised by hand: a spec route with no generated handler, an operation with no x-telemetry-category, and a missing handlers file each exit non-zero with the route named
  • e2e not run — needs Docker

Note

Medium Risk
Changes telemetry event types and what lands in control by default; consumers and OTLP pipelines that assumed all API calls were control need to opt into platform and update filters.

Overview
Splits VM-management HTTP traffic out of the control telemetry stream so api_call reflects browser-driving operations only, while a new platform_api_call / platform category covers recording, filesystem, process, and config endpoints.

Each OpenAPI operation now declares x-telemetry-category; categorygen builds an operation → category map from the generated ServerInterface (not derived from operationId), and unclassified routes default to platform so they cannot pollute control. platform is a new opt-in telemetry category (not in default capture). executePlaywrightCode records submitted source on the event via RecordTelemetryCode, using shared events.TruncateCaptured / CapturedFieldCap (also used for CDP response bodies).

Reviewed by Cursor Bugbot for commit 5659a6a. Bugbot is set up for automated code reviews on this repo. Configure here.

@archandatta
archandatta force-pushed the archand/kernel-1870/telemetry-control-platform-split branch 2 times, most recently from 205f61a to f22b32a Compare August 7, 2026 12:33
Every documented operation emitted api_call under `control`, so the
platform's own traffic — recorder polling, profile save/restore, telemetry
publishing — buried the agent's browser actions.

Operations now carry `x-telemetry-category` in openapi.yaml and categorygen
emits the operation -> category map alongside the event-type map, so a new
endpoint without a classification fails generation. Browser-control calls
keep emitting api_call under `control`; VM-management calls emit
platform_api_call under a new `platform` category, which is opt-in and out
of the default set.

api_call data also gains an optional `code` field, recorded for
executePlaywrightCode and clipped to 8 KB on a rune boundary, so the event
says what actually ran.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@archandatta
archandatta force-pushed the archand/kernel-1870/telemetry-control-platform-split branch from f22b32a to 5659a6a Compare August 7, 2026 13:43
@archandatta
archandatta marked this pull request as ready for review August 7, 2026 13:43

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 5659a6a. Configure here.

{events.Page, b.Page},
{events.Interaction, b.Interaction},
{events.Control, b.Control},
{events.Platform, b.Platform},

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Platform-only config disables middleware

High Severity

The TelemetryHTTPMiddleware is currently only enabled when the control telemetry category is active. Since platform_api_call events, now part of the platform category, rely on this middleware, enabling platform without control means these events won't be collected or published.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 5659a6a. Configure here.

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.

1 participant