Skip to main content

write-changelog

Use when a change in this repo needs a customer-facing changelog entry — e.g. "add a changelog entry" — or when an approved PR that changes user-visible behavior in lib/, ext/, or docs/GettingStarted.md is about to merge.

Ir a la instalación

Datos de origen

Repositorio
DataDog/dd-trace-rb
Última actividad en el origen
11 de septiembre de 2026 a las 08:39
Idioma detectado de SKILL.md
inglés
Estrellas
417
Forks
417

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
write-changelog
description
Use when a change in this repo needs a customer-facing changelog entry — e.g. "add a changelog entry" — or when an approved PR that changes user-visible behavior in lib/, ext/, or docs/GettingStarted.md is about to merge.
# Writing changelog fragments READ `unreleased/README.md` FIRST — it is the human-facing description of the fragment system and its fields. This skill is the agent-facing checklist. A fragment may be written as soon as the PR exists, but its grounding is only final when the diff is: re-ground the message against the final diff when the PR is complete and approved, right before merging — grounding and triage see the complete change only there. ## The customer Every message targets one reader: a Ruby developer using this gem in their application, scanning `CHANGELOG.md` to decide whether an upgrade affects them. They read for what changes in their application — what they observe, do, or get. The exact version they run is their context. ## Core principles - ALWAYS write for the customer, not the diff - ALWAYS lead with the customer effect; supporting detail follows - ALWAYS scope who is affected — versions, platforms, triggers, workloads — whenever the scope decides it - NEVER narrate the implementation Scope names what the customer runs; narrative names what the code does ## Grounding Read the diff and triage first; the answers drive every later step: - Effect: what does this PR make true when it lands? If the effect arrives only in a later change (groundwork, flag plumbed but off), there is nothing to write yet - Count: one change or several distinct effects? Several → ASK the user to confirm the split before writing several fragments; NEVER bundle several effects into one ```markdown <!-- Bad: two effects bundled into one fragment --> Add support for Bundler deployment mode (`bundle install --deployment`) and report UI-oriented injection results. <!-- Good: one effect stated whole; the PR's other effects each get their own fragment --> Add support for Bundler deployment mode (`bundle install --deployment`). ``` - Product: which product each effect belongs to — by effect, not code location (a core fix to a profiler crash is Profiling); diffuse core-wide → `Core`. Closed list: `ReleasePrep::Fragment::PRODUCTS` (`tasks/lib/release_prep/fragment.rb`); the integration name (Redis) goes in the `message`, not the `product` - Type: `Added` (new capability), `Changed` (behavior change), `Fixed` (bug fix); performance changes are `Changed`, or `Fixed` when they restore performance an earlier version had Then keep every written claim grounded: - Verify identifiers (settings, classes, methods, env vars, gems) against the hunks, not recalled conventions - Verify versions against the diff (gemspec, Matrixfile, CI), not ecosystem memory - Measured numbers: the diff, its benchmark output, or the author's reported result — a benchmark's output often lives only in the PR; no source there, and the claim stays directional - Verify behavior against the diff's tests — no test, no behavioral claim - A reproducible defect with no test: ASK the PR to add the test; the behavioral claim waits for it - A PR that merges without the test grounds its entry in what inspection establishes — the claim caps there, and the review thread notes the missing test - When a deterministic test cannot reproduce the defect — it depends on timing or uncontrolled external state — verification falls back to inspection: the change the diff adds is the evidence, and the message claims no more than it establishes - ALWAYS drop or weaken a claim that traces to nothing; NEVER hedge it ## Deciding - ALWAYS add a fragment for new features, behavior changes, and customer-affecting bug fixes - NEVER add a fragment for internal refactors, test-only, CI/tooling, or docs outside `docs/GettingStarted.md` - SHOULD add when unsure — a reviewer can delete an entry; a missing one leaves customers unaware ## Creating the fragment - ALWAYS write against a real PR number; with no PR yet, open a draft first — nothing checks the number mechanically - ALWAYS update the existing fragment for this effect; NEVER add a second one for the same effect. Fragments for other effects stay untouched - ALWAYS generate the scaffold with `bundle exec rake unreleased:new`; NEVER create a blank file by hand The placeholders name what each field needs; filled-in references live in `unreleased/examples/`. - ALWAYS set `author` to the external contributor's `@`-prefixed GitHub handle; NEVER set `author` for a Datadog contributor ## The floor and the standard `bundle exec rake unreleased:lint` and `unreleased:vale` enforce a basic mechanical floor and it will keep expanding. The floor never proves an entry good: passing it proves the entry checkable. Every rule below is the standard, stated on its own terms; some overlap the floor, none lean on it. ## Writing the message The rules follow in drafting order. When the structure will not fit the caps, keep the customer effect, its scope, and any access point or escape hatch — the compressible rest is the explanatory detail, never the actionable. - Structure by type — the reader's question differs: - `Fixed`: ALWAYS name the symptom they recognize, then the trigger they can perform or observe (a call they make, a setting they use); when nothing is observable, bottom out at what the evidence establishes, and NEVER below it, into internal sequencing ```markdown <!-- Bad: the trigger named, but no symptom to recognize --> Fix `Process.spawn` when passing an environment Hash. <!-- Good: the symptom they recognize + the trigger they perform --> Fix `TypeError` from `Process.spawn` when passing an environment Hash. ``` - `Added`: ALWAYS name the capability, then the access point — the setting/API that gets it for them ```markdown <!-- Bad: the capability stated, but no access point to enable it --> Show class and module names in profiler stack frames (`Foo::Bar#baz` instead of `baz`), making hot methods easier to identify. <!-- Good: capability + example + why it helps + the exact access point --> Show class and module names in profiler stack frames (`Foo::Bar#baz` instead of `baz`), making hot methods easier to identify; enable it with `DD_PROFILING_EXPERIMENTAL_SHOW_CLASSES_ENABLED=true`. ``` - `Changed`: ALWAYS name the new behavior and the escape hatch when one exists; SHOULD follow with why it matters ```markdown <!-- Bad: the new behavior and why, but no way back --> Move the gem's diagnostic logs from stdout to stderr, so stdout stays clean for application output. <!-- Good: new behavior + why it matters + escape hatch --> Move the gem's diagnostic logs from stdout to stderr, so stdout stays clean for application output; restore the old default with `c.logger.instance = Datadog::Core::Logger.new($stdout)` in `Datadog.configure`. ``` - ALWAYS state what changed, in customer terms; NEVER code-review jargon ("refactored", "cleaned up") or internal file names. ```markdown <!-- Bad: code-review terms lead — jargon, file name, the customer claim buried at the end --> Set `Tracing::Metadata::Ext::TAG_KIND` on spans in the `ActiveRecord` `sql` event handler (`events/sql.rb`) to fix missing peer tags for database queries. <!-- Good: customer framing, grounded, code spans --> Fix missing peer tags for database queries traced through `ActiveRecord`. ``` - ALWAYS open with a present-tense imperative verb (Add, Fix, Support, Improve, ...); NEVER the past tense ("Fixed a crash..."), process-speak ("This PR fixes..."), or subject-first prose ("The gem now supports...", "Also fixes...") — the entry states what the new version does for the customer, not a report of work done ```markdown <!-- Bad: the past tense reads as a report of work done, not what it does --> This PR fixes missing peer tags for database queries traced through `ActiveRecord`. <!-- Good: the present-tense imperative opens the entry --> Fix missing peer tags for database queries traced through `ActiveRecord`. ``` - ALWAYS end the message with terminal punctuation — the entry is a sentence, not a fragment - ALWAYS open on the customer's observable delta; the mechanism, scope, and numbers follow it ```markdown <!-- Bad: the mechanism opens; the customer's delta never leads --> Enforce a process-wide rate limit across all probes: with multiple probes set, they can emit less than their individual limits allow — combined output is capped at 20 snapshots/s and 5000 log events/s per process. <!-- Good: the customer's observable delta leads, the numbers follow --> Cap probe output process-wide: with multiple probes set, they can emit less than their individual limits allow — combined output is capped at 20 snapshots/s and 5000 log events/s per process. ``` - ALWAYS make the CamelCase code-span call: span what names the code the customer runs (`ActiveRecord`), leave product names bare in prose (Bundler) - NEVER repeat the product verbatim — with product `AppSec`, "Add AppSec detection..." says it twice; lowercase technical phrasing ("GC profiling") is fine ```markdown <!-- Bad: the product said twice --> Add AppSec detection of response splitting. <!-- Good: the product already renders beside the entry --> Add detection of response splitting. ``` - ALWAYS name exact versions and platforms when they decide who is affected — NEVER vague quantifiers ("recent", "newer") ```markdown <!-- Bad: vague version --> Disable live heap size profiling on recent Ruby versions due to incompatibility. <!-- Good: exact version --> Disable live heap size profiling on Ruby 4.0 due to incompatibility. ``` - SHOULD back performance claims with measured numbers from the PR's own evidence (Grounding); a claim with no measured number there stays directional ```markdown <!-- Bad: the vague quantifier stands in for the directional claim --> Reduce profiler overhead significantly for applications with many idle or blocked threads by skipping samples that would carry no new information; skipped threads are still reported each period. <!-- Good: directional with scope — the PR's evidence carries no measured number --> Reduce profiler overhead for applications with many idle or blocked threads by skipping samples that would carry no new information; skipped threads are still reported each period. ``` ## Finishing loop Run the three steps in order; ANY revision restarts the loop from step 1. Done when a pass makes no revision: 1. `bundle exec rake unreleased:lint` and `bundle exec rake unreleased:vale` — fix every reported violation 2. `bundle exec rake unreleased:render` — check the rendered entry against every Core principle and every Writing rule in turn, and revise; done when each one is accounted for 3. Re-run the Grounding triage against the final diff — effect, count, product, and type, then every identifier, version, number, and behavioral claim traced to a specific hunk, benchmark output, or test; drop or weaken each one that traces to nothing. A count that grew means a new effect: the ASK re-fires and it gets its own fragment
Ver en GitHub