Uh oh!
There was an error while loading. Please reload this page.
Expose telemetry through Rust SDK, C ABI, and .NET binding - #821
Expose telemetry through Rust SDK, C ABI, and .NET binding#821RamonArjona4 wants to merge 60 commits into
Conversation
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
|
Azure Pipelines: There may be pipelines that require an authorized user to comment /azp run to run. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Pull request overview
Exposes telemetry consent, policy, and per-run enablement through the Rust SDK and C ABI.
Changes:
- Adds typed Rust telemetry APIs.
- Adds panic-safe C ABI consent and policy entry points.
- Propagates telemetry settings and expands tests/codegen checks.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
src/ffi/mxc_ffi/src/streaming.rs | Propagates telemetry into streaming requests. |
src/ffi/mxc_ffi/src/lib.rs | Adds telemetry ABI and tests. |
src/ffi/mxc_ffi/Cargo.toml | Adds telemetry test support. |
src/core/mxc-sdk/src/telemetry.rs | Implements the Rust telemetry facade. |
src/core/mxc-sdk/src/lib.rs | Exports the telemetry module. |
src/core/mxc-sdk/README.md | Documents telemetry APIs and usage. |
src/Cargo.lock | Records the test dependency. |
scripts/check-dotnet-bindings-codegen.js | Verifies generated telemetry entry points. |
Suppressed comments (1)
src/ffi/mxc_ffi/src/lib.rs:622
- This new ABI entry point manually constructs a stable JSON contract, but no FFI-level test invokes it. Add a test that asserts every returned field (including
reason: nullwhere applicable), checks the platform-specific values, and frees the returned string; otherwise field omissions or ownership regressions can pass unnoticed.
pub unsafe extern "C" fn mxc_telemetry_get_consent_status(out_utf8: *mut *mut c_char) -> i32 {
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 8 changed files in this pull request and generated no new comments.
Suppressed comments (3)
src/core/mxc-sdk/src/telemetry.rs:342
- This accessor returns
inner_consent::get_status().effective_state, not the recorded state. For example, a legacy stored grant is returned asUndetermined; calling it “recorded” obscures the stored/effective distinction and can mislead SDK consumers. Point callers needing the persisted value toget_consent_status.
/// Return the user's recorded consent decision.
src/ffi/mxc_ffi/src/lib.rs:439
- The export marshals the effective state returned by
get_consent(), not necessarily the persisted state. A version-invalid stored grant is reported as"undetermined", so describing this as persisted gives C callers the wrong contract;mxc_telemetry_get_consent_statusis the API that exposes both values.
/// Read the persisted telemetry consent state.
src/ffi/mxc_ffi/src/lib.rs:627
- This is the only new telemetry export with no FFI-level test, so the JSON field names/values, allocation ownership, and null-output status can regress without this crate detecting it. Add a test using the isolated telemetry environment that calls this export, parses and frees the JSON, asserts
storedState,effectiveState,reason, andpolicy, and covers a null out pointer.
pub unsafe extern "C" fn mxc_telemetry_get_consent_status(out_utf8: *mut *mut c_char) -> i32 {
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
1f67a37 to
0ca5177CompareThere was a problem hiding this comment.
Pull request overview
Copilot reviewed 15 out of 16 changed files in this pull request and generated no new comments.
Suppressed comments (5)
sdk/dotnet/Microsoft.Mxc.Sdk/MxcTelemetry.cs:275
- A non-success native status is silently collapsed to
false, and the catch below does the same for load/marshaling failures. Becausefalseis also a legitimate answer, a broken native install becomes invisible to hosts that poll this getter. Keep the fail-closed return value, but report each distinct swallowed failure once through a non-throwing diagnostic path.
int needsPrompt = 0;
var status = NativeMethods.mxc_telemetry_needs_consent_prompt(&needsPrompt);
return status == (int)ErrorCode.Success && needsPrompt != 0;
sdk/dotnet/Microsoft.Mxc.Sdk/MxcTelemetry.cs:302
- This non-success path (and the catch below) returns the legitimate
Blockedstate without reporting why, so native ABI/load failures are indistinguishable from an administrator actually blocking telemetry. Preserve the fail-closed result, but emit a non-throwing, once-per-distinct-failure diagnostic so polling does not spam logs.
if (status != (int)ErrorCode.Success)
{
return TelemetryPolicyState.Blocked;
}
src/ffi/mxc_ffi/src/lib.rs:87
- This safety note overstates what the surrounding
catch_unwindcan protect. A panic escaping a Rustextern "C"presenter cannot unwind back to this frame; it normally aborts at the non-unwinding ABI boundary. The callback must catch Rust panics too, just as the managed bridge below catches managed exceptions, or binding authors may believe a presenter panic is recoverable.
/// **The callback must not unwind across the FFI boundary.** Only Rust panics
/// are caught by [`std::panic::catch_unwind`] on the Rust side; a C++
/// exception, a .NET/CLR exception, an Objective-C exception, a Go panic, or
/// any other foreign unwind mechanism escaping this callback into Rust is
sdk/dotnet/Microsoft.Mxc.Sdk/MxcTelemetry.cs:102
- The PR description and stack explicitly reserve the Node.js/.NET SDK surfaces for #822, but this file introduces the public .NET telemetry API in #821. That makes this PR contain the next stack layer and prevents the Rust SDK/C ABI change from being reviewed independently as described. Please move the .NET API, policy, error-code, and managed-test changes to #822 or update/split the stack consistently.
/// <summary>Telemetry consent helpers over the native <c>mxc_ffi</c> surface.</summary>
public static class MxcTelemetry
sdk/dotnet/Microsoft.Mxc.Sdk/MxcTelemetry.cs:149
- This catch converts native-load, marshaling, and malformed-native-response failures into the legitimate
Undeterminedconsent state. Callers then cannot distinguish “no decision” from a broken installation. Consent reads should surface failures as the SDK's documentedMxcExceptiontype; reserve never-throw fail-closed behavior for the polling helpers (NeedsConsentPromptandGetPolicy).
This issue also appears in the following locations of the same file:
- line 273
- line 299
catch
{
return TelemetryConsentState.Undetermined;
}
Keep the .NET run-to-completion API on the canonical nested Telemetry settings and remove internal implementation language from the Rust SDK documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
There was a problem hiding this comment.
🟡 Changes recommended
The callback unwind contract is inaccurate and the .NET README references a nonexistent state-aware telemetry property.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 23/24 changed files
- Comments generated: 2
- Review effort level: Balanced
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Require all FFI presenter callbacks to contain failures internally and remove the unavailable state-aware telemetry option from the standalone .NET SDK documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
There was a problem hiding this comment.
🔵 Needs a closer look
The privacy-sensitive public API spans Rust, native ABI, managed callbacks, and custom build integration, warranting final human validation.
Review details
- Files reviewed: 23/24 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
There was a problem hiding this comment.
🔵 Needs a closer look
The privacy-sensitive API spans Rust, native ABI, managed callbacks, and custom test-build infrastructure, warranting final human review.
Review details
- Files reviewed: 23/24 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Resolve the telemetry and diagnostic overlap with PR #791 while preserving top-level telemetry consent, internal state-aware correlation, requested sandbox attribution, and the scoped ETW audit events. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Carry the current PR #820 runtime and scoped ETW integration forward without rewriting the published Rust SDK and FFI history. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
There was a problem hiding this comment.
🟡 Changes recommended
Public API documentation incorrectly describes effective consent as the persisted user decision.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 23/24 changed files
- Comments generated: 3
- Review effort level: Balanced
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Resolve the squash-merge overlap by retaining the Rust SDK telemetry accessor and combined telemetry test support while adopting the finalized correlation-vector documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
There was a problem hiding this comment.
🟡 Changes recommended
The asynchronous consent API can persist consent after its cancellation token has been canceled.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Review details
- Files reviewed: 23/24 changed files
- Comments generated: 1
- Review effort level: Balanced
Uh oh!
There was an error while loading. Please reload this page.
Centralize binding policy parsing in the native engine, clarify effective consent APIs, and make asynchronous consent cancellation state-consistent across stalled, faulted, and synchronous presenters. Refs #1090, #1111, #1112, #1113, #1114 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
There was a problem hiding this comment.
🔵 Needs a closer look
Managed fail-closed query paths silently suppress failures instead of emitting required deduplicated diagnostics.
Review details
Suppressed comments (3)
Previously missed (1) — in code that hasn't changed since the last review.
sdk/dotnet/Microsoft.Mxc.Sdk/MxcTelemetry.cs:151
- This fallback silently hides native-load and managed parsing failures. Telemetry's fail-closed convention requires swallowed failures to remain diagnosable once per distinct failure (see
docs/telemetry/telemetry-administrative-policy.md:47-49and the nativereport_diagnostic_oncehelper), otherwise a broken binding is indistinguishable from a genuine undetermined state. Report the exception through a non-throwing, deduplicated diagnostic helper before returningUndetermined.
This issue also appears in the following locations of the same file:
- line 317
- line 351
sdk/dotnet/Microsoft.Mxc.Sdk/MxcTelemetry.cs:319
- This catch converts every resolver/native failure to
falsewithout any diagnostic. Becausefalseis also the legitimate no-prompt result, a broken native installation becomes invisible; the telemetry failure-handling convention reports swallowed failures once per distinct failure (docs/telemetry/telemetry-administrative-policy.md:47-49). Use the same non-throwing, deduplicated managed diagnostic helper as the other fail-closed queries before returning.
catch
{
return false;
sdk/dotnet/Microsoft.Mxc.Sdk/MxcTelemetry.cs:353
- Returning
Blockedis correctly fail-closed, but silently swallowing this exception violates the policy contract that unreadable failures are reported once so operators can distinguish a broken deployment from an intentional block (docs/telemetry/telemetry-administrative-policy.md:43-49). Emit a non-throwing, deduplicated diagnostic before returning the fallback.
catch
{
return TelemetryPolicyState.Blocked;
- Files reviewed: 26/27 changed files
- Comments generated: 0 new
- Review effort level: Balanced
Emit non-throwing, process-deduplicated diagnostics whenever managed consent and policy queries return fail-closed fallback values. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Use stable bounded diagnostic categories, redact exception details, and add deterministic deduplication coverage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Route fail-closed reports through Trace, use typed allocation-free deduplication keys, remove the global sink override, and document the managed diagnostic channel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Make deduplication and capacity independently testable, scope Trace assertions to unique operation tags, and cover concurrent reports. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Add an internal query seam for deterministic fail-closed integration tests, cover concurrent capacity and throwing Trace listeners, and document retained diagnostic fields. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Use atomic override restoration, cover concurrent disposal, and name the seam for the fail-closed reads it intentionally isolates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Rollback diagnostic reservations when Trace listeners fail, isolate production tracker state in tests, strengthen override restoration coverage, and consolidate reporter control flow. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Reject overlapping process-global test overrides, cover each read failure branch, and clarify diagnostic documentation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Use a fresh dedup tracker and assert the distinct exception and status diagnostic paths without consuming process-global state. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Dispose process-global test overrides during assertion unwinding and document why the telemetry collection is nonparallel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
Document that managed fail-closed reporting retains a bounded set of distinct process-lifetime failure signatures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 6e20d046-910e-4ee7-b8e8-acb0fe007208
There was a problem hiding this comment.
🔵 Needs a closer look
The broad privacy-sensitive, cross-language API and FFI changes warrant final human validation despite the extensive coverage.
Review details
- Files reviewed: 26/27 changed files
- Comments generated: 0 new
- Review effort level: Balanced
.github/copilot-instructions.md.Summary
Exposes stable telemetry consent and policy through the public Rust SDK, panic-safe C ABI, and managed .NET binding. Adds typed presenter/status/withdrawal APIs, native binding entry points, streaming and state-aware propagation, and binding-codegen coverage.
This is PR 4 of 5 and depends on the stable runtime integration in PR 3.
Stack
Review only this PR's diff; prerequisite behavior is in the PR above.