Skip to content

Commit 3dfeeca

Browse files
richlanderCopilotjeffhandley
authored
Add release notes agentic workflow (dotnet#10334)
* Add release notes agentic workflow and skill references Cron-driven GitHub Agentic Workflow that maintains release notes branches for .NET preview/RC/GA releases. Architecture: - dotnet-release generate changes tool produces changes.json (deterministic, from VMR source-manifest.json diffs) - Agent reads changes.json and writes curated markdown for high-value features - One PR per release milestone, maintained incrementally - Respects human edits on the branch Skill references (6 docs, ~700 lines total): - quality-bar.md: what good release notes look like - vmr-structure.md: VMR branches, tags, source-manifest.json - changes-schema.md: changes.json schema reference - component-mapping.md: components, product slugs, output files - format-template.md: markdown document structure - editorial-rules.md: tone, attribution, naming Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add release notes system design document Describes the three-layer architecture (tool → agent → workflow), the source-manifest.json mechanism, branch lifecycle, and design rationale. Links from SKILL.md for discoverability. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update release notes skill docs to match actual dotnet-release CLI Tested dotnet-release v1.1.0 generate changes against the VMR (P1→P2: 1,389 changes across 21 repos). Updated docs to reflect the actual tool output: - Remove aspirational product/package fields from changes-schema.md (tool outputs repo, not product slugs) - Add labels field (optional, via --labels flag) - Fix workflow CLI syntax (positional path, --base/--head) - Update component-mapping.md: agent does repo→file routing - Remove resolved open question about package mapping - Update example JSON and jq queries to match real output Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Scope to dotnet org repos; skip microsoft/vstest for now vstest is the only microsoft org repo in the VMR manifest and is already on the infra skip list. SAML token requirements for the microsoft org can be addressed later. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix schema docs: product field exists, add labels analysis Tested --labels flag: 776/1389 changes got labels (56% coverage). Best coverage: runtime (94%), roslyn (96%), winforms/wpf (100%). Lower coverage on infra-heavy repos as expected. Corrected the schema docs — the product field IS output by the tool (repo-level mapping), just empty for infra repos. Added product back to the schema with accurate description. Added labels field documentation and updated examples/queries. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Make milestone detection deterministic Replace heuristic branch-scanning with a deterministic algorithm using three data sources: 1. releases.json → what has shipped 2. VMR eng/Versions.props on main → current development iteration 3. VMR tags → base refs for generating diffs Decision: if Versions.props iteration > latest shipped → that's the target. Exact commands provided in workflow steps 1-2. Updated DESIGN.md (milestone detection section), vmr-structure.md (version metadata + base tag discovery), and the workflow file (deterministic steps 1 and 2 with concrete examples). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add head-ref selection logic: check for target tag before using main Once main is bumped to the next iteration, it contains preview N+1 work. The agent must check if a VMR tag exists for the target milestone: - No tag → in development, use --head main - Tag exists → finalized, use --head <tag> Updated workflow step 1e and step 2 with both code paths. Added Head ref selection section to DESIGN.md explaining why this matters. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move general docs link to README only; add component-specific links The general 'What'\''s new in .NET' link belongs in README.md, not in every component file. Component files should link to their specific docs page when one exists (runtime, libraries, SDK, ASP.NET Core, C#, EF Core). Added the dotnet/docs overview source URL so the agent can discover component-specific links. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add dotnet_commit field to schema (dotnet-release v1.2.0) v1.2.0 now maps every source-repo change to its VMR codeflow commit. The new dotnet_commit field on each change entry keys into the commits dict for the dotnet/dotnet commit. Multiple source PRs typically share the same VMR commit (codeflow batches). Updated schema docs, example JSON, and field descriptions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update schema docs for dotnet-release v2.0.0 - commit field is now VMR commit (was source repo) - dotnet_commit removed (replaced by commit) - local_repo_commit added for source repo commit - product field absent for infra repos (not empty string) - Updated example and jq queries Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Evolve to multi-milestone live system with human interaction - Multi-milestone: discover all active milestones (P4 and P5 simultaneously) - Re-validate base/head refs every nightly run (tags appear, branches create, main bumps) - Branch-per-milestone on dotnet/core (release-notes/11.0-preview4, etc.) - Human interaction: respect edits, respond to PR comments, ask when unsure - Handle transitions: main bumps, new tags, release branches, PR merges - Increased safe-output limits for multi-milestone support - Updated DESIGN.md with multi-milestone discovery, human interaction model Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Compile agentic workflow; fix toolset names - Fix invalid toolsets: contents→repos, code_search→search - Add compiled release-notes.lock.yml - Add .github/aw/actions-lock.json (gh aw artifact) - Add linguist-generated gitattributes for lock files Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove stale gist link from changes schema docs The inline example in this file is the authoritative reference. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add curated examples reference doc Six examples from .NET 9/10 preview release notes demonstrating three styles: - Short: exception handler diagnostics, container insecure registries - Medium: extension operators (C#), PipeReader JSON support - Long: post-quantum cryptography, OpenIdConnect PAR Added to reference docs list in workflow and DESIGN.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add JIT/runtime examples to release notes reference Three styles of JIT feature descriptions: - Array Enumeration De-Abstraction (progressive benchmarks, optimization narrative) - Struct Arguments codegen (before/after assembly comparison) - Loop Optimizations (metric-heavy prose, no code) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add ask-for-help guidance: benchmarks, samples, domain context The agent should recognize when a feature description needs content it can't generate (benchmark data, definitive code samples, domain expertise) and post PR comments requesting it from feature authors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Split examples by component for token efficiency Replace monolithic examples.md with per-component files: - examples/README.md — principles index, component directory - examples/runtime.md — 3 JIT examples with inlined content - examples/aspnetcore.md — 3 examples (short/medium/long) - examples/csharp.md — extension operators - examples/sdk.md — container insecure registries - examples/libraries.md — post-quantum cryptography Each file includes the actual example text and links back to the original source file. Agent loads only the relevant component file when writing, saving context tokens. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Reformat examples: content first, metadata in footer blocks New format per file: ## Heading (H2) Actual content (copy/paste from original) --- Source: link to original Commentary: why it was selected Why it works: what makes it effective --- Clear separation between the example content and the editorial commentary. Content reads exactly as it would in release notes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update for dotnet-release v2.1.0; fix example formatting - id field is now string (repo@commit format) — globally unique - Updated schema docs and example JSON - Removed trailing blank lines in example metadata blocks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Run every 6 hours instead of daily More frequent runs mean faster feedback loops on PR comments and quicker pickup of new VMR content. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix commentary: callback example would benefit from code sample Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Replace short ASP.NET example: StatusCodeSelector with code snippet Replaces SuppressDiagnosticsCallback (prose-only) with StatusCodeSelector (one paragraph + clean code sample). Better exemplar for 'short + code'. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add active voice principle to examples guide Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add style note: simplify awkward phrasing in PipeReader example Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Mark PAR example as anti-pattern; add Title/Content/Credit principle The 'guest introduction' style restructures the note around attribution instead of the feature. Prefer: explain the feature, then credit at end. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add style note: simplify transition to rule bullets in C# example Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add style note: active voice for MLDsa ease-of-use intro Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add principle: link PRs/issues in org/repo #number format Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add principle: avoid jargon and ambiguous words 'Snippet' in a programming context suggests code. Say what you mean plainly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add style note: don't bury the lede with backward-looking passive Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix markdownlint: setext headings, list numbering, table spacing Add blank lines before closing --- to prevent setext heading parsing. Fix numbered list sequence in README. Fix table separator spacing. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix broken relative links; exclude lock files from super-linter Source links needed 5 levels up (not 4) from examples/ to repo root. Workflow link to examples/ fixed to use correct relative path. Exclude *.lock.yml from super-linter (generated by gh aw compile). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix remaining CI: blank line before list, README link paths Add blank line before list in workflow (MD032). Fix README.md table links — files are siblings, not in examples/ subdirectory. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove stale monolithic examples.md (replaced by examples/ directory) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add API verification guidance using dotnet-inspect - New reference doc: api-verification.md — why, when, and how to verify API names before writing about them in release notes - Updated SKILL.md: verification is now step 3 in the pipeline - Updated DESIGN.md: agent verifies before writing, not as an afterthought - Updated quality-bar.md: 'verify before you write' as a hard rule — placeholder over fabrication Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add nightly SDK download workflow for API verification - Query dotnet11 NuGet feed to find the last preview.N build - Download SDK tarball from ci.dot.net with matching version - Set DOTNET_ROOT to point dotnet-inspect at the correct build - Document why stale builds give false negatives - Add PR test fallback when nightly is unavailable - Tested: confirmed AnyNewLine=2048 in P3, ProcessStartOptions correctly absent Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify API verification: query NuGet feed directly, no SDK install Replace DOTNET_ROOT/tarball approach with direct --package --source queries against the dotnet11 nightly NuGet feed. Pure data, no SDK installation needed. Link to richlander/dotnet-release#42 for dotnet-release to provide build metadata automatically. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update api-verification: use dotnet-release build-metadata pipeline Replace manual feed query with dotnet-release generate build-metadata command (v2.3.0). Show real output including all ref packs. Remove --library workaround (fixed in dotnet-inspect). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Editorial rules: prefer short sentences, avoid interrupting clauses Long sentences are fine when they flow as one thought (what → why). They're not fine when a subordinate clause interrupts the main verb. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Editorial rules: three-tier feature ordering Broad interest → cluster by area → alphabetical within cluster. Replaces vague 'customer impact' guidance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Editorial rules: 20/80 rule, two-sentence test, value headlines Features must matter to ≥20% of readers. Write so the other 80% understand why. If you can only write two sentences, it's probably an engineering fix — cut it. Headlines should convey value. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * SKILL.md: add examples/ to reference documents Agents weren't told to read the curated examples before writing. The examples directory has 5 component files and 12 editorial principles — our best guidance on style. Now explicitly referenced. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Editorial rules: don't overstate maturity in previews Say what concretely changed (enabled by default, no opt-in needed) rather than editorializing readiness (ready for production use). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Editorial rules: filtered features comment block When cutting features for 20/80 or two-sentence test, record them in an HTML comment in the output file. Creates a learning record for future runs and human reviewers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Editorial rules: TODO for borderline entries, vet community lists - Borderline features should get a TODO comment asking for data rather than being silently included or silently cut. - Community contributor lists must be vetted: exclude -msft suffixes and other Microsoft employee indicators. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Format template: add release info and VMR refs to README README.md should include a version table and VMR base/head refs with links. Values come from build-metadata.json. Useful for tracking what was diffed and for incremental updates. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Editorial rules: dedup nuance — state changes are new news A feature introduced in P1 and enabled by default in P3 is new news. Don't skip it just because the feature name appeared in a prior preview. Document the change in state, not the feature from scratch. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Initialize Agentic Workflows agent * Set up the select-copilot-pat integration into agentic workflows * Integrate select-copilot-pat into release-notes workflow * Move labeler workflow readme to avoid it being recognized as a workflow * Apply review feedback. Set schedule to be daily around 9am PDT. * Do not run the release-notes workflow on forks unless manually dispatched * Set release-notes workflow timeout to 2 hours * Split release notes skill pipeline Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Refine release notes scoring guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify release-notes editorial guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prefer stronger verbs in release-note headings Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Refine release-notes workflow guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove redundant release-notes docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update .github/workflows/release-notes.md Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com> * Update .github/workflows/release-notes.md Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com> * Deduplicate editorial rubric guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify preview and GA api-diff labels Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename maintainer release tool to release-notes-gen Update the workflow docs, repo skills, and locked workflow permissions to use the renamed maintainer CLI and package name while keeping dotnet-release for the public graph-query tool. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Jeff Handley <jeffhandley@users.noreply.github.com>
1 parent 275a19e commit 3dfeeca

33 files changed

Lines changed: 3695 additions & 103 deletions

File tree

.gitattributes

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,6 @@
6060
#*.pdf diff=astextplain
6161
#*.PDF diff=astextplain
6262
#*.rtf diff=astextplain
63-
#*.RTF diff=astextplain
63+
#*.RTF diff=astextplain
64+
65+
.github/workflows/*.lock.yml linguist-generated=true merge=ours

.github/aw/actions-lock.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"entries": {
3+
"actions/download-artifact@v8.0.1": {
4+
"repo": "actions/download-artifact",
5+
"version": "v8.0.1",
6+
"sha": "3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c"
7+
},
8+
"actions/github-script@v8": {
9+
"repo": "actions/github-script",
10+
"version": "v8",
11+
"sha": "ed597411d8f924073f98dfc5c65a23a2325f34cd"
12+
},
13+
"actions/setup-dotnet@v5.2.0": {
14+
"repo": "actions/setup-dotnet",
15+
"version": "v5.2.0",
16+
"sha": "c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7"
17+
},
18+
"actions/upload-artifact@v7": {
19+
"repo": "actions/upload-artifact",
20+
"version": "v7",
21+
"sha": "bbbca2ddaa5d8feaa63e36b76fdaad77386f024f"
22+
},
23+
"github/gh-aw-actions/setup@v0.65.1": {
24+
"repo": "github/gh-aw-actions/setup",
25+
"version": "v0.65.1",
26+
"sha": "1831bcd4f397da99da6e6e6b65687557a1a37ac7"
27+
},
28+
"github/gh-aw-actions/setup@v0.65.6": {
29+
"repo": "github/gh-aw-actions/setup",
30+
"version": "v0.65.6",
31+
"sha": "31130b20a8fd3ef263acbe2091267c0aace07e09"
32+
}
33+
}
34+
}

.github/skills/api-diff/SKILL.md

Lines changed: 72 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,83 @@
11
---
22
name: api-diff
3-
description: Generate an API comparison report between two .NET versions using the RunApiDiff.ps1 script. Invoke when the user asks to run, create, or generate an API diff.
4-
disable-model-invocation: true
3+
description: >
4+
Download, inspect, and diff .NET APIs for a given build or release. Use
5+
`dotnet-inspect` to verify that APIs actually exist in the shipped packages,
6+
detect missed reverts, and generate before/after API diffs. Use
7+
`RunApiDiff.ps1` when a full markdown diff report is needed.
58
---
69

7-
# API Diff Generation
10+
# API Downloading, Verification, and Diffing
811

9-
Map the user's request to parameters for `release-notes/RunApiDiff.ps1` and run it. See [release-notes/RunApiDiff.md](../../../release-notes/RunApiDiff.md) for the full parameter reference.
12+
Use this skill when you need evidence about the **actual public API surface** of a .NET build.
1013

11-
When no versions are mentioned, run with no parameters — the script auto-infers versions.
14+
This is primarily for:
15+
16+
- confirming whether an API really shipped in the build binaries/ref packs
17+
- catching reverts or incomplete rollouts before they end up in release notes
18+
- generating before/after API diffs for a release milestone
19+
20+
## Preferred workflow
21+
22+
### 1. Query the right build first
23+
24+
Do **not** trust the locally installed SDK for preview work. Query the target build's packages directly.
25+
26+
Use the process in [api-verification.md](../release-notes/references/api-verification.md):
27+
28+
1. Generate or read `build-metadata.json`
29+
2. Get `nuget.source` and the package versions for the target release
30+
3. Run `dotnet-inspect` against those exact packages
31+
32+
### 2. Verify APIs with `dotnet-inspect`
33+
34+
Typical tasks:
35+
36+
- **Find a type or member** to confirm the API exists
37+
- **Compare versions** to see what changed between previews or between RC and GA
38+
- **Validate naming** before writing prose or code samples
39+
40+
Examples:
41+
42+
```bash
43+
# Find a type in the runtime ref pack
44+
dnx dotnet-inspect -y -- find "*AnyNewLine*" \
45+
--package "Microsoft.NETCore.App.Ref@${VER}" \
46+
--source "$FEED"
47+
48+
# Verify members on a type
49+
dnx dotnet-inspect -y -- member RegexOptions \
50+
--package "Microsoft.NETCore.App.Ref@${VER}" \
51+
--source "$FEED" \
52+
-k field
53+
54+
# Diff public APIs between two versions
55+
dnx dotnet-inspect -y -- diff \
56+
--package "Microsoft.NETCore.App.Ref@11.0.0-preview.2..11.0.0-preview.3" \
57+
--source "$FEED"
58+
```
59+
60+
If the API is missing from the target build, treat that as a serious signal: it may have been renamed, kept internal, or reverted.
61+
62+
### 3. Use `RunApiDiff.ps1` for full diff reports
63+
64+
When the user wants the markdown-ready, repo-shaped API diff output, use `release-notes/RunApiDiff.ps1`. See [release-notes/RunApiDiff.md](../../../release-notes/RunApiDiff.md) for the full parameter reference.
1265

1366
## Mapping natural language to parameters
1467

15-
| User says | Parameters |
16-
|---|---|
17-
| "generate the next API diff" | *(none)* |
18-
| ".NET 10 GA vs .NET 11 Preview 1" | `-PreviousMajorMinor 10.0 -CurrentMajorMinor 11.0 -CurrentPrereleaseLabel preview.1` |
19-
| "net9.0-preview6 to net10.0-preview5" | `-PreviousMajorMinor 9.0 -PreviousPrereleaseLabel preview.6 -CurrentMajorMinor 10.0 -CurrentPrereleaseLabel preview.5` |
20-
| ".NET 10 RC 2 vs .NET 10 GA" | `-PreviousMajorMinor 10.0 -PreviousPrereleaseLabel rc.2 -CurrentMajorMinor 10.0` |
21-
| "10.0.0-preview.7.25380.108 to 10.0.0-rc.1.25451.107" | `-PreviousVersion "10.0.0-preview.7.25380.108" -CurrentVersion "10.0.0-rc.1.25451.107"` |
22-
23-
- **GA** or no qualifier omit the PrereleaseLabel parameter
24-
- **Preview N** / **previewN** `-PrereleaseLabel preview.N`
25-
- **RC N** / **rcN** `-PrereleaseLabel rc.N`
26-
- **netX.Y-previewN** (TFM format) `-MajorMinor X.Y -PrereleaseLabel preview.N`
27-
- Full NuGet version strings use `-PreviousVersion` / `-CurrentVersion` directly
68+
| User says | Parameters |
69+
| ----------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
70+
| "generate the next API diff" | _(none)_ |
71+
| ".NET 10 GA vs .NET 11 Preview 1" | `-PreviousMajorMinor 10.0 -CurrentMajorMinor 11.0 -CurrentPrereleaseLabel preview.1` |
72+
| "net9.0-preview6 to net10.0-preview5" | `-PreviousMajorMinor 9.0 -PreviousPrereleaseLabel preview.6 -CurrentMajorMinor 10.0 -CurrentPrereleaseLabel preview.5` |
73+
| ".NET 10 RC 2 vs .NET 10 GA" | `-PreviousMajorMinor 10.0 -PreviousPrereleaseLabel rc.2 -CurrentMajorMinor 10.0` |
74+
| "10.0.0-preview.7.25380.108 to 10.0.0-rc.1.25451.107" | `-PreviousVersion "10.0.0-preview.7.25380.108" -CurrentVersion "10.0.0-rc.1.25451.107"` |
75+
76+
- **GA** or no qualifier -> omit the `PrereleaseLabel` parameter for `RunApiDiff.ps1`; if a downstream api-diff release label is needed, use `ga`
77+
- **Preview N** / **previewN** -> `-PrereleaseLabel preview.N` (for example, `preview.4`, not `preview4`)
78+
- **RC N** / **rcN** -> `-PrereleaseLabel rc.N`
79+
- **netX.Y-previewN** (TFM format) -> `-MajorMinor X.Y -PrereleaseLabel preview.N`
80+
- Full NuGet version strings -> use `-PreviousVersion` / `-CurrentVersion` directly
2881
- The "previous" version is always the older version; "current" is the newer one
2982

3083
## Running the script
@@ -33,4 +86,4 @@ When no versions are mentioned, run with no parameters — the script auto-infer
3386
.\release-notes\RunApiDiff.ps1 [mapped parameters]
3487
```
3588

36-
Set an initial wait of at least 300 seconds — the script takes several minutes. Use `read_powershell` to poll for completion. The script does not print a final "done" message; it exits after generating a README.md in the output folder. After completion, summarize the results: how many diff files were generated and where.
89+
Set an initial wait of at least 300 seconds — the script takes several minutes. After completion, summarize the results: how many diff files were generated and where.
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
name: editorial-scoring
3+
description: >
4+
Apply the shared reader-centric rubric used to rank candidate features for
5+
release notes, blog posts, and docs. Use this when you need scoring and cut
6+
guidance independent of any one output format or task.
7+
---
8+
9+
# Editorial Scoring
10+
11+
Use this skill whenever you need to answer **"How important is this to a reader?"**
12+
13+
This skill is intentionally **rubric-focused, not task-focused**. It does not generate files on its own. Instead, it provides the shared editorial calibration that other skills should reuse:
14+
15+
- `generate-features` — assigns the first-pass scores
16+
- `review-release-notes` — audits and recalibrates those scores
17+
- `release-notes` — uses the resulting cut to decide what gets written up
18+
- future blog/docs workflows — can reuse the same rubric with different thresholds
19+
20+
This is the **canonical home** for the shared scoring scale and 80/20 audience
21+
filter. Other release-notes docs should point back here instead of restating the
22+
rubric in full.
23+
24+
## Core question
25+
26+
Score from the perspective of a developer upgrading to the new release — not from the perspective of the engineer who implemented the feature.
27+
28+
## Reader-centric scale
29+
30+
| Score | Reader reaction | What to do with it |
31+
| ----- | -------------------------------------------------------------------------------- | ---------------------------------------------------------- |
32+
| `10` | "This is the first feature I'll enable or test." | Lead story |
33+
| `8+` | "I'm going to use this when I upgrade." | Strong release-note feature |
34+
| `6+` | "I'm glad I know about this. It will likely come in handy." | Good grouped release-note material |
35+
| `4+` | "I can see how someone could use this. I'll look up the docs if I ever need it." | Optional mention, grouping candidate, or short paragraph |
36+
| `2+` | "This one is a mystery to me." | Usually skip unless stronger explanation changes the score |
37+
| `0` | "This is total gobbledygook — internal .NET engineering work." | Cut it from public-facing content |
38+
39+
## 80/20 audience filter
40+
41+
Default to features that make sense to roughly **80% of the audience**.
42+
43+
Keep a more specialized feature for the other **20%** only when the remaining 80% can still understand why it matters and react with something like:
44+
45+
> "Not for me, but I'm glad that's there for the people who need it."
46+
47+
This is how foundational but initially niche work can still earn a good score.
48+
49+
## Strong positive signals
50+
51+
- New public APIs with obvious user value
52+
- CLI or workflow improvements developers will notice right away
53+
- Features that are easy to explain by anchoring them to a familiar tool or workflow
54+
- Clear performance, reliability, or usability wins
55+
- Features people have been asking for
56+
- Changes that require docs, migration notes, or examples to use well
57+
58+
## Strong negative signals
59+
60+
- Test-only work
61+
- Build or infrastructure churn
62+
- Refactoring with no user-visible effect
63+
- VMR sync noise, dependency updates, or repo automation
64+
- Highly specialized implementation details that read like internal jargon
65+
- Features that only matter after several stacked conditions are true (for example: uses single-file publish **and** cares deeply about startup **and** is willing to do extra training/tuning)
66+
- PRs with very thin descriptions where the only concrete signal is an internal runtime/tooling term like cDAC
67+
- Existing niche surfaces that are barely documented and are not part of the model's normal customer-facing understanding
68+
- Claimed "new API" features where the actual new public API cannot be identified
69+
- Bug fixes for features that were never really announced or are still obscure to most readers
70+
- Old, low-engagement bugs filed internally that sat for a long time without clear external demand
71+
72+
## Common scoring mistakes
73+
74+
- **Technical novelty bias** — "this is clever" is not the same as "users will care"
75+
- **API inventory mode** — listing everything from an API diff is not release-note curation
76+
- **Effort bias** — a difficult implementation may still score low if the reader value is small
77+
- **Insider-language inflation** — terms like JIT, LSRA, cDAC, intrinsics, or pipeline details can sound impressive but still be a `0-4` unless the value is explained clearly
78+
- **Audience multiplication blindness** — when a feature requires several independent interests or behaviors, multiply those filters together instead of scoring the broadest prerequisite alone
79+
- **Description vacuum optimism** — if the PR does not explain the user scenario, do not fill in the blanks with a generous story
80+
- **Documentation blindness** — if an "existing" feature is not findable in Learn docs and does not show up as a known customer scenario, that is a signal to score it around `1`, not to assume hidden importance
81+
- **Phantom API stories** — if you cannot identify the concrete new public API, do not give API credit based on a vague title alone
82+
- **Promotion by association** — a fix in a glamorous subsystem is still just a `1` if it only patches an unannounced or niche feature
83+
- **Demand inversion** — do not mistake an old internal bug with no reactions for evidence that many users need to hear about the fix
84+
- **Fragmentation bias** — do not dismiss each small related item in isolation when several `2-4` items together form one intelligible reader story, such as a cluster of "Unsafe evolution" changes
85+
86+
## Working thresholds
87+
88+
- **8+** — worthy of its own section
89+
- **6-7** — usually grouped with similar items, sometimes a short standalone section
90+
- **0-5** — bug-fix bucket, one-liner, or cut
91+
92+
Several `3-5` items in the same area can still combine into **one** worthwhile writeup. Keep the individual scores honest, then let the writing stage roll them up into a single themed section.
93+
94+
## Breaking changes are separate from score
95+
96+
Use score for **reader interest/value**, and use `breaking_changes: true` for **reaction/migration significance**.
97+
98+
That means:
99+
100+
- a **low-score breaking change** often still deserves a short end-of-notes callout
101+
- a **high-score breaking change** may deserve both a full feature writeup and a migration note
102+
103+
Do **not** inflate a narrow breaking change to `7+` just to keep it visible.
104+
105+
## Canonical references
106+
107+
- [`../release-notes/references/feature-scoring.md`](../release-notes/references/feature-scoring.md) — detailed scoring guidance
108+
- [`../release-notes/references/quality-bar.md`](../release-notes/references/quality-bar.md) — what good release notes look like
109+
- [`../release-notes/references/examples/README.md`](../release-notes/references/examples/README.md) — editorial examples and why they work
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
name: generate-changes
3+
description: >
4+
Generate `changes.json` for a .NET release milestone by selecting the correct
5+
VMR base/head refs and running `release-notes-gen generate changes`. Handles
6+
preview-only multi-branch targeting (`main` vs release branches vs tags) and
7+
emits the authoritative manifest of what shipped. DO NOT USE FOR: API
8+
verification/diffs (use api-diff), feature scoring (use generate-features),
9+
or writing markdown release notes (use release-notes).
10+
---
11+
12+
# Generate `changes.json`
13+
14+
Produce the authoritative `changes.json` input for a preview, RC, or GA release milestone.
15+
16+
This is the **VMR-aware data acquisition stage** of the release notes pipeline:
17+
18+
1. Determine which milestone(s) are active
19+
2. Resolve the correct `--base` and `--head` refs
20+
3. Run `release-notes-gen generate changes`
21+
4. Write `changes.json` into the correct `release-notes/` folder
22+
23+
## When to use
24+
25+
- A new preview, RC, or GA milestone needs fresh shipped-change data
26+
- The user wants to know whether **multiple preview milestones** are active at once
27+
- The release notes branch should be refreshed after the VMR moved forward
28+
- `changes.json` is missing, stale, or suspected to have the wrong ref selection
29+
30+
## Preview-only branch targeting
31+
32+
This is the subtle part, and it mostly matters for **previews**.
33+
34+
Multiple preview milestones can be active simultaneously:
35+
36+
```text
37+
Latest shipped in this repo: Preview 3
38+
VMR main: Preview 5
39+
VMR release branch exists: Preview 4
40+
41+
→ Generate one `changes.json` for Preview 4
42+
→ Generate one `changes.json` for Preview 5
43+
```
44+
45+
For each target milestone `N`:
46+
47+
| Milestone state | Base ref | Head ref |
48+
| --------------------------------------- | ----------- | ------------------ |
49+
| Tag exists for N | Tag for N-1 | Tag for N |
50+
| Release branch exists for N, no tag yet | Tag for N-1 | Release branch tip |
51+
| Only on `main` | Tag for N-1 | `main` |
52+
53+
**Critical rule:** never use `main` for milestone `N` if `main` has already moved to `N+1`.
54+
55+
## Inputs
56+
57+
The user should provide as much of this as they know:
58+
59+
- **Target release** — e.g. `.NET 11 Preview 4`, `.NET 10 RC 2`, `.NET 10 GA`
60+
- **VMR clone path** — defaults to a local clone of `dotnet/dotnet`
61+
- Optionally, the exact refs if they already know them
62+
63+
If the user does **not** specify the milestone, infer it from:
64+
65+
1. `release-notes/{version}/releases.json` in this repo
66+
2. `eng/Versions.props` on `main` in the VMR
67+
3. Matching preview tags and release branches in the VMR
68+
69+
## Process
70+
71+
### 1. Determine the floor from `releases.json`
72+
73+
Find the latest shipped milestone in this repo. That tells you the lowest in-flight milestone that may need work.
74+
75+
### 2. Inspect the VMR
76+
77+
- Read `eng/Versions.props` on `main` to determine the current prerelease iteration
78+
- List matching VMR tags for finalized milestones
79+
- List matching VMR release branches for stabilizing milestones
80+
81+
Use the [VMR structure reference](../release-notes/references/vmr-structure.md) for naming conventions and branch patterns.
82+
83+
### 3. Resolve `--base` and `--head`
84+
85+
For each active milestone:
86+
87+
- `--base` is the previous shipped milestone tag
88+
- `--head` is the milestone tag, release branch tip, or `main`, depending on what exists
89+
90+
### 4. Generate the file
91+
92+
```bash
93+
release-notes-gen generate changes <vmr-clone-path> \
94+
--base <previous-release-tag> \
95+
--head <current-release-ref> \
96+
--version "<release-version>" \
97+
--date "<yyyy-mm-dd>" \
98+
--labels \
99+
--output release-notes/<major.minor>/<milestone-path>/changes.json
100+
```
101+
102+
Examples:
103+
104+
```bash
105+
# Preview milestone
106+
release-notes-gen generate changes ~/git/dotnet \
107+
--base v11.0.0-preview.3.26210.100 \
108+
--head origin/release/11.0.1xx-preview4 \
109+
--version "11.0.0-preview.4" \
110+
--labels \
111+
--output release-notes/11.0/preview/preview4/changes.json
112+
113+
# GA/patch milestone
114+
release-notes-gen generate changes ~/git/dotnet \
115+
--base v10.0.7 \
116+
--head v10.0.8 \
117+
--version "10.0.8" \
118+
--output release-notes/10.0/10.0.8/changes.json
119+
```
120+
121+
## Output contract
122+
123+
The output file must follow the shared schema documented in [changes-schema.md](../release-notes/references/changes-schema.md):
124+
125+
- top-level `release_version`, `release_date`, `changes`, `commits`
126+
- stable `id` values in `repo@shortcommit` format
127+
- same authoritative source of truth used by later skills
128+
129+
Once `changes.json` exists, the next step is usually `generate-features`.

0 commit comments

Comments
 (0)