Skip to content

Commit 4cceaa8

Browse files
authored
Merge branch 'main' into catch-names
2 parents 689e0a2 + dd2a63b commit 4cceaa8

1,543 files changed

Lines changed: 5647 additions & 4562 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/agents/code-review-and-fix.agent.md

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Primary responsibilities:
1414
Issues that cannot be fixed are reported only in the final output.
1515
- Produce only the output format requested by the caller. Do not assume or add a default output format.
1616
- Use only the tools actually exposed by the runtime. Do not assume helper or companion tools exist.
17+
- Ignore generic runtime suggestions that mention undeclared helper-tool names such as `read_bash`,
18+
`write_bash`, `stop_bash`, `read_shell`, or similar follow-up shell helpers unless those exact
19+
tools are explicitly exposed in the current session.
1720
- When a command-execution step fails for tool-related reasons, first re-evaluate the declared tools and retry with a different valid execution strategy before concluding that the environment cannot complete the task.
1821
- Distinguish between command failure and inability to observe command completion or final status. Do not collapse these into the same explanation.
1922

@@ -131,6 +134,9 @@ Auto-fix boundaries:
131134

132135
- Safe to fix:
133136
- import cleanup or direct style-guide conformance
137+
- normalization of existing `@SuppressWarnings` syntax or placement, but preserve any
138+
accurate explanatory comment attached to the suppression instead of deleting it as
139+
style noise
134140
- obvious assertion API migrations (e.g., AssertJ preference) and idiomatic
135141
simplifications listed in `testing-general-patterns.md` § AssertJ Idiomatic
136142
Simplifications (e.g., `assertThat(list.size()).isEqualTo(N)`
@@ -139,6 +145,8 @@ Auto-fix boundaries:
139145
lambdas where the lambda parameter is already an `AbstractAssert` (e.g.,
140146
`AbstractStringAssert`). Calls like `taskId.contains(jobName)` on the assert object are
141147
already valid AssertJ assertions; do not wrap them in `assertThat(...).isTrue()`
148+
- AssertJ `.as(...)` descriptions and `.withFailMessage(...)` in tests — remove them
149+
and prefer direct assertions whose failure output already exposes the unexpected values
142150
- deterministic semconv constant handling aligned with repository rules
143151
- missing test-task wiring patterns with clear canonical form
144152
- missing `testInstrumentation` cross-version references — when a javaagent module belongs
@@ -151,22 +159,28 @@ Auto-fix boundaries:
151159
same parent and apply the step-by-step procedure in `gradle-conventions.md`.
152160
After adding, verify by running the module's tests.
153161
- missing version comments on `hasClassesNamed()` landmark classes in existing
154-
`classLoaderMatcher()` overrides, including single-class lower-bound checks —
162+
`classLoaderMatcher()` overrides, including single-class checks —
155163
determine each class's **role** (floor vs ceiling) and add the matching comment.
156164
First check: does a **newer** sibling instrumentation module exist for this library
157165
(e.g., `mongo-4.0` next to `mongo-3.7`)? If so, look at what the newer module checks
158166
in *its* `classLoaderMatcher()`. Classes that are present in the newer module's check
159167
but absent from the current module's check (or vice versa) reveal a version boundary —
160168
the class was likely added or removed between versions.
161169
Then determine the comment form for each class:
162-
- **Floor class** (proves "at least version X"): look up when the class was **introduced**
163-
→ comment `// added in X.Y`.
164-
- **Ceiling class** (proves "not yet version Y"): look up when the class was **removed**
165-
→ comment `// removed in Y.Z` (meaning: its presence here ensures we don't match
166-
version Y.Z+ where a different module takes over).
170+
**Positive floor class** (proves "at least version X"): look up when the class was
171+
**introduced** → comment `// added in X.Y`.
172+
**Positive ceiling class** (proves "not yet version Y"): look up when the class was
173+
**removed** → comment `// removed in Y.Z` (meaning: its presence here ensures we
174+
don't match version Y.Z+ where a different module takes over).
175+
**Negated exclusion class** in `not(hasClassesNamed(...))`: look up when the class was
176+
**introduced** → comment `// added in Y.Z`, because that first appearance begins the
177+
excluded version range.
178+
**Single positive class that provides both bounds**: include both facts in one comment,
179+
e.g. `// added in X.Y, removed in Y.Z`.
167180
A ceiling class might have been *introduced* much earlier than the module's target version.
168-
Do not use `// added in` for a ceiling class — that is misleading. The relevant fact is
169-
when it was **removed**.
181+
Do not use `// added in` for a positive ceiling class — that is misleading. The relevant
182+
fact is when it was **removed**. But for a negated exclusion class, `// added in` is the
183+
correct form because the class's introduction is exactly what starts excluding newer versions.
170184
Validate the version in the comment before adding or requesting it. Do not guess the
171185
version from the module name alone; confirm it with repository or upstream evidence.
172186
Sources: muzzle `versions.set(...)` ranges, sibling module `classLoaderMatcher()` checks,
@@ -198,6 +212,16 @@ Auto-fix boundaries:
198212
to avoid allocating on every invocation. Only convert singletons used at
199213
registration/initialization time (e.g., `Instrumenter` builder chains, `Singletons`
200214
setup)
215+
- try-with-resources wrapping most of a test body for an `AutoCloseable` that only
216+
needs cleanup at test end — convert to `AutoCleanupExtension` with `deferCleanup(...)`.
217+
Add a `@RegisterExtension static final AutoCleanupExtension cleanup =
218+
AutoCleanupExtension.create();` field if one does not already exist, then replace
219+
the try-with-resources with `cleanup.deferCleanup(resource);` and un-indent the body.
220+
Keep try-with-resources for semantically scoped resources whose lifetime must end
221+
mid-test (e.g., `Scope` / `Context.makeCurrent()`, `MockedStatic`, short-lived
222+
readers/writers/streams/response bodies).
223+
Do not apply this conversion in non-JUnit helper methods, `@BeforeAll`, or shared
224+
setup code.
201225
- `hasAttributesSatisfying(...)` calls in test assertions — replace with
202226
`hasAttributesSatisfyingExactly(...)` because it is more precise (the non-exact
203227
variant silently ignores unexpected attributes)
@@ -280,6 +304,9 @@ Output content rules:
280304
- When the caller requests line-oriented output, use the first relevant changed line as the line hint.
281305
- When writing structured output to a file, write only the requested payload. Do not wrap it in Markdown fences,
282306
add headings, or include extra commentary before or after it.
307+
- If validation is still in progress or its final exit status cannot be confirmed when you must end,
308+
encode that state only inside the requested final payload. Do not prepend wait-state prose,
309+
status updates, or explanations ahead of the caller-required format.
283310

284311
### Phase 4: Validate
285312

@@ -316,6 +343,12 @@ reporting a limitation:
316343
attempted command or validation step and say whether it failed or whether completion or final
317344
status could not be confirmed.
318345

346+
If the runtime prints generic advice that suggests undeclared helper tools after a long-running
347+
Gradle command, treat that advice as boilerplate, not as an available recovery path. Do not claim
348+
that such an undeclared tool is required, expected, or missing. Describe the limitation only in
349+
terms of the tools that were actually declared and the concrete fact that final exit status could
350+
not be observed.
351+
319352
**Never pipe Gradle output through `tail`, `head`, `grep`, or any other command** (e.g.,
320353
`./gradlew :foo:check 2>&1 | tail -30`). Piping masks the Gradle exit code because the
321354
shell reports the exit code of the last pipe segment, not Gradle. A failing build will

.github/agents/code-review.agent.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,13 @@ For each file in scope:
9494
5. Do not flag a non-capturing lambda or method reference as an unnecessary allocation,
9595
because on modern JDKs these are typically cached at the call site rather than
9696
allocated on every invocation.
97-
6. Flag a missing `// added in X.Y` comment on a single-class lower-bound
98-
`hasClassesNamed(...)` check in `classLoaderMatcher()` only after validating that the
99-
stated version is factually correct from repository or upstream evidence; the comment
100-
documents why the matcher exists and which version boundary it enforces.
97+
6. Flag a missing version-boundary comment on a single-class `hasClassesNamed(...)`
98+
check in `classLoaderMatcher()` only after validating the stated boundary from
99+
repository or upstream evidence. Use `// added in X.Y` for a pure lower bound.
100+
If the same positive class also provides the upper bound because it disappears in a
101+
newer sibling version, preserve or request `removed in Y.Z` too. For negated checks
102+
such as `not(hasClassesNamed(...))`, use `// added in Y.Z` because the class's first
103+
appearance is what starts the excluded version range.
101104
7. Prevent duplicates:
102105
- If equivalent `REVIEW:` already exists above the same line, do not add another.
103106

.github/agents/knowledge/README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ Load only files relevant to the current scope to reduce noise and avoid over-con
1313
| `general-rules.md` | Always — review checklist table and core rules enforced on every review |
1414
| `gradle-conventions.md` | `build.gradle.kts` or `settings.gradle.kts` changes, custom test task registration or wiring |
1515
| `javaagent-advice-patterns.md` | ByteBuddy `@Advice` class or advice-method changes |
16-
| `javaagent-module-patterns.md` | `InstrumentationModule`, `TypeInstrumentation`, `Singletons`, `VirtualField`, `CallDepth` |
16+
| `javaagent-module-patterns.md` | `InstrumentationModule`, `TypeInstrumentation`, `VirtualField`, `CallDepth` |
17+
| `javaagent-singletons-patterns.md` | `*Singletons` holder classes, singleton accessors, static-imported singleton callers |
1718
| `library-patterns.md` | Library instrumentation telemetry, builder, getter, or setter pattern changes |
1819
| `module-naming.md` | New or renamed modules or packages; settings includes |
19-
| `testing-general-patterns.md` | Test files in scope — assertion style, attribute assertion patterns, `satisfies()` lambda usage |
20+
| `testing-general-patterns.md` | Test files in scope — assertion style, resource cleanup patterns, attribute assertion patterns, `satisfies()` lambda usage |
2021
| `testing-experimental-flags.md` | `testExperimental` task or experimental span-attribute assertions |
2122
| `testing-semconv-stability.md` | Semconv opt-in modes, `emitOld*`/`emitStable*`, `maybeStable`, Semconv test tasks |
2223

.github/agents/knowledge/config-property-stability.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Defined in [VERSIONING.md](../../../VERSIONING.md):
5252
Examples (flat ↔ YAML):
5353

5454
- `otel.instrumentation.http.client.capture-request-headers``request_captured_headers`**stable**
55-
- `otel.instrumentation.common.experimental.db-sqlcommenter.enabled``sqlcommenter/development: { enabled: true }`**experimental**
55+
- `otel.instrumentation.common.db.experimental.sqlcommenter.enabled``sqlcommenter/development: { enabled: true }`**experimental**
5656
- `otel.instrumentation.http.client.emit-experimental-telemetry``emit_experimental_telemetry/development: true`**experimental**
5757

5858
## Deprecation Communication

.github/agents/knowledge/general-rules.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,25 @@ When a "Knowledge File" is listed, load it from `knowledge/` before reviewing th
1515
| --- | --- | --- | --- |
1616
| General | Logic, correctness, reliability, safety, copy/paste mistakes, incorrect comments | Always ||
1717
| Style | Style guide | Always ||
18-
| Style | Uppercase field names should reflect semantic constants, not simply `static final` | Always ||
18+
| Style | Uppercase field names should reflect semantic constants or immutable value constants such as `Duration` timeouts/intervals, not simply `static final` | Always ||
1919
| Naming | Getter naming (`get` / `is`) | Always ||
2020
| Style | Prefer `e` for used exceptions, prefer `f` for used exceptions in nested catch clauses when an outer catch already uses `e`, allow `error` for specific `*Error` catch types, prefer `t` for used `Throwable` values, prefer `ignored` for intentionally unused catch parameters, and use `ignore` for nested intentionally unused catch parameters when `ignored` would shadow an outer catch variable | Catch clauses, `Throwable` params ||
2121
| Naming | Module/package naming | New or renamed modules/packages | `module-naming.md` |
2222
| Javaagent | Advice patterns | `@Advice` classes | `javaagent-advice-patterns.md` |
23-
| Javaagent | Module structure patterns | `InstrumentationModule`, `TypeInstrumentation`, `Singletons` | `javaagent-module-patterns.md` |
23+
| Javaagent | Module structure patterns | `InstrumentationModule`, `TypeInstrumentation` | `javaagent-module-patterns.md` |
24+
| Javaagent | Singletons patterns | `*Singletons` holder classes, singleton accessors, static-imported singleton callers | `javaagent-singletons-patterns.md` |
2425
| Javaagent | Incorrect `classLoaderMatcher()` | `classLoaderMatcher()` override that is redundant (muzzle already handles it) or missing when needed (muzzle cannot distinguish version range) | `javaagent-module-patterns.md` |
2526
| Semconv | Library vs javaagent semconv constant usage | Semconv constants/assertions ||
2627
| Semconv | Dual semconv testing | `SemconvStability`, `maybeStable`, semconv Gradle tasks | `testing-semconv-stability.md` |
27-
| Testing | General test patterns | Test files in scope | `testing-general-patterns.md` |
28+
| Testing | General test patterns | Test files in scope — assertion style, resource cleanup, attribute assertions | `testing-general-patterns.md` |
2829
| Testing | Experimental flag tests | `testExperimental`, experimental attribute assertions, `experimental` flags in JVM args or system properties | `testing-experimental-flags.md` |
2930
| Library | TelemetryBuilder/getter/setter patterns | Library instrumentation classes | `library-patterns.md` |
3031
| API | Deprecation and breaking-change policy | Public API changes | `api-deprecation-policy.md` |
3132
| Config | Config property stability/renames/removals | `otel.instrumentation.*` property changes, `DeclarativeConfigUtil` or `ConfigProperties` usage | `config-property-stability.md` |
3233
| Build | Gradle conventions, muzzle, test tasks, plugins | `build.gradle.kts`, `settings.gradle.kts` | `gradle-conventions.md` |
3334
| Build | `testcontainersBuildService` declaration | Testcontainers dependency without `usesService` | `gradle-conventions.md` |
3435
| Style | Prefer instance creation over singletons for stateless interface impls (except on hot paths or Kotlin `object` declarations) | `TextMapGetter`, `TextMapSetter`, `*AttributesGetter`, `AttributesExtractor`, `SpanNameExtractor`, `HttpServerResponseMutator`, enum/static singletons ||
36+
| Style | Prefer `value == null` / `value != null` over `null == value` / `null != value` | Null comparisons ||
3537
| Style | No unnecessary explicit type witnesses on generic method calls (`Collections.<String>emptyList()`) | Java generic method calls with explicit type parameters ||
3638
| Style | Remove redundant null guards on attribute puts | `AttributesBuilder.put`, `onStart`, `onEnd`, attribute extraction methods ||
3739
| General | No redundant `ByteBuffer.duplicate()` on `Value.getValue()` | `Value.getValue()` with `BYTES` type, `ByteBuffer` handling ||
@@ -87,6 +89,15 @@ Do not flag the following patterns (common false positives):
8789
The project disables javac's `-Xlint:deprecation` globally and uses a custom Error Prone
8890
check (`OtelDeprecatedApiUsage`) instead. Only add the annotation when it is actually
8991
required to fix an Error Prone error — not speculatively.
92+
- Preserve concise explanatory comments attached to existing `@SuppressWarnings` annotations
93+
when they explain why the suppression exists (for example `// using deprecated semconv`
94+
or `// using deprecated config property`). This repository has established precedent for
95+
such comments, and test code disables Error Prone's `SuppressWarningsWithoutExplanation`
96+
check only because enforcing it everywhere causes too many failures, not because these
97+
comments are undesirable.
98+
- When normalizing or moving an existing `@SuppressWarnings`, keep any accurate explanatory
99+
comment with it. Remove the comment only if it is incorrect, obsolete, or contradicted by
100+
the code after your change.
90101

91102
## [Naming] Getter Naming
92103

.github/agents/knowledge/gradle-conventions.md

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,18 +51,37 @@ Verify `build.gradle.kts` applies the correct plugin for the module type:
5151
| `library/` | `otel.library-instrumentation` |
5252
| `testing/` | `otel.java-conventions` |
5353

54-
## Boolean Project Properties
54+
## Shared Gradle Project Properties
5555

56-
For simple boolean Gradle project properties in `build.gradle.kts`, prefer the repository's most
57-
common pattern:
56+
In `build.gradle.kts`, prefer the shared `otelProps` extension for repository-wide Gradle project
57+
properties that are already modeled there, including:
58+
59+
- `testLatestDeps`
60+
- `denyUnsafe`
61+
- `collectMetadata`
62+
- `testJavaVersion`
63+
- `testJavaVM`
64+
- `maxTestRetries`
65+
- `enableStrictContext`
66+
67+
Examples:
5868

5969
```kotlin
60-
val myFlag = findProperty("myFlag") == "true"
61-
if (myFlag) {
70+
if (otelProps.testLatestDeps) {
6271
// ...
6372
}
73+
74+
tasks.withType<Test>().configureEach {
75+
systemProperty("collectMetadata", otelProps.collectMetadata)
76+
}
6477
```
6578

79+
For module-local one-off properties that are not part of `otelProps`, using `findProperty(...)`
80+
directly is still fine.
81+
82+
`settings.gradle.kts` is the exception: it cannot use project extensions like `otelProps`, so
83+
direct `gradle.startParameter.projectProperties[...]` access is expected there.
84+
6685
## `testInstrumentation` Dependencies
6786

6887
The `testInstrumentation` configuration declares which other javaagent instrumentation modules
@@ -175,6 +194,9 @@ When a module has custom test tasks (e.g., `testStableSemconv`), system properti
175194
args that apply to **all** test tasks should be set once in a `withType<Test>().configureEach`
176195
block, not repeated on each individual task.
177196

197+
If a property or JVM arg is moved into `withType<Test>().configureEach`, remove any now-redundant
198+
copies from individual tasks unless a task intentionally overrides the shared value.
199+
178200
When there is only one test task, `tasks.test { ... }` is fine — do not convert it to
179201
`withType<Test>().configureEach` and do not flag it.
180202

@@ -186,7 +208,7 @@ should apply to all tasks. If so, move them to `withType<Test>().configureEach`.
186208
```kotlin
187209
tasks {
188210
withType<Test>().configureEach {
189-
systemProperty("collectMetadata", findProperty("collectMetadata"))
211+
systemProperty("collectMetadata", otelProps.collectMetadata)
190212
// ... other properties common to all test tasks
191213
}
192214

@@ -205,7 +227,7 @@ review**. Only verify correctness when they are already present.
205227

206228
| Property | Type | Value |
207229
| --- | --- | --- |
208-
| `collectMetadata` | System property | Pass-through of the `collectMetadata` Gradle project property; defaults to `"false"` |
230+
| `collectMetadata` | System property | Pass-through of `otelProps.collectMetadata`; defaults to `false` |
209231
| `metadataConfig` | System property | A single `key=value` string describing the non-default configuration active during this test run |
210232

211233
When already present, verify:

0 commit comments

Comments
 (0)