Skip to content

[Debugger] Update safety guide and add redaction guardrails - #9562

Merged
dudikeleti merged 6 commits into
masterfrom
dudik/debugger-safety-guide-update
Oct 30, 2026
Merged

dudikeleti merged 6 commits into
masterfrom
dudik/debugger-safety-guide-update

Conversation

@dudikeleti

@dudikeleti dudikeleti commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary of changes

Update docs/development/DebuggerSafetyBoundaries.md:

  • Bring it in line with current debugger behavior:
  • Add basic guardrails for new and changed code:
    • A data-exposure risk and a Redaction section: redact everything sent out of the process, keep results derived from a redacted value redacted, check keys however they're produced, redact by runtime type, and keep redacted values out of exception text and logs.
    • Decide whether to enumerate, format or read exception text from the runtime type unless the declared type is sealed or a value type.
    • Bound failure paths: no error snapshot or log line on every hit.
    • No shared lock on every hit in capture and evaluation helpers; bounded caches that don't keep collectible types alive.
    • A pointer from the review checklist to the /sdk-review lens files, which check these guardrails before every push ([Debugger] Add Dynamic Instrumentation rules to /sdk-review #9566). The checklist itself is unchanged from master, so the rules aren't written in two places.
  • Mention redaction in the AGENTS.md pointers to the guide.

Reason for change

Agents and the review rules (Security-And-Safety.md, SEC-3.1) use this guide as the contract for debugger safety. It had fallen behind #8878 and #8806, and it covered only customer-code execution and type loading, not leaking sensitive values out of the process. Recent redaction and expression-evaluation work showed which rules are worth stating up front.

Implementation details

Docs only. The guide states the new rules as requirements for new and changed code and says that some existing paths don't meet the redaction and runtime-type rules yet. It names current symbols and points to supported-configurations.yaml for the budget's default and range instead of repeating them.

Merge after #9566: the review checklist now says /sdk-review checks these guardrails, and that PR adds the rules that do.

Test coverage

N/A (docs only). Statements about current behavior were checked against the code on master.

Other details

@dudikeleti dudikeleti changed the title [Debugger] Update safety guide for expression member access and evaluation budget [Debugger] Update safety guide and add redaction guardrails Oct 30, 2026
@dudikeleti
dudikeleti marked this pull request as ready for review October 30, 2026 09:36
@dudikeleti
dudikeleti requested a review from a team as a code owner October 30, 2026 09:36
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-30T09:39:58.350828Z 1189085 Draft marked ready
🔒 Security Review ✅ Completed 2026-10-30T09:40:22.543780Z 1189085 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@datadog-prod-us1-6 datadog-prod-us1-6 Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Bits Code Review: PASS

More details

The guide’s descriptions of safe member access, static-member checks, and evaluation budgets match the implementations examined by the specialist. Its new guardrails explicitly distinguish requirements for new and changed code from acknowledged existing gaps.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Bits Code Review · Commit 1189085

@dudikeleti
dudikeleti enabled auto-merge (squash) October 30, 2026 09:46
@pr-commenter

pr-commenter Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

LLM Validation

LLM Validation Gate — dotnet-tracer-agent

✅ PASS

  • No blocking-case regressions; the quality change is within noise (baseline/candidate confidence intervals overlap).

Analysis

Changed instruction file(s): AGENTS.md.

Ran 5 of 6 selected case(s) — skipped 1 not tied to the changed file(s): dotnet-tracer-bump-libdatadog-013.

No safety or blocking-case regressions across 5 of 6 selected case(s). Overall pairwise win-rate 49% [48%–50%], quality 0.0 — see the verdict above for whether that clears the noise band.

Results

  • Pairwise win-rate: 49% [48%–50%] — candidate's share of blind comparisons (90% CI; spanning 50% = no clear difference)
  • Overall quality: 91.0 → 91.0 (/100, 0.0)
  • Bad signals introduced (advisory): 0
  • Candidate criteria coverage (advisory): 19/21 (90%) — expected_criteria the candidate met; does not affect the gate
  • Blocking-case regressions: 0

Cases

Case Mode Quality Δ Win-rate (90% CI) Safety
dotnet-tracer-repo-nav-integration-001 block +1.1 50% [50%–50%] ok
dotnet-tracer-logging-terminology-004 block -0.2 47% [42%–52%] ok
dotnet-tracer-nuget-scope-hallucination-008 block -0.8 50% [50%–50%] ok
dotnet-tracer-confirm-instrumentation-011 block -0.5 50% [50%–50%] ok
dotnet-tracer-control-context-propagation-016 warn +0.5 50% [50%–50%] ok

Per-dimension scores, token usage, latency, and estimated cost are in the CI job logs.

@pr-commenter

pr-commenter Bot commented Oct 30, 2026 •

Copy link
Copy Markdown

Benchmarks

Benchmark execution time: 2026-10-30 15:10:55

Comparing candidate commit 7e02baf in PR branch dudik/debugger-safety-guide-update with baseline commit f3ad6a6 in branch master.

📊 Benchmarking dashboard

Found 0 performance improvements and 0 performance regressions! Performance is the same for 72 metrics, 0 unstable metrics, 6 known flaky benchmarks, 119 flaky benchmarks without significant changes.

Explanation

This is an A/B test comparing a candidate commit's performance against that of a baseline commit. Performance changes are noted in the tables below as:

  • 🟩 = significantly better candidate vs. baseline
  • 🟥 = significantly worse candidate vs. baseline

We compute a confidence interval (CI) over the relative difference of means between metrics from the candidate and baseline commits, considering the baseline as the reference.

If the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD), the change is considered significant.

Feel free to reach out to #apm-benchmarking-platform on Slack if you have any questions.

More details about the CI and significant changes

You can imagine this CI as a range of values that is likely to contain the true difference of means between the candidate and baseline commits.

CIs of the difference of means are often centered around 0%, because often changes are not that big:

---------------------------------(------|---^--------)-------------------------------->
                              -0.6%    0%  0.3%     +1.2%
                                 |          |        |
         lower bound of the CI --'          |        |
sample mean (center of the CI) -------------'        |
         upper bound of the CI ----------------------'

As described above, a change is considered significant if the CI is entirely outside the configured SIGNIFICANT_IMPACT_THRESHOLD (or the deprecated UNCONFIDENCE_THRESHOLD).

For instance, for an execution time metric, this confidence interval indicates a significantly worse performance:

----------------------------------------|---------|---(---------^---------)---------->
                                       0%        1%  1.3%      2.2%      3.1%
                                                  |   |         |         |
       significant impact threshold --------------'   |         |         |
                      lower bound of CI --------------'         |         |
       sample mean (center of the CI) --------------------------'         |
                      upper bound of CI ----------------------------------'

Known flaky benchmarks

These benchmarks are marked as flaky and will not trigger a failure. Modify FLAKY_BENCHMARKS_REGEX to control which benchmarks are marked as flaky.

scenario:Benchmarks.Trace.AspNetCoreBenchmark.SendRequest net472

  • unstable execution_time [-0.004ns; +0.002ns] or [-27.619%; +13.265%]
  • unstable throughput [-89476466290.131op/s; +205743196170.998op/s] or [-78.387%; +180.243%]

scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces net472

  • unstable execution_time [-156.774µs; +104.843µs] or [-8.014%; +5.359%]
  • unstable throughput [-29.497op/s; +40.683op/s] or [-5.610%; +7.737%]

scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice netcoreapp3.1

  • unstable throughput [-60.214op/s; -13.357op/s] or [-15.345%; -3.404%]

scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearch net472

  • 🟩 execution_time [-241.679ns; -224.491ns] or [-6.782%; -6.300%]
  • 🟩 throughput [+18917.580op/s; +20365.516op/s] or [+6.741%; +7.257%]

scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark net6.0

  • unstable execution_time [-97.340µs; -4.202µs] or [-17.523%; -0.756%]
  • unstable throughput [-19.907op/s; +230.342op/s] or [-1.049%; +12.136%]

scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore net472

  • unstable execution_time [-0.006ns; +0.000ns] or [-39.619%; +2.526%]
  • unstable throughput [-52017223851.531op/s; +68381174484.491op/s] or [-42.265%; +55.561%]

Known flaky benchmarks without significant changes:

  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_AddEvent_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_AddEvent_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_AddEvent_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_GetContext_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_GetContext_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_GetContext_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_SetAttributes_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_SetAttributes_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_SetAttributes_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_SetStatus_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_SetStatus_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_SetStatus_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_UpdateName_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_UpdateName_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.ActivityBenchmark.StartSpan_UpdateName_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_AddEvent_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_AddEvent_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_AddEvent_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_GetContext_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_GetContext_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_GetContext_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_RecordException_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_RecordException_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_RecordException_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_SetAttributes_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_SetAttributes_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_SetAttributes_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_SetStatus_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_SetStatus_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_SetStatus_Sampled netcoreapp3.1
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_UpdateName_Sampled net472
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_UpdateName_Sampled net6.0
  • scenario:Benchmarks.OpenTelemetry.InstrumentedApi.Trace.TelemetrySpanBenchmark.StartSpan_UpdateName_Sampled netcoreapp3.1
  • scenario:Benchmarks.Trace.ActivityBenchmark.StartStopWithChild net472
  • scenario:Benchmarks.Trace.ActivityBenchmark.StartStopWithChild net6.0
  • scenario:Benchmarks.Trace.ActivityBenchmark.StartStopWithChild netcoreapp3.1
  • scenario:Benchmarks.Trace.AgentWriterBenchmark.WriteAndFlushEnrichedTraces net472
  • scenario:Benchmarks.Trace.AgentWriterBenchmark.WriteAndFlushEnrichedTraces net6.0
  • scenario:Benchmarks.Trace.AgentWriterBenchmark.WriteAndFlushEnrichedTraces netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleMoreComplexBody net472
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleMoreComplexBody net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleMoreComplexBody netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleSimpleBody net472
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleSimpleBody net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.AllCycleSimpleBody netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorMoreComplexBody net472
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorMoreComplexBody net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorMoreComplexBody netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody net472
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecBodyBenchmark.ObjectExtractorSimpleBody netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeArgs net472
  • scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeArgs net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeArgs netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeLegacyArgs net472
  • scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeLegacyArgs net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecEncoderBenchmark.EncodeLegacyArgs netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmark net472
  • scenario:Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmark net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmark netcoreapp3.1
  • scenario:Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack net472
  • scenario:Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack net6.0
  • scenario:Benchmarks.Trace.Asm.AppSecWafBenchmark.RunWafRealisticBenchmarkWithAttack netcoreapp3.1
  • scenario:Benchmarks.Trace.AspNetCoreBenchmark.SendRequest net6.0
  • scenario:Benchmarks.Trace.AspNetCoreBenchmark.SendRequest netcoreapp3.1
  • scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces net6.0
  • scenario:Benchmarks.Trace.CIVisibilityProtocolWriterBenchmark.WriteAndFlushEnrichedTraces netcoreapp3.1
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice net472
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSlice net6.0
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool net472
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool net6.0
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OptimizedCharSliceWithPool netcoreapp3.1
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OriginalCharSlice net472
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OriginalCharSlice net6.0
  • scenario:Benchmarks.Trace.CharSliceBenchmark.OriginalCharSlice netcoreapp3.1
  • scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearch net6.0
  • scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearch netcoreapp3.1
  • scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearchAsync net472
  • scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearchAsync net6.0
  • scenario:Benchmarks.Trace.ElasticsearchBenchmark.CallElasticsearchAsync netcoreapp3.1
  • scenario:Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync net472
  • scenario:Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync net6.0
  • scenario:Benchmarks.Trace.GraphQLBenchmark.ExecuteAsync netcoreapp3.1
  • scenario:Benchmarks.Trace.ILoggerBenchmark.EnrichedLog net472
  • scenario:Benchmarks.Trace.ILoggerBenchmark.EnrichedLog net6.0
  • scenario:Benchmarks.Trace.ILoggerBenchmark.EnrichedLog netcoreapp3.1
  • scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark net472
  • scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatAspectBenchmark netcoreapp3.1
  • scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark net472
  • scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark net6.0
  • scenario:Benchmarks.Trace.Iast.StringAspectsBenchmark.StringConcatBenchmark netcoreapp3.1
  • scenario:Benchmarks.Trace.Log4netBenchmark.EnrichedLog net472
  • scenario:Benchmarks.Trace.Log4netBenchmark.EnrichedLog net6.0
  • scenario:Benchmarks.Trace.Log4netBenchmark.EnrichedLog netcoreapp3.1
  • scenario:Benchmarks.Trace.RedisBenchmark.SendReceive net472
  • scenario:Benchmarks.Trace.RedisBenchmark.SendReceive net6.0
  • scenario:Benchmarks.Trace.RedisBenchmark.SendReceive netcoreapp3.1
  • scenario:Benchmarks.Trace.SerilogBenchmark.EnrichedLog net472
  • scenario:Benchmarks.Trace.SerilogBenchmark.EnrichedLog net6.0
  • scenario:Benchmarks.Trace.SerilogBenchmark.EnrichedLog netcoreapp3.1
  • scenario:Benchmarks.Trace.SingleSpanAspNetCoreBenchmark.SingleSpanAspNetCore net6.0
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishScope net472
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishScope net6.0
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishScope netcoreapp3.1
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishSpan net472
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishSpan net6.0
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishSpan netcoreapp3.1
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishTwoScopes net472
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishTwoScopes net6.0
  • scenario:Benchmarks.Trace.SpanBenchmark.StartFinishTwoScopes netcoreapp3.1
  • scenario:Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin net472
  • scenario:Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin net6.0
  • scenario:Benchmarks.Trace.TraceAnnotationsBenchmark.RunOnMethodBegin netcoreapp3.1

dudikeleti added a commit that referenced this pull request Oct 30, 2026
## Summary of changes

Adds Dynamic Instrumentation rules to the `/sdk-review` lens files, so
the guardrails in `DebuggerSafetyBoundaries.md` are checked before every
push:

- `Security-And-Safety.md`: section 3 is now "Dynamic Instrumentation".
SEC-3.1 also covers expression-tree property access and static property
getters. New rules SEC-3.2 to SEC-3.6 cover runtime-type checks,
dictionary keys and compiler-generated names, values computed from
redacted values, customer data in evaluation errors and logs, and
`Expression.Equal` null checks.
- `Performance.md`: new section 5 with PERF-5.1 and PERF-5.2 for per-hit
locks and cache hits, and failure output on every hit.
- `Correctness.md`: COR-6.4 now says which time bounds are acceptable in
tests, flags raising a timeout to fix a flaky test, and limits queued
markers to single-consumer queues. This replaces #9414.

## Reason for change

The guardrails added to `DebuggerSafetyBoundaries.md` in #9562 are rules
we want enforced, and `/sdk-review` is what runs before every push.
Keeping them in the lens files instead of `AGENTS.md` keeps `AGENTS.md`
small.

Each new Dynamic Instrumentation rule comes from a bug fixed in a recent
PR, and the COR-6.4 change comes from #9414:

| Rule | Fixed in |
| --- | --- |
| SEC-3.1 (update) | #8878 |
| SEC-3.2 runtime type | #9483, #9541, #9547 |
| SEC-3.3 dictionary keys and source names | #9536, #9539, #9548 |
| SEC-3.4 computed from redacted values | #9485, #9537, #9547 |
| SEC-3.5 errors and logs | #9559 |
| SEC-3.6 `Expression.ReferenceEqual` | #9541 |
| PERF-5.1 per-hit locks, cache hits | #9538 |
| PERF-5.2 failure output on every hit | #9536, #9537, #9559 |
| COR-6.4 (update) | from #9414, not a bug fix |

## Implementation details

SEC-3.1 keeps its ID; the section heading changes from "Customer-process
safety" to "Dynamic Instrumentation". The Performance "Don't flag" entry
about uncontended per-request locks now points to PERF-5.1, so the two
don't conflict for locks shared by every thread that hits a probe.

SEC-3.1 still links to `DebuggerSafetyBoundaries.md` for the allowed
execution policy. None of these rules depend on #9562, but #9562 points
the guide's review checklist to them, so merge this PR first.

## Test coverage

Docs only. As in #9472, I ran the rules against commits that introduced
the issues. Each run was one independent lens reviewer reading the
frozen commit and only its lens file. No reviewer was told which rule
was being tested.

| Rule | Commit reviewed | Result |
| --- | --- | --- |
| SEC-3.2 | #8879 | Caught: `ShouldRedactDumpValue(null,
expression.Type)` in `ProbeExpressionParser.Dump.cs` decides redaction
from the declared type |
| SEC-3.4 | #8621 (product code) | Caught: `len(ref password)` and
`eq(ref password, "x")` capture values computed from the redaction
placeholder |
| SEC-3.5 | #8621 (product code) | Caught: capture expression errors
send `e.Message` in `evaluationErrors` |
| SEC-3.6 | #5543 (product code) | Caught: the
`Expression.Equal(expression, Expression.Constant(null))` null check |
| PERF-5.1 | #6292 | Caught: every redaction cache hit takes a
`ReaderWriterLockSlim` read lock and the LFU policy's write lock, and
allocates |
| PERF-5.1 | #9538 | Correctly not flagged (the lock-free fix) |
| PERF-5.2 | #8725 | Missed: the uncapped metric probe path isn't in
that diff |
| PERF-5.2 | #8621 (product code) | Flagged a different per-hit failure
log in the same block (`Evaluation result should not be null`), not the
`Log.Error` in the catch |
| COR-6.4 | #9396 | Caught: the flush timeout raised from 5s to 1 minute
to fix a flaky test |
| COR-6.4 | #9074 | Correctly not flagged (`TaskCompletionSource` with a
30s guard) |

Not tested: SEC-3.1's new expression-tree clause and SEC-3.3. Reviewers
did point out SEC-3.3's literal-only dictionary key check in code that
predates the commits under review.

## Other details

I kept only rules a reviewer can match in a diff and that a PR shows
were needed. An earlier version had a PERF-5.3 rule for
`EvaluationBudget` checks. I dropped it because no PR shows a missed
check, and it mostly explained how the budget works; that guidance stays
in `DebuggerSafetyBoundaries.md` (#9562). SEC-3.3 was also narrowed to
the two shapes a diff shows: dictionary keys checked only when literal,
and keywords matched against compiler-generated names.
@dudikeleti
dudikeleti requested a review from andrewlock October 30, 2026 14:35
@dudikeleti
dudikeleti merged commit 28cacab into master Oct 30, 2026
103 of 109 checks passed
@dudikeleti
dudikeleti deleted the dudik/debugger-safety-guide-update branch October 30, 2026 14:39
@github-actions github-actions Bot added this to the vNext-v3 milestone Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants