agentleFS
codebeltnetcodebeltnet/agentic/skills/git-nuget-release-notes/SKILL.md

git-nuget-release-notes

Skill3 starsChanged 40 days agoMITView on GitHub

Use when the user wants per-package NuGet release notes in cumulative `.nuget/{ProjectName}/PackageReleaseNotes.txt` files, including creating missing files for packable `src/` projects. Do not use for repository `CHANGELOG.md`, GitHub releases, or package README work.

The file

Show its rules and text

We split this skill into the rules it gives an agent

38 rules. About 0 are common, 23 are distinctive, and 15 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈23

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 15

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read references/package-release-notes-format.md before writing any release-note block.

    line 13
  2. Very specific:

    Create or update .nuget/{ProjectName}/PackageReleaseNotes.txt directly, then stop for user review.

    line 17
  3. Distinctive:

    Treat a same-named tracking branch as a synchronization target, not the default release-note base.

    line 19
  4. Very specific:

    Prefer an existing .nuget/{ProjectName}/ folder when one already exists for the packable project.

    line 21
  5. Very specific:

    Every selected package must receive a complete target-version block with Version:, resolved Availability:, and a non-empty # ALM section, …

    line 23
  6. Very specific:

    Treat the package's base-to-HEAD state as truth.

    line 24
  7. Distinctive:

    Read full commit subjects and bodies before writing the package notes.

    line 28
  8. Distinctive:

    Use cumulative newest-first history.

    line 30
  9. Distinctive:

    If the target version already exists at the top of the file, rewrite that block in place instead of duplicating it.

    line 31
  10. Distinctive:

    If the target version is not present, prepend the new block above the older history.

    line 32
  11. Very specific:

    Always include # ALM and at least one ALM bullet in the block you write.

    line 34
  12. Very specific:

    Use only this section order when sections are populated: ALM, Breaking Changes, New Features, Improvements, Bug Fixes, References.

    line 35
  13. Very specific:

    Start every bullet with an all-caps action verb such as ADDED, CHANGED, REMOVED, FIXED, EXTENDED, OPTIMIZED, MOVED, RENAMED, DEPRECATED, or …

    line 37
  14. Very specific:

    Keep package/type/member identifiers exact where possible.

    line 38
  15. Distinctive:

    Do not dump commit subjects verbatim into the release notes.

    line 39
  16. Distinctive:

    Do not invent unsupported changes, package references, or availability.

    line 40
  17. Distinctive:

    When a scope is resolved, use this model for each target package:

    line 65
  18. Distinctive:

    Read chronological commit subjects and bodies as supporting context.

    line 81
  19. Distinctive:

    Use history to explain the surviving outcomes, then map them into the package-note sections.

    line 82
  20. Distinctive:

    Do not accumulate bullets from individual commits and deduplicate them afterward.

    line 84
  21. Very specific:

    If the user named a range, branch comparison, base branch, or PR range, use that.

    line 109
  22. Very specific:

    Treat a same-named tracking branch such as origin/v10.8.0/options-enhancement for v10.8.0/options-enhancement as a synchronization target …

    line 111
  23. Distinctive:

    If no safe integration branch or merge-base can be established, or the current branch is itself the integration branch, stop and ask for a …

    line 114
  24. Very specific:

    Keep project identity anchored to the packable project name or the existing .nuget/{ProjectName}/ folder already used by the repo.

    line 140
  25. Distinctive:

    If you cannot determine a safe concrete version, stop and ask instead of guessing.

    line 161
  26. Distinctive:

    Do not infer a version by bumping the previous entry manually unless the user explicitly asked you to choose the next version.

    line 163
  27. Very specific:

    Read TargetFramework or TargetFrameworks from the project and any inherited repo-level props when needed.

    line 169
  28. Distinctive:

    Do not guess availability from memory if the project file or evaluated MSBuild properties can answer it.

    line 181
  29. Distinctive:

    Read the full commit bodies only after the cumulative delta is clear.

    line 193
  30. Very specific:

    Use the normalized section order from references/package-release-notes-format.md.

    line 207
  31. Distinctive:

    Prefer a minimal complete block over an inflated one.

    line 218
  32. Distinctive:

    Write the block in this normalized shape:

    line 224
  33. Distinctive:

    If the file is missing, create it with the new block only.

    line 240
  34. Distinctive:

    If the top block already targets the resolved version, replace that top block in place from the full resolved delta and leave older history …

    line 241
  35. Distinctive:

    If the top block targets an older version, prepend the new block and a blank line before the existing history.

    line 242
  36. Distinctive:

    Keep each bullet on one physical line regardless of length.

    line 245
  37. Distinctive:

    Do not add decorative Markdown, tables, or changelog callouts.

    line 246
  38. Very specific:

    After updating the relevant PackageReleaseNotes.txt files, stop and let the user review them.

    line 252

≈ “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.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Git NuGet Release Notes

Image: Git NuGet Release Notes

This skill creates or updates cumulative .nuget/{ProjectName}/PackageReleaseNotes.txt files for packable .NET projects by reading git history and the actual project/package metadata. It is intentionally closer to the package-note style used in codebelt repositories than to a repo-wide CHANGELOG.md.

Read references/package-release-notes-format.md before writing any release-note block.

Critical

  • Create or update .nuget/{ProjectName}/PackageReleaseNotes.txt directly, then stop for user review.
  • A bare invocation with a concrete version is a complete edit request. Resolve the full current branch against its integration branch and continue without asking for range confirmation when that default is safe.
  • Treat a same-named tracking branch as a synchronization target, not the default release-note base. Pushing a branch must not shrink its release-note scope.
  • Discover packable projects under src/; ignore test/, tuning/, tooling/, and projects that are explicitly non-packable.
  • Prefer an existing .nuget/{ProjectName}/ folder when one already exists for the packable project. If none exists, create .nuget/<MSBuildProjectName>/PackageReleaseNotes.txt.
  • A version-only invocation covers every packable src/ project, including unchanged projects. Narrow the package inventory only when the user explicitly selects packages or projects; an explicit git range alone does not narrow it.
  • Every selected package must receive a complete target-version block with Version:, resolved Availability:, and a non-empty # ALM section, even when its file already exists or its semantic delta is empty.
  • Treat the package's base-to-HEAD state as truth; chronological history is supporting provenance.
  • Inspect cumulative package, API, manifest, version, and metadata deltas before classifying the package history.
  • Classify each user-facing package capability from whether it existed at the resolved base before considering intermediate commits or individual files.
  • Describe only surviving package outcomes. Do not preserve intermediate upgrades, removals, renames, or bug fixes that do not survive into HEAD.
  • Read full commit subjects and bodies before writing the package notes.
  • Inspect the net diff too; do not classify a package from commit subjects alone.
  • Use cumulative newest-first history.
  • If the target version already exists at the top of the file, rewrite that block in place instead of duplicating it.
  • If the target version is not present, prepend the new block above the older history.
  • Normalize the block you write to Version: and Availability:.
  • Always include # ALM and at least one ALM bullet in the block you write. Use the required default below when there are no package-specific ALM outcomes.
  • Use only this section order when sections are populated: ALM, Breaking Changes, New Features, Improvements, Bug Fixes, References.
  • Omit empty optional sections instead of emitting placeholders. # ALM is mandatory and uses the required default when needed.
  • Start every bullet with an all-caps action verb such as ADDED, CHANGED, REMOVED, FIXED, EXTENDED, OPTIMIZED, MOVED, RENAMED, DEPRECATED, or REFACTORED.
  • Keep package/type/member identifiers exact where possible.
  • Do not dump commit subjects verbatim into the release notes.
  • Do not invent unsupported changes, package references, or availability.
  • Ignore odd historical spacing such as non-breaking spaces in older entries; normalize only the block you are writing unless the user asks for a larger cleanup.

Required Release Block

Package coverage and change classification are separate decisions. An empty semantic delta suppresses change-specific bullets, never the release block. If there are no package-specific ALM outcomes, use this exact default bullet:

- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

This is the required package-release boilerplate, including for unchanged packages. It is not evidence that a named dependency changed; do not infer additional upgrade bullets from it. When actual ALM outcomes exist, describe them accurately instead of replacing their details with the default. Other sections contain only supported surviving outcomes.

The minimum complete block for an unchanged package is:

Version: <resolved-version>
Availability: <resolved-framework-list>

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

Deterministic Package Delta Model

When a scope is resolved, use this model for each target package:

Result = semantic_delta(PackageBase, PackageHEAD)
History = provenance used to explain Result

History is evidence; the resulting state is truth.

Reduce first. Interpret second. Summarize last.

Establish the classification baseline at the user-facing package-capability boundary, not independently for every changed file or commit. If a capability is absent at the base and present at HEAD, it belongs under # New Features with an ADDED bullet; intermediate commits that refine, fix, document, or validate that capability cannot move it to # Improvements or # Bug Fixes. Dependency, TFM, packaging, or separately pre-existing capability changes remain distinct outcomes classified from their own base states.

  1. Inspect cumulative manifest, property, version, and metadata deltas that affect the package.
  2. Inspect the cumulative base-to-HEAD diff for the package and its shared packaging files.
  3. Determine which package changes actually survive at HEAD.
  4. Read chronological commit subjects and bodies as supporting context.
  5. Use history to explain the surviving outcomes, then map them into the package-note sections.

Do not accumulate bullets from individual commits and deduplicate them afterward.

Reconciliation rules:

  • Base state and HEAD state are identical -> no change-specific bullet; still write the complete target-version block with the default ALM text.
  • Dependency, API, metadata, or TFM value that returns to the base state -> no change-specific bullet; this never suppresses the required release block or default ALM text.
  • Package capability absent at base and present at HEAD -> one surviving ADDED outcome under # New Features. Do not emit CHANGED, EXTENDED, or FIXED outcomes for refinements within that same introduction cycle.
  • Base present and HEAD absent -> one surviving removal.
  • Base present and changed HEAD state -> one surviving modification, fix, rename, or move derived from the final delta.
  • Equivalent entity/path/name moved or renamed -> one rename/move outcome when the cumulative diff supports it, not add plus remove.

Examples:

  • Newtonsoft.Json 13.0.3 -> 14.0.0 -> 13.0.3 -> no dependency-specific # ALM bullet; keep the required default ALM block.
  • Newtonsoft.Json 13.0.3 -> 14.0.0 -> 14.0.2 -> one surviving upgrade from 13.0.3 to 14.0.2.
  • Public API removed and later restored unchanged -> no # Breaking Changes bullet.
  • Feature added, fixed several times, then removed -> no package-note entry for that feature.
  • One capability added, reworked, fixed, documented, and still present -> one final ADDED bullet under # New Features describing what shipped.

Workflow

Step 1: Resolve the source range

Resolve the range from local, read-only git metadata in this order:

  1. If the user named a range, branch comparison, base branch, or PR range, use that. Preserve explicit range endpoints; for a branch comparison, resolve its merge-base with HEAD.
  2. Otherwise, resolve the repository's integration branch. Prefer the locally cached remote default branch, such as origin/HEAD resolving to origin/main, then try origin/main, origin/master, local main, and local master. A differently named upstream may be used when repository metadata or conventions establish it as the integration branch.
  3. Treat a same-named tracking branch such as origin/v10.8.0/options-enhancement for v10.8.0/options-enhancement as a synchronization target only. Use it as the base only when the user explicitly requested that comparison. Never limit the default scope to unpushed commits.
  4. Resolve <base> to the merge-base of the integration branch and HEAD, and use <base>..HEAD for the full branch delta. Keep the resolved endpoints fixed throughout inspection.
  5. State the resolved range briefly and proceed with the edits. Do not ask the user to choose between the full branch and its latest commits when the default resolves safely.
  6. If no safe integration branch or merge-base can be established, or the current branch is itself the integration branch, stop and ask for a base branch or range instead of guessing. An explicit range remains usable on the integration branch.

A concrete version such as 10.8.0 selects the block to write; it does not select a git range. Do not switch to a previous-release tag merely because a version was supplied. A previous-release tag is a comparison boundary only when explicitly requested, and its own commit is excluded from <tag>..HEAD. Already released blocks remain historical output to preserve, not targets to regenerate.

The current target-version block is cached output, not a comparison baseline. Recompute it from the entire resolved delta even when earlier branch commits already wrote part of that block; this keeps surviving features and their later refinements together. Do not preserve obsolete bullets or drop earlier branch outcomes by using the draft's commit as the base.

Helpful commands:

git status --short --branch
git rev-parse --abbrev-ref HEAD
git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}'
git symbolic-ref refs/remotes/origin/HEAD --short
git merge-base HEAD origin/main
git merge-base HEAD origin/master
git merge-base HEAD main
git merge-base HEAD master

Step 2: Discover the target packages

Discover the packable src/ projects that belong in .nuget/.

  • Enumerate src/**/*.csproj.
  • Exclude projects that live outside src/ or are clearly test, benchmark, sample, or tooling projects.
  • Exclude projects with IsPackable explicitly set to false.
  • Keep project identity anchored to the packable project name or the existing .nuget/{ProjectName}/ folder already used by the repo.
  • By default, select every packable src/ project. Honor an explicit package/project selection, but never use the changed-path list to exclude unchanged projects from the selected inventory.
  • Maintain that selected inventory through writing and final verification. An existing note file or an empty package diff does not satisfy target-version coverage.

Helpful commands:

rg --files src -g *.csproj
git diff --name-only <base>..HEAD -- src .nuget Directory.Build.props Directory.Build.targets Directory.Packages.props

Step 3: Resolve the concrete release version

Each release-note block needs a real package version, not an [Unreleased] placeholder.

Use this order:

  1. Explicit version provided by the user.
  2. Branch prefix such as v0.3.1/feature-name -> 0.3.1.
  3. Evaluated package version from the project if it is concrete and safe to use.

If you cannot determine a safe concrete version, stop and ask instead of guessing.

Do not infer a version by bumping the previous entry manually unless the user explicitly asked you to choose the next version.

Step 4: Resolve the availability line

Derive Availability: from the package's target frameworks.

  • Read TargetFramework or TargetFrameworks from the project and any inherited repo-level props when needed.
  • Reuse the prior Availability line when the current target frameworks are verified unchanged. Check the project and inherited framework settings; recompute the line if frameworks or their order changed. Apply this resolution to unchanged packages too.
  • Preserve the project order when rendering frameworks.
  • Convert TFMs to the human-readable style used by the existing files.
  • Join the final list with commas and and.

Examples:

  • net10.0;net9.0 -> .NET 10 and .NET 9
  • net10.0;net9.0;netstandard2.0 -> .NET 10, .NET 9 and .NET Standard 2.0
  • net10.0;net9.0;netstandard2.1;netstandard2.0 -> .NET 10, .NET 9, .NET Standard 2.1 and .NET Standard 2.0

Do not guess availability from memory if the project file or evaluated MSBuild properties can answer it.

Step 5: Inspect the cumulative package delta first

For each target package, use this order to understand the real release story.

  • Build the package-specific path set: the package project, its source folder, any package-specific .nuget/{ProjectName}/ files, and shared packaging/build files that materially affect it.
  • Inspect cumulative manifest, property, version, and metadata deltas first. This includes Directory.Packages.props, package references in project files, TargetFramework / TargetFrameworks, package metadata, and other shared packaging files that affect the package.
  • Inspect the cumulative base-to-HEAD diff for the package paths.
  • Determine which package changes survive at HEAD: public APIs, dependency versions, TFMs, package metadata, types/members, renames/moves, removals, and bug fixes that still exist.
  • Identify each user-facing package capability and test its existence at the resolved base before classifying its child files or commit verbs.
  • Eliminate exact reversions, temporary features, reverted dependency churn, and restored APIs or metadata that match the base state.
  • Read the full commit bodies only after the cumulative delta is clear. Use history to explain the surviving outcomes, confirm rename intent, understand migration context, and choose accurate user-facing terminology. Never let an intermediate commit override contradictory final-state evidence.

Helpful commands:

git diff --name-status -M -C <base>..HEAD -- <paths>
git diff --stat <base>..HEAD -- <paths>
git diff <base>..HEAD -- <paths>
git log --reverse --format=medium <range> -- <paths>
git log --reverse --stat --format=medium <range> -- <paths>

Step 6: Classify the content into the package-note format

Use the normalized section order from references/package-release-notes-format.md.

Classification guidance:

  • # ALM: describe surviving dependency upgrades/downgrades, TFM support changes, packaging metadata changes, or other release-engineering/package-management changes. Use the final before -> after versions that remain at HEAD. If none exist for the package, write the exact required default ALM bullet from Required Release Block; never omit the section or leave it empty.
  • # Breaking Changes: only incompatible renames, removals, moved APIs, changed contracts, or behavior that still requires consumer action at HEAD.
  • # New Features: only additive APIs, capabilities, packages, or options that are absent at the base state and present at HEAD.
  • # Improvements: surviving non-breaking enhancements such as CHANGED, EXTENDED, OPTIMIZED, DEPRECATED, or other refinements to existing behavior.
  • # Bug Fixes: surviving defect corrections for behavior that remains changed versus the base state.
  • # References: package IDs only, and only when the package is an umbrella/meta package or the existing file already carries a references section the current release should preserve.

Prefer a minimal complete block over an inflated one. ALM-only blocks are required for selected packages with no surviving changes, as well as valid for dependency or TFM maintenance. A restored API or reverted dependency upgrade does not earn a section entry. Use history to help group or explain the surviving outcomes, not to manufacture extra bullets. Refinement or bug-fix commits made after a capability was first added but before its first release remain part of the ADDED new-feature outcome. # Improvements and # Bug Fixes require the affected capability or behavior to exist at the resolved base.

Step 7: Write or update PackageReleaseNotes.txt

Write the block in this normalized shape:

Version: 0.3.1
Availability: .NET 10 and .NET 9

# ALM
- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs)

# New Features
- ADDED ...

Editing rules:

  • Apply these rules to every selected package, including unchanged packages. Do not stop after editing only the packages with source or dependency changes.
  • If the file is missing, create it with the new block only.
  • If the top block already targets the resolved version, replace that top block in place from the full resolved delta and leave older history below it intact. Existing draft bullets are not independent evidence or a reason to narrow the range.
  • If the top block targets an older version, prepend the new block and a blank line before the existing history.
  • An existing target-version block is complete only when its version, availability, non-empty ALM section, and supported change bullets all satisfy this workflow. Repair missing ALM even if its feature text already matches the delta.
  • Preserve older release blocks below the edited one unless the user explicitly asked for a historical cleanup.
  • Keep each bullet on one physical line regardless of length. Do not hard-wrap at a fixed column width; rely on editor soft wrapping instead.
  • Do not add decorative Markdown, tables, or changelog callouts.

Step 8: Stop after the edit

Before stopping, reconcile the selected project inventory against the written target-version blocks. Read each selected file and verify exactly one target-version block at the top, resolved availability, and # ALM with either accurate package-specific outcomes or the exact default bullet. Verify older blocks remain intact. A file's existence alone is not coverage; no selected package may remain on an older version or lack ALM. Correct missing or incomplete blocks before handing back the result.

After updating the relevant PackageReleaseNotes.txt files, stop and let the user review them. Do not commit, tag, push, pack, or publish unless the user asks.

Good Output Characteristics

  • Reads like curated package release notes, not a repo-wide changelog.
  • Keeps one truthful release block per package/version.
  • Covers every selected packable package, including unchanged packages, with a complete target-version block and non-empty ALM.
  • Classifies each package from its surviving base-to-HEAD delta; reverted churn disappears.
  • Uses concrete package/type/member names and namespaces.
  • Writes the newest release first while preserving older history.
  • Keeps ALM details explicit when dependencies or TFMs changed.
  • Creates missing files when the package should be represented.
  • Keeps availability aligned with actual target frameworks.

Bad Output Characteristics

  • Writing one repo-level summary and copying it into every package file.
  • Skipping unchanged selected packages, leaving them on a prior version, or accepting a target-version block without ALM.
  • Using Unreleased or omitting the concrete version line.
  • Guessing availability instead of reading project metadata.
  • Dumping commit subjects line by line into the file.
  • Reporting temporary dependency, API, metadata, or TFM changes that do not survive into HEAD.
  • Emitting # Breaking Changes, # New Features, or # Bug Fixes bullets for work that was later restored or removed before release.
  • Moving a base-absent capability into # Improvements or # Bug Fixes because intermediate commits refined or fixed it before its first release.
  • Creating empty headings or filler bullets like "misc updates".
  • Claiming breaking changes, fixes, or references not supported by git and the project/package metadata.

Download now (ZIP)

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
What did you use it for? e.g. Reviewing pull requests in a Rails app

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.