Skip to content

feat(telemetry): outcome vocabulary and transfer metric payloads - #934

Merged
sirahd merged 1 commit into
sira/telemetry-2-clientfrom
sira/telemetry-3-vocabulary
Aug 11, 2026
Merged

sirahd merged 1 commit into
sira/telemetry-2-clientfrom
sira/telemetry-3-vocabulary

Conversation

@sirahd

@sirahd sirahd commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

Part 3 of 6 of the client transfer telemetry stack, split out of #919 for review. Each PR in the stack compiles and passes CI on its own.

Defines what a transfer report contains: the outcome and error-class
vocabulary, the shared identity and common metrics, and the upload- and
download-specific metric sets, with the OpenAPI description of the endpoint
that receives them.

These definitions live in xet_data rather than xet_client because this is the
only layer that can see DeduplicationMetrics and GroupProgressReport.

The outcome vocabulary stays ungated on wasm even though the payloads do not:
it appears in FileDownloadSession's public signatures, and gating it would push
a cfg onto every caller that merely names an outcome.

Nothing emits these yet - the emit path and its session hooks are the next PR.

Review note: xet_data/src/telemetry/mod.rs declares only outcome and payload here. Part 4 adds mod emit; and its re-exports — that file is additive across the two PRs, not replaced.


Note

Low Risk
Additive API spec and library types with no runtime behavior change until a later PR wires emission; schema is guarded by tests but future key/type changes would affect analytics consumers.

Overview
Introduces the client transfer telemetry contract ahead of wiring: OpenAPI documents fire-and-forget POST /v1/telemetry (read scope) with a TelemetryEnvelope whose metrics map is intentionally open-ended and points to Rust as the source of truth.

Adds xet_data::telemetry with a wasm-universal outcome layer (Outcome, stable wire strings, error_class / classify_error over DataError) and non-wasm payload builders that flatten CommonMetrics, UploadMetrics (dedup/shard/ingest timing), and DownloadMetrics from GroupProgressReport, DeduplicationMetrics, and TransferTelemetry snapshots. Payload construction enforces fixed key sets, scalar-only JSON, and finite ratios/rates; tests lock upload/download keys, types, and no-PII rules.

No emission in this PR—only types, serializers, and API spec; the next stack piece hooks sessions to send these documents.

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

Defines what a transfer report contains: the outcome and error-class
vocabulary, the shared identity and common metrics, and the upload- and
download-specific metric sets, with the OpenAPI description of the endpoint
that receives them.

These definitions live in xet_data rather than xet_client because this is the
only layer that can see DeduplicationMetrics and GroupProgressReport.

The outcome vocabulary stays ungated on wasm even though the payloads do not:
it appears in FileDownloadSession's public signatures, and gating it would push
a cfg onto every caller that merely names an outcome.

Nothing emits these yet - the emit path and its session hooks are the next PR.
@sirahd
sirahd marked this pull request as ready for review August 10, 2026 23:05

@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 default 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 a1e7ab7. Configure here.

ClientError::FileNotFound(_) | ClientError::XORBNotFound(_) => "not_found",
ClientError::InternalError(_) => "internal",
ClientError::ReqwestMiddlewareError(_) => "network",
ClientError::ReqwestError(e, _) => reqwest_error_class(e),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Middleware timeouts misclassified

Medium Severity

ClientError::ReqwestMiddlewareError always maps to network, so the timeout path in reqwest_error_class never runs for transport failures. RetryWrapper turns send-time timeouts into middleware errors, so real timeouts are bucketed as network and the closed timeout class stays empty for the main client path.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit a1e7ab7. Configure here.

@sirahd
sirahd merged commit 5ab83e4 into main Aug 11, 2026
10 checks passed
@sirahd
sirahd deleted the sira/telemetry-3-vocabulary branch August 11, 2026 19:52
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.

2 participants