semantic-conventions-upgrade
Skill679 starsChanged 50 days agoApache-2.0View on GitHub
Upgrade the OpenTelemetry semantic conventions version that a component in opentelemetry-dotnet-contrib targets (or bump the generated SemanticConventions package). Use when asked to update, bump, migrate or adopt a new semantic conventions version, change a schema URL, or align an instrumentation or resource detector with newer semantic conventions.
In this repository3 other files it gives its agents.
- AGENTS.mdAGENTS.md
- code-reviewSkill
- performance-benchmarkSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
38 rules. About 0 are common, 20 are distinctive, and 18 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈20
Distinctive · estimate
This author's own choices. Worth a look.
18
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
Use this skill when moving a component under src/ from one version of the OpenTelemetry Semantic Conventions to another, or when bumping …
- Very specific: line 21
Every instrumentation scope created via ActivitySourceFactory or MeterFactory, and every Resource created with a schema URL, declares a …
- Distinctive: line 50
Do not mix kinds A, B and C in a single PR unless the user asks.
- Distinctive: line 56
Find every declared version in the component: Do not assume there is one.
- Distinctive: line 71
Every one must be accounted for and deliberately kept or changed.
- Very specific: line 114
Use the Weaver version that test/Shared/weaver.Dockerfile pins, or newer if the target registry requires it (v1.45.0 needed v0.28.0 for …
- Distinctive: line 137
Every version in the range must have at least one row, even if the row says "nothing relevant, checked X, Y and Z".
- Distinctive: line 143
Do not stop at attribute renames.
- Very specific: line 187
Check the timing of attributes.
- Very specific: line 189
Check every TFM. #if NETFRAMEWORK/#if NET code paths can often write the same attributes in different places (WCF client vs server, Http …
- Distinctive: line 199
Read the README attribute/metric tables.
- Distinctive: line 221
If a design question has more than one reasonable answer (default behavior, omit vs.
- Very specific: line 260
Create separate versioned scopes: old (previous version), new (target version) and "both" (schema URL null, because the output matches no …
- Distinctive: line 267
Only bump the declared version of the new path when the library is in old-by-default mode.
- Very specific: line 281
New selectable version enums (AWS): add the new member (V1_45_0), make Latest resolve to it, update the public API files, and do not change …
- Distinctive: line 288
If any item in the range is unmet or deferred, the component's declared version must not be bumped.
- Very specific: line 300
Version constants: Update every constant found in Step 1, keeping shared constants shared.
- Very specific: line 303
Generated constants: Prefer the generated attribute classes from OpenTelemetry.SemanticConventions when the component references that …
- Very specific: line 312
Package references: Keep to the minimal OpenTelemetry package (OpenTelemetry.Api where possible) per AGENTS.md.
- Distinctive: line 318
Recommended and Opt-in attributes: Only add new Public API surface for attributes that are recommended or opt-in according to the semantic …
- Distinctive: line 332
Shared metrics: When several old instruments collapse into one new instrument, producers and consumers share it.
- Very specific: line 375
Keep suppressAdvice entries minimal, each linked to an upstream issue.
- Very specific: line 383
When a Weaver test fails with Expected: 0 Actual: 1, look at the Weaver output for download or parse errors first.
- Very specific: line 393
README: update the semantic-conventions/blob/v<version>/...
- Distinctive: line 406
Update attribute and metric tables and any footnotes describing conditional behavior, and describe the opt-in environment variable values …
- Distinctive: line 423
Every component touched gets its own entry.
- Distinctive: line 428
Run in order and report outcomes faithfully, including anything not run:
- Distinctive: line 441
Run the Weaver tests if Docker is available.
- Very specific: line 448
Update SEMCONV_VERSION (and GENERATOR_VERSION if needed) in both src/OpenTelemetry.SemanticConventions/scripts/generate.sh and generate.ps1.
- Very specific: line 451
If the target registry uses features the pinned Weaver does not understand (for example unref), bump the generator and also update …
- Very specific: line 455
Run the script (needs Docker) and review the full diff in Attributes/ and .publicApi/PublicAPI.Unshipped.txt: additions, removals and …
- Distinctive: line 458
Search the repository for usages of any removed or renamed member and fix them.
- Distinctive: line 460
Add the CHANGELOG entry and keep the scripts' version consistent with whatever the README of the package claims.
- Very specific: line 465
Follow .github/PULL_REQUEST_TEMPLATE.md and the AI disclosure rules in AGENTS.md.
- Distinctive: line 471
Call out every observable behavior change and whether the default changes.
- Very specific: line 472
When editing the description after it was first posted, fetch the current body from GitHub (gh pr view N --json body -q .body), apply a …
- Distinctive: line 477
Do not push, open PRs or change repository visibility without the user's confirmation.
- Distinctive: line 482
Before declaring the work done, confirm each of these:
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Semantic Conventions Upgrade
Use this skill when moving a component under src/ from one version of the
OpenTelemetry Semantic Conventions
to another, or when bumping the generated
OpenTelemetry.SemanticConventions package. It is also a good checklist for
any change that alters the attributes, metrics, span names or span kinds a
component emits.
The goal is a change that is correct the first time. Most mistakes in past upgrades came from the same few causes, which are called out as Lessons throughout and summarised in the final checklist.
Core principle: the declared version is a claim
Every instrumentation scope created via ActivitySourceFactory or
MeterFactory, and every Resource created with a schema URL, declares a
semantic conventions version. That version becomes the telemetry schema URL
(https://opentelemetry.io/schemas/<version>) which tells backends how to
interpret the data.
[!IMPORTANT] Only declare a version when what the component emits actually matches that version. Bumping the constant is the last step, after the behavior has been verified or changed, never a first step and never a no-op.
Per REVIEW.md, the instrumentation scope must carry both a Version and a
SchemaUrl. When the supported semantic convention version changes, update the
SchemaUrl (via the declared constant); the scope Version stays the
package's own version.
Step 0: Classify the change
Decide which of these you are doing; they have different rules and often belong in separate PRs (one PR per concern, one CHANGELOG entry per affected component).
| Kind | Example | Notes |
A. Regenerate OpenTelemetry.SemanticConventions | [SemanticConventions] Bump to v1.45.0 | Mechanical; see Generated package. Land first. |
| B. Declared-version bump only | [Repo] Update declared semantic conventions version | Only for components where nothing emitted changes. Needs evidence (Step 2). |
| C. Behavioral migration | ConfluentKafka, WCF, gRPC, Elasticsearch, Redis | Attributes, names, kinds, metrics change. Needs a compatibility strategy (Step 4). |
| D. New selectable version | AWS SemanticConventionVersion.V1_45_0 | Adds an option; the default must not change. |
Do not mix kinds A, B and C in a single PR unless the user asks. Components that need design decisions should never be held up by, or hidden inside, a PR that bumps unrelated components.
Step 1: Establish the starting point
Find every declared version in the component. Do not assume there is one.
grep -rnE "SemanticConventionsVersion|new\(1, [0-9]+, 0\)|new Version\(1, [0-9]+" src/OpenTelemetry.<Type>.<Name> grep -rnE "semantic-conventions/(blob|tree)/v[0-9.]+" src/OpenTelemetry.<Type>.<Name>Components can have several: separate constants for traces and metrics (Owin), different constants for the old and new opt-in paths (EntityFrameworkCore: old
1.24.0, new1.36.0before the bump), per-TFM implementations (Http:HttpWebRequeston .NET Framework vsDiagnosticSourcehandlers), shared constants referenced across files (Kusto: one constant shared byActivitySourceandMeterso they cannot drift), and resource detectors that pass the version toSchemaUrls.Get. Every one must be accounted for and deliberately kept or changed.- Find what the README claims. README links to
semantic-conventions/blob/vX.Y.Z/...are frequently stale or already disagree with the code (for example the Http README linkedv1.40.0while the code declared1.41.0). Treat them as documentation to update, never as evidence of what the code does. - Record the range. The upgrade is from current declared version to
target version, e.g.
1.41.0 -> 1.45.0. List every released tag in between (1.42.0,1.43.0,1.44.0,1.45.0).
[!NOTE] Lesson: the range matters, not just the target. A component moving from
1.41.0to1.45.0must account for the changes in1.42.0,1.43.0,1.44.0and1.45.0. The release notes and schema file of the target version describe only that step. A rename made in1.43.0that the component never adopted is still owed by the time it declares1.45.0, and a change introduced in1.42.0and partially reverted in1.44.0must be judged on the net result. Never review only the latest version's diff.
Step 2: Gather the changes for every version in the range
For each version in the range, collect changes from all of these sources. Using only one source misses things.
- Schema file.
schemas/<version>in the semantic-conventions repo is the authoritative list of attribute and metric renames per version. Read every file in the range, not only the target. - Release notes and changelog for each tag
(
https://github.com/open-telemetry/semantic-conventions/releases/tag/vX.Y.Z). Scan for the signals the component emits (HTTP, DB, RPC, messaging, FaaS, cloud, host, process, runtime, etc.), including deprecations, stability changes and requirement-level changes. Resolved registry diff. Resolve the registry at the current and target tags with Weaver and diff the output. This catches changes the schema file does not: type changes, requirement level changes, new attributes, enum member changes, units, span kinds, instrument types.
git clone --depth 1 --branch v1.45.0 https://github.com/open-telemetry/semantic-conventions sc-1.45.0 docker run --rm -v "$PWD/sc-1.45.0/model:/source" otel/weaver:v0.28.0 \ registry resolve --registry /source --format json > resolved-1.45.0.jsonUse the Weaver version that
test/Shared/weaver.Dockerfilepins, or newer if the target registry requires it (v1.45.0 needed v0.28.0 forunref). Run it against the starting tag too and diff the two JSON files, filtered to the relevant groups.- The docs themselves. Weaver's resolved v1 JSON does not show v2
refinement spans, so a span's name format, span kind, sampling-relevant
attributes and conditional requirement text can only be seen by diffing the
markdown under
docs/<area>/between the two tags. Do this for every page the component implements (for exampledocs/db/database-spans.md,docs/db/database-metrics.md,docs/messaging/kafka.md). - Dependent conventions. Common attributes (
server.*,network.*,error.type,url.*) and per-technology pages (docs/db/sql-server.md,docs/db/redis.md, ...) can change independently of the area page.
Produce a table per version (this goes in the PR description or a scratch file, and the final PR should summarise it):
| Version | Change | Affects this component? | Evidence / decision |
| 1.42.0 | rpc.method now service/method | Yes | Qualified name emitted; tests updated |
| 1.43.0 | (nothing relevant) | No | Checked schema, release notes, docs diff |
| 1.44.0 | ... | ... | ... |
Every version in the range must have at least one row, even if the row says "nothing relevant, checked X, Y and Z". An empty cell means the version was not reviewed.
Categories of change to look for
Do not stop at attribute renames. Previous upgrades turned up each of these:
- Renames and removals:
messaging.system->messaging.system.name,messaging.kafka.*->kafka.*,faas.invocation_id->faas.invocation.id,net.peer.*->server.*. - Enum value changes: the SQS system value
aws_sqs->aws.sqs. - Type changes: an
intattribute becoming astring(Kafkadestination.partition.id, RPCrpc.response.status_code). PerREVIEW.md, attribute values must match the specified type. - Requirement-level changes: attributes becoming
Required,Conditionally RequiredorOpt-In; conditions changing; values that must now be omitted (Kusto:server.portis not recorded when it is the default port for the scheme). - Span name format:
send {topic},{operation} {target}, low-cardinality rules. - Span kind: the Kafka poll span is
Client, notConsumer; AWS single-messageSendMessage/PublishbecameProducerwhile batch operations stayClient. - Status and error handling:
error.typevalues and when the span status is set, and what goes in the status description. - Metric changes: renamed or merged instruments (Kafka publish/receive
duration collapsing into one
messaging.client.operation.duration), units, instrument type, required attributes and bucket advice. - Semantics of an unchanged attribute:
server.addressin the database conventions changed meaning (the configured address, with the contacted node moving tonetwork.peer.*), which an unchanged attribute name would hide. - Newly required or recommended attributes the component can now provide.
- Deprecations of attributes the component emits. Deprecation alone does
not make an attribute invalid at the target version: check the target
area's requirement level and migration notice. For example, the AWS SDK
span conventions at v1.45.0 still mark the deprecated
rpc.systemasRequiredandrpc.serviceasRecommended. Replace an attribute only when the area's conventions no longer require or recommend it, or the notice says to; otherwise keep it and note the decision in the per-version table.
Step 3: Inventory what the component actually emits
You cannot judge a change without knowing the current output.
- Grep for attribute constants and literals: the generated
Attribute*classes, the hand-writtenSemanticConventions.csconstants insrc/Sharedand per-component files, and raw"db."/"rpc."/"messaging."strings. - List span names, span kinds, status mapping, metric names, units, instrument types and their tag sets.
- Check the timing of attributes. Sampling-sensitive attributes must be set
before the activity starts (
REVIEW.md). - Check every TFM.
#if NETFRAMEWORK/#if NETcode paths can often write the same attributes in different places (WCF client vs server, Http handlers vsHttpWebRequest). - Check for native instrumentation. On newer runtimes parts of the telemetry are emitted by the framework itself (HttpClient on .NET 9+, ASP.NET Core). The library must not change or override native attributes, and the framework's version of the conventions governs them. Make sure that claiming a newer version is honest for what the library itself emits, and that the sibling/library-created activities carry the same attributes as the native ones.
- Read the README attribute/metric tables; they are part of the contract and must be updated together with the code.
[!NOTE] Lesson: look at how the library gets its data before promising an attribute. The StackExchange.Redis
server.addresschange needed a design decision because the library only knows the contacted node, not the configured address. ElasticsearchClient could not honestly emitdb.operation.namebecause NEST does not expose the endpoint identifier. The SqlClient payload has no row count except through the statistics dictionary. If the data is not available, omit the attribute and say so rather than guess or derive it heuristically, and confirm with the user.
Step 4: Decide what to do about each change
For each row in the Step 2 tables choose one of:
- Apply - emit the new shape.
- Not applicable - with evidence (the component does not emit it).
- Defer - with a reason, and exclude the component from the version bump (see below).
If a design question has more than one reasonable answer (default behavior, omit vs. approximate, which attribute carries which address), ask the user instead of deciding silently.
Compatibility strategy for behavior changes
Changing emitted telemetry is a breaking change for dashboards, alerts and sampling rules. Choose the strategy from the migration guidance for the convention area and the component's existing compatibility contract, not from package stability alone.
Each area's notice only applies to components that emit conventions at or before a starting version, and that version differs per area. Read it from the notice at the target tag instead of assuming one. At v1.45.0:
| Area | Opt-in values | Notice applies to components emitting |
| Database | database, database/dup | v1.24.0 or prior |
| RPC | rpc, rpc/dup | v1.37.0 or prior |
| Messaging | messaging, messaging/dup | v1.24.0 or prior |
- Read the area's migration notice at the target tag (for example
docs/db/README.md,docs/rpc/README.md). Check whether it defines anOTEL_SEMCONV_STABILITY_OPT_INvalue, what the default must be, and when the variable applies (the RPC notice limits it to the migration from experimental conventions to their initial stable version). - Read the component's existing contract: its README, CHANGELOG, options and any helper it already uses. Keep opt-ins it already ships; do not remove or reinterpret them.
- Then pick the matching case:
- Experimental to initial stable, where the notice defines opt-in values
and the component is at or before the notice's starting version: keep
the default output and use the dual-emit pattern.
- Database:
DatabaseSemanticConventionHelper. - RPC:
RpcSemanticConventionHelper. - Messaging: no shared helper exists yet; model one on the two above.
- Link the shared helper (
src/Shared) rather than copying it, and add the option properties (EmitOldAttributes/EmitNewAttributesstyle) that the other libraries use. - Create separate versioned scopes: old (previous version), new
(target version) and "both" (schema URL
null, because the output matches no single schema), e.g.ActivitySourceFactory.Create<T>(null). Pick the scope per mode. - In
dupmode, a key that exists in both shapes with conflicting values (RPC'srpc.method) needs a documented winner. Prefer the new value and document the compromise. - Only bump the declared version of the new path when the library is in old-by-default mode; the old path's version stays put (EntityFrameworkCore bumped only the database opt-in path).
- Database:
- The component already ships an opt-in contract (stable or pre-release): extend that contract. Do not replace it with a hard cutover.
- The component is past the notice's starting version, or the area
defines no opt-in value: the notice does not apply, so do not invent a
new opt-in variable. Follow the notice. A pre-release package with no
existing contract may do a hard cutover; mark it
**Breaking change**in the CHANGELOG, describe every rename, and confirm the approach with the user. - The area is already stable (for example HTTP): no new opt-in; follow the notice for any remaining migration.
- New selectable version enums (AWS): add the new member (
V1_45_0), makeLatestresolve to it, update the public API files, and do not change the default. Derive the new conventions class from the previous one and override only what changed.
- Experimental to initial stable, where the notice defines opt-in values
and the component is at or before the notice's starting version: keep
the default output and use the dual-emit pattern.
Components to leave out of a bump
If any item in the range is unmet or deferred, the component's declared version must not be bumped. State this explicitly in the PR ("Intentionally not included") with the reason, for example:
- StackExchangeRedis because the
server.addressguidance needs a design decision. - A library that maps attributes it does not own (for example an exporter
translating
messaging.system), where the effect on consumers needs separate analysis.
Step 5: Implement
- Version constants. Update every constant found in Step 1, keeping
shared constants shared. Verify with a grep afterwards that no stale
1.xxremains unintentionally. - Generated constants. Prefer the generated attribute classes from
OpenTelemetry.SemanticConventionswhen the component references that package. For components that usesrc/Shared/SemanticConventions.csor per-component constants, rename the constants and the string values, and check every use. - Emission changes. Make each change from Step 4; keep old and new paths separate and well-commented so the old path can be deleted when it is retired. Where required attribute values depend on data that may not be present (topic, partition, endpoint), set them only when known.
- Package references. Keep to the minimal OpenTelemetry package
(
OpenTelemetry.Apiwhere possible) perAGENTS.md; addsrc/Sharedfiles via linked<Compile Include>items and versions only inDirectory.Packages.props. - Public API. New public members go into
.publicApi/PublicAPI.Unshipped.txt. - Recommended and Opt-in attributes. Only add new Public API surface for attributes that are recommended or opt-in according to the semantic conventions when explicitly asked to do so by the user.
- Do not hand-edit generated files.
Gotchas to check for in the implementation
- Const value collisions. Generated constant names come from pascal-casing
the attribute id. Two different ids can produce the same name, and the
surviving value may silently change. In 1.45.0
AttributeFaasInvocationIdchanged fromfaas.invocation_idtofaas.invocation.idbecause both pascal-case to the same name. After regenerating, diff the.csfiles and thePublicAPI.Unshipped.txtfor value changes, not only added and removed members, and search consumers. - Shared metrics. When several old instruments collapse into one new instrument, producers and consumers share it; do not assume one metric per operation in tests (ConfluentKafka produced 3 distinct metric names, not 4).
- Distinct components, same attribute. Components implemented over a shared
helper (AWS, AWS Lambda and the AWS resource detectors share
src/Shared/AWS) must all be updated and tested together. - Resource detectors pass the version through
SchemaUrls.Get. Check each detector's emitted resource attributes against the range as well; a detector may need only the bump (Host, Process, OperatingSystem) or an attribute change (Gcpgcp.gce.instance.name). - Netfx quirks.
net462is the minimum framework; check any new code paths there (nullable annotations, missing BCL APIs,Activityclock differences). - Culture. Number-to-string conversions use
CultureInfo.InvariantCulture(e.g.((int)status).ToString(CultureInfo.InvariantCulture)for string status codes). - Performance. Where possible, avoid boxing value types when adding attributes
to activities or metrics, as this can introduce unnecessary allocations due to
needing to box value types to pass to the overload that accepts
object.
Step 6: Tests
- Schema URL assertions. Tests that assert the schema URL must be updated
to the constants (or the new literal) for each mode. For dual-emit, assert
the schema URL for old, new and both modes. Do not change scope
Versionexpectations: the factories set it from the package version, not the semantic conventions version. - Attribute and metric assertions per mode. For opt-in libraries, parameterise tests over the modes (Old/New/Dupe) rather than testing only the mode you changed. Assert the absence of attributes that must not be present in a given mode, including types (string vs int).
- Weaver conformance tests. Components that have a
SpecificationTests : WeaverSpecificationTestsclass validate their telemetry against the semantic conventions registry using Docker-based Weaver (test/Shared/Weaver*.cs). Pass the declared version constant (not a literal) toAssertTelemetryConformsToSemanticConventionsso that the test validates the claim being made. If the component has no such test and emits telemetry covered by the conventions, add one modelled ontest/OpenTelemetry.Instrumentation.Http.Tests/SpecificationTests.cs.- These tests are
[Trait("Category", "Weaver")]and run on a Linux Docker engine. If Docker is unavailable locally, say so explicitly in the PR instead of reporting the suite as passing. The user may be able to start Docker manually for you to run the tests. - Keep
suppressAdviceentries minimal, each linked to an upstream issue. Re-check existing suppressions when moving versions: a fixed upstream issue means the suppression should be removed. - Weaver fails silently (exit code 1, empty report) for some inputs: a
span status without a string
messageproperty, or a registry that could not be downloaded. The shared fixture handles both (it always emitsmessageand uses theansidiagnostic format); do not switch the format back togh_workflow_command, which hides non-policy errors. When a Weaver test fails withExpected: 0 Actual: 1, look at the Weaver output for download or parse errors first.
- These tests are
- Integration tests (Docker or external services, such as Kafka and SQL Server) are gated by categories/traits; run them if possible and otherwise say they were not run.
- Native vs library. On runtimes with native instrumentation, tests must not require the library to override native attributes.
Step 7: Documentation and CHANGELOG
README: update the
semantic-conventions/blob/v<version>/...links that document what the component itself now emits, using tag permalinks (nevermain, perREVIEW.md). Classify each link first:- Migrated path (what the component emits at the new version): update to the new tag, including links that were already stale.
- Legacy path (old default or old
OTEL_SEMCONV_STABILITY_OPT_INmode): keep the tag matching the version that path declares. - Runtime- or framework-owned telemetry (for example native HttpClient or ASP.NET Core instrumentation): link the version the runtime implements, not the version the library declares.
- Historical references (migration notes, comparisons with older versions): leave unchanged.
Update attribute and metric tables and any footnotes describing conditional behavior, and describe the opt-in environment variable values the library understands, where relevant.
CHANGELOG in every affected component, under
## Unreleased, new entries at the end, sentence case, ending in a period, with the PR link. Do not add a version header. Use the established wording for a plain bump:* Updated Semantic Conventions version to `1.45.0`. ([#NNNN](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/NNNN))For behavior changes, list each renamed/removed/retyped attribute or metric and prefix breaking changes with
**Breaking change**:. For a dual-emit change, say whichOTEL_SEMCONV_STABILITY_OPT_INvalues enable it.- Generated package: its CHANGELOG entry is
Updated to \v1.45.0` release of OpenTelemetry Semantic Conventions.` - Every component touched gets its own entry. Components that were deliberately skipped get none.
Step 8: Verify
Run in order and report outcomes faithfully, including anything not run:
dotnet build
dotnet test test/OpenTelemetry.<Type>.<Name>.Tests/ --no-build
dotnet format --verify-no-changes
markdownlint .- Build in Release at least once so
TreatWarningsAsErrorsand the public API analyzers run; build all target frameworks includingnet462on Windows. - Re-grep for stale versions in the component, its tests and its README.
- Re-read the diff for every constant whose value changed.
- Run the Weaver tests if Docker is available.
- Confirm no unrelated components were touched.
Generated package (OpenTelemetry.SemanticConventions)
For kind A changes:
- Update
SEMCONV_VERSION(andGENERATOR_VERSIONif needed) in bothsrc/OpenTelemetry.SemanticConventions/scripts/generate.shandgenerate.ps1. Keep them identical. - If the target registry uses features the pinned Weaver does not understand
(for example
unref), bump the generator and also updatetest/Shared/weaver.Dockerfileso the tests use a compatible version (pinned by digest; preserve that format). - Run the script (needs Docker) and review the full diff in
Attributes/and.publicApi/PublicAPI.Unshipped.txt: additions, removals and value changes (see the const collision gotcha above). - Search the repository for usages of any removed or renamed member and fix them.
- Add the CHANGELOG entry and keep the scripts' version consistent with whatever the README of the package claims.
Pull request
- Follow
.github/PULL_REQUEST_TEMPLATE.mdand the AI disclosure rules inAGENTS.md. - Describe, per version in the range, what was reviewed and the outcome.
Reviewers should be able to see that
1.42.0,1.43.0, ... were each considered, not only the last. - List any components intentionally not included and why.
- Call out every observable behavior change and whether the default changes.
- When editing the description after it was first posted, fetch the current
body from GitHub (
gh pr view N --json body -q .body), apply a minimal targeted edit and push that; never overwrite it with a locally saved copy, because maintainers may have edited it (ticked boxes, struck-out items). - Replies to PR comments and reviews are posted by the user, not by an agent.
- Do not push, open PRs or change repository visibility without the user's confirmation.
Final checklist
Before declaring the work done, confirm each of these:
- All declared versions in the component were found (traces, metrics, old/new paths, per-TFM, resource schema URLs) and each was handled.
- Every version between the current and target was reviewed, using the schema file, release notes, resolved registry diff and docs diff.
- A per-version table of findings exists, including "nothing relevant" rows with evidence.
- Types, enum values, requirement levels, span names, span kinds, status and error mapping, and metric names/units/instruments were checked, not only attribute names.
- Data that cannot be sourced honestly is omitted, with the user's agreement, rather than guessed.
- The compatibility approach follows the area's migration notice and the component's existing opt-in contract (no new opt-ins invented, none dropped); any hard cutover is limited to pre-release packages without such a contract and is documented as breaking.
- The declared version is only bumped where the behavior matches; skipped components are listed with reasons.
- Generated constant values were diffed, not just names.
- Tests cover each opt-in mode, schema URLs, attribute types and absence of attributes; Weaver tests use the declared version constant.
- README links for the migrated path and tables, CHANGELOG entries (every
affected component, at the end of
Unreleased) and public API files are updated; legacy, runtime-owned and historical links were left alone. - Build (all TFMs), tests,
dotnet formatandmarkdownlintoutcomes are reported, with anything not run called out. - PR description follows the template, discloses AI usage, and lists the components deliberately excluded.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

