Skip to content

skill(apm-integrations): async instrumentation - add rules from review feedback - #11990

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 12 commits into
masterfrom
feat/skill-async-iteration-2
Jul 27, 2026
Merged

skill(apm-integrations): async instrumentation - add rules from review feedback#11990
gh-worker-dd-mergequeue-cf854d[bot] merged 12 commits into
masterfrom
feat/skill-async-iteration-2

Conversation

@jordan-wong

@jordan-wong jordan-wong commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds 13 rules to the apm-integrations skill, driven by two sources:

  1. Iteration-1 async cycle findings — 7 skill prescriptions from the
    CI-triage of the async blind regens for rxjava-3.0 ( rxjava-3.0 async blind regeneration for #11927 #11939) and
    reactor-core-3.1 ([reference] reactor-core-3.1 async blind regeneration for #11927 #11940). Full inventory:
    docs/eval-research/cycles/2026-07-14-async-cycle-report.md in
    apm-instrumentation-toolkit.

  2. Reviewer feedback on those two PRs — 6 additional rules from
    @ygree, @mcculls, and Codex reviews. Full extraction:
    docs/eval-research/http-findings-2026-07-16/FEEDBACK-CONSOLIDATED-2026-07-16.md.

Rules added

context-tracking.md (2 new subsections):

  • Library-native context-map pattern — prescribes *ContextBridge-style
    helper preservation for libraries with a first-class Context concept
    (Reactor, Kotlin coroutines, JAX-RS, Vert.x). Directly addresses the
    primary iteration-1 regression: reactor-core-3.1 dropped
    ReactorContextBridge + 4 supporting classes, silently breaking Spring
    WebFlux + Spring Kafka reactive.
  • Wrap placement and context-store lifecycle — boundary-only wrapping,
    Subscriber-lifecycle stores, avoid double-wrapping.

instrumenter-module.md (5 new/strengthened subsections):

  • super(...) alias strengthening — concrete rxjava-3.0 example showing
    DD_TRACE_RXJAVA_3_ENABLED breakage when the version alias is dropped.
  • Package layout preservation on regen — concrete reactor-core-3.1 example
    showing graal-native-image cross-module reference breakage.
  • Enumerate all master *Instrumentation.java classes on regen —
    reactor-core-3.1 kept only 2 of 7 master classes.
  • Preserve declarative-array ordering (helperClassNames, contextStore).
  • Hoist repeated Class.getName() calls in contextStore().

muzzle.md (3 new subsections):

  • Namespace-isolation fail blocks for major-version siblings — rxjava-3.0
    master has fail { name = "rxjava2-must-not-match" }; eval dropped it.
  • Preserve compileOnly dependency versions on regen — extends existing
    testImplementation parity rule.
  • Preserve test-scope build.gradle dependencies on regen — reactor-core-3.1
    eval dropped 8 test deps flagged by @mcculls.

tests.md (2 new subsections):

  • Version-sensitive tests belong in a separate latestDepTest source set.
  • No banner/separator comments in test files.

advice-class.md (1 new subsection):

  • No inline explanatory comments in Advice methods when a wrapping class's
    Javadoc already covers the intent.

Validation

Iteration-2 blind regens ran against this skill branch. Results:

reactor-core-3.1 iteration-2 — all 6 iteration-1 gaps CLOSED. Regen
produced a byte-identical ReactorContextBridge.java plus the 4 supporting
operator instrumentations that iteration-1 dropped. Local
:check :muzzle :latestDepTest green. See #11974 ([reference]) for the
concrete output. Cost: $7.67 (down from iteration-1's $13).

rxjava-3.0 iteration-2 — 2 of 7 gaps CLOSED (super(...) alias fix,
helperClassNames ordering). 5 gaps STILL-OPEN as rule-adherence failures
(rule exists in the skill, model did not apply it): muzzle fail block,
reactive-streams version parity, contextStore hoist, no inline Advice
comments, no banner test comments. Local
:check :muzzle :latestDepTest green. See #11991 ([reference]) for the concrete output.

The reactor result shows the rules generalize correctly for Reactor-shape
context-propagation. The rxjava3 result surfaces a rule-adherence gap that
should be addressed in a follow-up (candidates: reviewer_checks/ grep
rules, or moving these rules to more prominent SKILL.md positions).

Cross-references

Not requesting reviewers on open — waiting to sequence after #11927 discussion settles.

🤖 Generated with APM Instrumentation Toolkit

@datadog-official

This comment has been minimized.

@dd-octo-sts

dd-octo-sts Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🟢 Java Benchmark SLOs — All performance SLOs passed

Suite Status
Startup 🟢 pass

SLO thresholds are defined here based on automatically generated metrics. A warning is raised when results are within 5% of the threshold.

PR vs. master results
Scenario Candidate master Δ (95% CI of mean)
startup:insecure-bank:iast:Agent 13.93 s 13.91 s [-0.6%; +0.8%] (no difference)
startup:insecure-bank:tracing:Agent 12.82 s 12.98 s [-1.9%; -0.5%] (maybe better)
startup:petclinic:appsec:Agent 16.81 s 16.26 s [-1.2%; +7.9%] (no difference)
startup:petclinic:iast:Agent 16.40 s 16.83 s [-6.9%; +1.8%] (no difference)
startup:petclinic:profiling:Agent 16.61 s 16.74 s [-1.9%; +0.3%] (no difference)
startup:petclinic:sca:Agent 16.88 s 16.71 s [-0.1%; +2.2%] (no difference)
startup:petclinic:tracing:Agent 16.06 s 16.00 s [-0.4%; +1.2%] (no difference)

Commit: 6bbf6a4e · CI Pipeline · Benchmarking Platform UI


Load and DaCapo benchmarks can be triggered manually in the GitLab pipeline. Results will appear in the Benchmarking Platform UI after completion.

@jordan-wong
jordan-wong requested a review from Copilot July 20, 2026 02:09

Copilot AI 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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copilot AI 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.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 5 comments.

Comment thread .agents/skills/apm-integrations/references/tests.md Outdated
Comment thread .agents/skills/apm-integrations/references/tests.md Outdated
Comment thread .agents/skills/apm-integrations/references/instrumenter-module.md Outdated
Comment thread .agents/skills/apm-integrations/references/muzzle.md Outdated
Comment thread .agents/skills/apm-integrations/references/context-tracking.md Outdated
jordan-wong added a commit that referenced this pull request Jul 20, 2026
…Test nuance, find vs ls glob, muzzle fail scope, ContextStore implementation accuracy
@jordan-wong
jordan-wong marked this pull request as ready for review July 21, 2026 14:28
@jordan-wong
jordan-wong requested a review from a team as a code owner July 21, 2026 14:28
@jordan-wong
jordan-wong requested review from PerfectSlayer and mcculls and removed request for PerfectSlayer July 21, 2026 14:28
…acement guidance

Adds two subsections to context-tracking.md driven by reactor-core-3.1 blind
regen findings (dd-trace-java PR #11940):

1. **Library-native context maps — the *ContextBridge pattern** (RI-6).
   Prescribes preservation/regeneration of the Reactor-style context-bridge
   helper for libraries with a first-class Context concept (Reactor,
   Kotlin coroutines, JAX-RS, Vert.x). The subscriber-wrapping pattern
   alone is insufficient — regenerating a reactive module without the
   bridge silently breaks Spring WebFlux, Spring Kafka reactive, and
   related downstream libraries.

2. **Wrap placement and context-store lifecycle** (from @mcculls' review
   of PR #11940). Boundary-only wrapping, Subscriber-lifecycle stores,
   avoid double-wrapping. Prevents the "increased memory use" pattern
   the eval output demonstrated.

Motivating incident: dd-trace-java PR #11940 eval dropped 5 of 7 master
reactor-core-3.1 instrumentation classes including ReactorContextBridge,
which caused spring-messaging-4.0's KafkaBatchListenerCoroutineTest to
time out.

Sources:
- @mcculls on PR #11940 FluxInstrumentation.java:20
- docs/eval-research/cycles/2026-07-14-async-cycle-report.md RI-5, RI-6
- Master reference: dd-java-agent/instrumentation/reactor-core-3.1/
…age, classes, ordering

Adds five prescriptions to instrumenter-module.md driven by async cycle
iteration-1 findings (docs/eval-research/cycles/2026-07-14-async-cycle-report.md)
plus @ygree review feedback on rxjava-3.0 PR #11939.

1. **super() alias strengthening (RI-1)** — concrete rxjava-3.0 example
   showing DD_TRACE_RXJAVA_3_ENABLED breakage when the version alias is
   dropped. Existing "preserve super() verbatim" rule was too abstract.

2. **Package layout preservation on regen (RI-4)** — concrete reactor-core-3.1
   example showing graal-native-image cross-module reference breakage when
   the eval renamed reactor.core -> reactorcore.

3. **Enumerate all master *Instrumentation.java classes on regen (RI-5)** —
   the reactor-core-3.1 regen kept 2 of 7 master classes, silently dropping
   ReactorContextBridge and 4 others. Rule prescribes an explicit
   pre-generation enumeration + post-generation diff check.

4. **Preserve declarative-array ordering (NR-1)** — @ygree flagged
   "meaningless reshuffling" in helperClassNames(). Rule: preserve
   master's ordering unless a semantic change requires reordering.

5. **Hoist repeated Class.getName() in contextStore() (NR-2)** — @ygree
   flagged five inlined copies of Context.class.getName() as a regression
   from master's hoist pattern.

Sources:
- docs/eval-research/cycles/2026-07-14-async-cycle-report.md RI-1, RI-4, RI-5
- @ygree PR #11939 comments 3591691401, 3591695153
… parity

Adds three prescriptions to muzzle.md from async cycle iteration-1 findings
and @mcculls review feedback.

1. **Namespace-isolation fail block for major-version siblings (RI-2).**
   rxjava-3.0 master has `muzzle { fail { name = "rxjava2-must-not-match" } }`
   to assert rxjava3 advice never matches rxjava2 coordinates. Eval dropped
   the block. Rule prescribes preservation for any module with a prior-major
   sibling module in the repo.

2. **compileOnly dep version parity on regen (RI-3).** rxjava-3.0 master
   uses reactive-streams 1.0.3; eval regenerated as 1.0.0, silently
   narrowing the tested API surface. Rule extends the existing
   testImplementation parity rule to compileOnly.

3. **Test-scope build.gradle dep preservation (NR-5, @mcculls PR #11940).**
   reactor-core-3.1 eval dropped 8 testImplementation and latestDepTest
   deps that back annotation-driven tests and cross-module interop tests.
   Rule prescribes superset-of-master semantics for test deps.
…s in tests

Adds two prescriptions to tests.md from async cycle iteration-1 findings
and @ygree review feedback.

1. **latestDepTest source-set preservation (RI-7).** reactor-core-3.1
   master has src/latestDepTest/groovy/ for version-sensitive tests.
   The eval collapsed all tests into src/test/java/, which caused
   Schedulers.elastic() (removed in Reactor 3.4+) to break :latestDepTest
   compilation across all JVM shards. Rule prescribes preserving the
   split when master has it, and using it for libraries with breaking
   API changes across recent minor versions.

2. **No banner comments in test files (NR-4).** @ygree flagged
   `// --------- Successful completion ---------` style banners in
   RxJava3ResultExtensionTest.java as "distracting and don't offer much
   value because their scope is unclear." Rule: omit or extract into
   separate test classes with focused Javadoc.

@datadog-official datadog-official 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.

Datadog Autotest: WARN

New rules accurately capture findings from iteration-1 CI failures (reactor-core-3.1 dropped context bridges, rxjava-3.0 dropped version aliases). However, the rules are documented but not wired into SKILL.md steps — code-gen LLMs won't apply them without explicit prompt references. Also, several important existing rules on async HTTP clients and advice-class constraints were removed without explanation, creating a documentation gap.

P1 New rules documented but not wired into SKILL.md prompt steps

Future regenerations of reactive modules will likely omit context bridges, drop version aliases, skip muzzle namespace-isolation blocks, and collapse latestDepTest source sets — all regressions documented in this PR.

Assertion details
  • Input: Code-gen LLM uses apm-integrations skill to generate a new reactive library instrumentation
  • Expected: LLM should reference and apply the new rules: library-native context maps, namespace-isolation muzzle blocks, latestDepTest source set preservation, super() alias preservation
  • Actual: SKILL.md does not reference these new subsections explicitly. LLM reads SKILL.md and references files, but without explicit step-by-step pointers (e.g. 'Step 5.1: Read the new "super() alias" subsection in instrumenter-module.md'), the rules remain optional/advisory. This replicates the iter-2 rxjava-3.0 finding where 5 rule-adherence gaps remained despite rules existing in the skill.

P2 Important guidance on async HTTP clients and advice constraints removed without explanation

Future developers won't find guidance on async HTTP client pitfalls or understand why certain advice patterns exist in production modules. Code-gen or manual implementations may reinvent wrong patterns (lambdas in advice, reassigning futures, creating duplicate spans).

Assertion details
  • Input: Developer reads advice-class.md to understand how to write advice for async HTTP clients or route enrichers
  • Expected: Documentation explains: (1) when NOT to create a second span in async wrappers, (2) when to use executor instrumentation vs reactivate patterns, (3) CompletableFuture cancellation preservation via named callbacks not lambdas, (4) why not to extract advice logic into single-use helpers, (5) route-only enricher patterns for SparkJava-like frameworks
  • Actual: All five subsections removed from advice-class.md. Replaced with single 'No inline explanatory comments' rule. No explanation in PR description. Removed sections had concrete examples from feign-11.0, okhttp-3.0, SparkJava.

Was this helpful? React 👍 or 👎

Open Bits AI session

🤖 Datadog Autotest · Commit 1243a8d · What is Autotest? · Any feedback? Reach out in #autotest

…hods

Adds NR-3 from @ygree review of PR #11939. Advice bodies are typically
short; the wrapper/helper class is where reviewers look to understand
semantics. Duplicating the explanation as a `//`-comment at the advice
call site inflates the diff and drifts out of sync with the wrapper's
Javadoc.

Source: @ygree, PR #11939 comment on SingleInstrumentation.java:55.
…Test nuance, find vs ls glob, muzzle fail scope, ContextStore implementation accuracy
@jordan-wong
jordan-wong force-pushed the feat/skill-async-iteration-2 branch from 1243a8d to 0338411 Compare July 21, 2026 14:33
@dd-octo-sts

dd-octo-sts Bot commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Hi! 👋 Thanks for your pull request! 🎉

To help us review it, please make sure to:

  • Add at least one type, and one component or instrumentation label to the pull request

If you need help, please check our contributing guidelines.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1243a8d54b

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .agents/skills/apm-integrations/references/context-tracking.md
Comment thread .agents/skills/apm-integrations/references/tests.md Outdated
Comment thread .agents/skills/apm-integrations/references/muzzle.md Outdated
Comment thread .agents/skills/apm-integrations/references/muzzle.md Outdated
Comment thread .agents/skills/apm-integrations/references/instrumenter-module.md Outdated
- context-tracking.md: narrow ContextStore key rule — Reactor uses
  Publisher/Subscriber; JAX-RS uses ContainerRequestContext; Vert.x uses
  its own Context; coroutines use Continuation/CoroutineContext. Do not
  force Reactor's key type onto libraries that don't expose Publisher /
  Subscriber. Also broaden lifecycle-boundary examples per library shape.
- tests.md: distinguish latest-only APIs (belong in src/latestDepTest/)
  from removed-in-latest APIs (belong in src/test/, or use replacement
  API in latestDepTest). The Reactor Schedulers.elastic() removal is
  the removed-in-latest case, not the latest-only case.
- muzzle.md #1 (fail-block scope): explicitly show same-coordinate
  cases (jedis/okhttp/jetty-server) alongside different-coordinate
  cases (rxjava, jms api). The bounded 'versions' range in the fail
  block is what asserts non-overlap for same-coordinate siblings.
- muzzle.md #2 (test-dep preservation): extend the preservation list to
  cover testRuntimeOnly / latestDepTestRuntimeOnly / forkedTestRuntimeOnly.
  Runtime-only test deps do NOT trigger compile failures if dropped, so
  losing them silently removes cross-instrumentation coexistence coverage
  (e.g. rxjava-3.0's testRuntimeOnly on rxjava-2.0).
- instrumenter-module.md: broaden the pre-regen source-file enumeration
  from `src/main/java` to every production source set: src/main/java17,
  src/main/java11, src/main/groovy, src/main/scala, src/main/kotlin.
  Kafka-clients-3.8 and jetty-server-12.0 keep classes under java17;
  a `find` limited to `src/main/java` misses them.

All five findings are P2 severity per Codex classification; each corrects
a case where the iter-2 rule was too narrow and could mislead a regen.

@mcculls mcculls 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.

General comment - a lot of this appears to be helping to minimize changes when rewriting an existing integration. Is all of this text appropriate given most of the time we expect to be writing new integrations?

A lot of it could be replaced by telling the AI to do things like "edit in place"

…w rules into SKILL.md

Feedback from @mcculls on this PR and separately from a senior engineer:
async is a hard area where AI output should be a starting point for
human+AI iteration, not held to a "perfect on first try" bar. Most of
this PR's new content was regen-specific "keep things stable when
rewriting" directives, disproportionate for a skill whose SKILL.md is
otherwise written entirely for the common case (writing a new
integration). 8 of the 12 new sections fell into this category.

Collapsed all 8 into a single "editing an existing module" note per
file (3 files), each a few sentences: read the current file, preserve
what's there unless you have a reason to change it, applies to
super()/package/class-set/ordering/dependencies/test-source-sets alike.
Kept exactly one concrete example (ReactorContextBridge — the
highest-stakes case, since dropping it silently breaks sibling modules
that reference the class by FQN) instead of one narrated failure story
per rule. Net: ~365 lines added by the PR, ~200 removed here.

The 4 sections that are genuine new async-instrumentation content
(library-native context maps / *ContextBridge pattern, wrap-placement
memory considerations, no-inline-advice-comments, no-banner-comments)
are unchanged — those aren't regen-specific, they apply to any reactive
library instrumentation, new or edited.

Also addresses the Datadog Autotest P1 finding (2026-07-21): the new
rules existed in reference files but SKILL.md's per-step pointers were
generic ("read this file") rather than pointing at the specific new
subsections. Added explicit pointers at Steps 4.1, 5, 7, and 9.2/9.3 so
a code-gen LLM sees "read the ContextBridge section" / "add the
namespace-isolation fail block" inline in its step-by-step flow instead
of needing to discover them by skimming a 200+ line reference file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@dd-octo-sts dd-octo-sts Bot added the tag: ai generated Largely based on code generated by an AI or LLM label Jul 23, 2026
@jordan-wong
jordan-wong requested a review from Copilot July 23, 2026 19:09

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 22d970969a

ℹ️ 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .agents/skills/apm-integrations/references/tests.md Outdated
Comment thread .agents/skills/apm-integrations/references/context-tracking.md Outdated
Comment thread .agents/skills/apm-integrations/references/context-tracking.md Outdated
Comment thread .agents/skills/apm-integrations/SKILL.md Outdated
Comment thread .agents/skills/apm-integrations/references/context-tracking.md Outdated
…ified against dd-trace-java source

Codex flagged (2026-07-23) that the previous fix broadening the
ContextBridge rule beyond Reactor invented plausible-sounding but
factually wrong specifics for 3 libraries. Verified each claim against
actual dd-trace-java modules before fixing:

- JAX-RS: SKILL.md listed it as needing a ContextTracking bridge, but
  AbstractRequestContextInstrumentation extends InstrumenterModule.Tracing
  — it's span-owning code, not context-tracking. Removed the JAX-RS
  mention from SKILL.md and context-tracking.md entirely.

- Kotlin coroutines: told agents to key a ContextStore by
  Continuation/CoroutineContext, but KotlinCoroutinesModule has no
  contextStore() at all — it uses ThreadContextElement
  (DatadogThreadContextElement implements ThreadContextElement<Context>).
  Corrected to point at the actual pattern.

- Vert.x: told agents to key by io.vertx.core.Context, but that type is
  shared across many handler executions on the same Vert.x context —
  existing vertx-web instrumentation keys per-request state on
  RoutingContext instead. Keying by core Context would cause
  cross-request parentage. Corrected to point at RoutingContext.

- Reactor wrap-placement: the "prefer subscriber over publisher key"
  guidance implied these were alternatives, but master's
  ReactorCoreModule.contextStore() keys BOTH Publisher (via
  HandoffContext, read before a subscriber exists) AND Subscriber (via
  Context, for the wrapping pattern) — they're complementary, not a
  choice. Reworded so the publisher-keyed store is called out as exempt
  from the "prefer bounded lifetime" optimization.

Also fixed a latestDepTest gap Codex found: the prior wording said to
put removed-in-latest-version tests in src/test/, but that's only safe
when the module uses addTestSuite('latestDepTest') with separate
sources. Modules using addTestSuiteForDir('latestDepTest', 'test')
reuse src/test/ for both suites, so a removed-API test placed there
still gets compiled against latestDepTestImplementation and fails the
same way. Split the guidance by which build.gradle wiring the module
uses.

Root cause: the earlier fix (responding to a prior Codex comment about
Reactor-only bias) generalized to other libraries from category-level
reasoning ("JAX-RS surely uses a context map like Reactor does") rather
than reading those libraries' actual dd-trace-java modules first. Fixed
per the java-eval-research skill's canonical-first rule: don't publish
a claim about library-specific behavior without checking the source.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@jordan-wong
jordan-wong requested a review from mcculls July 23, 2026 19:53
**A context-tracking module for such a library MUST include a `*ContextBridge`-style helper** that:

1. Reads a well-known key (Datadog convention: `"dd.span"`) from the library-native context.
2. Adapts the retrieved object (which implements `WithAgentSpan` or is an `AgentSpan`) into a `datadog.context.Context`.

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.

Note an AgentSpan is already a datadog.context.Context so no cast is necessary.

This is ok for now - I'll rewrite this once all my datadog.context.Context refactorings have landed


**Reference:** `dd-java-agent/instrumentation/reactor-core-3.1/` — master has `ReactorContextBridge.java` plus four supporting instrumentations that hook the specific lifecycle points: `BlockingPublisherInstrumentation` (for `.block()` / `.blockFirst()` / `.blockLast()` on the calling thread), `ContextWritingSubscriberInstrumentation` (for `.contextWrite(...)` subscribers at subscribe time), `CorePublisherInstrumentation` (for the base publisher interface handing off to downstream subscribers), and `OptimizableOperatorInstrumentation` (for Reactor's internal fused-operator optimization path). Regenerating this module without preserving these classes silently breaks downstream libraries — Spring WebFlux, Spring Kafka reactive `@KafkaListener suspend fun`, resilience4j-reactor, reactor-netty — that rely on the `dd.span` propagation path.

**How to detect the pattern in an unfamiliar library:** search the library's public API for a `Context` type with `put`/`get`/`hasKey` methods that user code can write to (as opposed to a Datadog-internal context). If such a type exists, the library has a native context map and needs a `*ContextBridge` helper. If the library instead carries context via a thread-local mechanism (e.g. Kotlin coroutines' `ThreadContextElement`) or a per-request object already used for span ownership elsewhere in the codebase (e.g. Vert.x web's `RoutingContext`), follow that library's existing pattern instead of introducing a `ContextStore`-backed bridge — read the sibling instrumentation module for that library first.

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.

Some frameworks work better with the swap approach provided by datadog.context.Context rather than attach/detach or continuations - but again, this is something I'll add in the next week or so

@mcculls mcculls 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.

LGTM - thanks for the cleanup

I added a small note to remind myself to add a section about datadog.context.Context going forwards, and its use in async frameworks or anything requiring continuations,

@jordan-wong
jordan-wong enabled auto-merge July 24, 2026 10:32
@jordan-wong jordan-wong added tag: no release notes Changes to exclude from release notes type: documentation comp: tooling Build & Tooling labels Jul 24, 2026
@jordan-wong jordan-wong changed the title skill(apm-integrations): async cycle iteration-2 — 13 rules from #11939/#11940 review feedback skill(apm-integrations): async instrumentation category - add rules from review feedback Jul 24, 2026
@jordan-wong jordan-wong changed the title skill(apm-integrations): async instrumentation category - add rules from review feedback skill(apm-integrations): async instrumentation - add rules from review feedback Jul 24, 2026
@pr-shepherd-6ad11f

Copy link
Copy Markdown

PR Shepherd is now watching this PR: fixing basic CI failures, rebasing when it falls behind, and re-queueing after transient merge-queue failures. To disable it, add the pr-shepherd:ignore label.

If you have any questions, reach the team in #ai-devx-flow.

@dd-octo-sts

dd-octo-sts Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

/merge

@gh-worker-devflow-routing-ef8351

gh-worker-devflow-routing-ef8351 Bot commented Jul 27, 2026

Copy link
Copy Markdown

View all feedbacks in Devflow UI.

2026-07-27 06:48:45 UTC ℹ️ Start processing command /merge


2026-07-27 06:48:50 UTC ℹ️ MergeQueue: pull request added to the queue

The expected merge time in master is approximately 1h (p90).


2026-07-27 07:41:58 UTC ℹ️ MergeQueue: This merge request was merged

@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Jul 27, 2026
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot merged commit 5a8dcc6 into master Jul 27, 2026
611 of 618 checks passed
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854d Bot deleted the feat/skill-async-iteration-2 branch July 27, 2026 07:41
@github-actions github-actions Bot added this to the 1.65.0 milestone Jul 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: tooling Build & Tooling tag: ai generated Largely based on code generated by an AI or LLM tag: no release notes Changes to exclude from release notes type: documentation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants