diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 99235c19a30cd..6175fa98c33be 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -1,24 +1,20 @@
# .NET Documentation Guidelines
-IMPORTANT: For any Markdown files generated by AI, always disclose that they were created with the assistance of AI. If missing, add the `ai-usage` frontmatter key/value pair:
-
-- When reviewing a PR not created by AI:
+- .NET 8 is an LTS (long-term support) release that's still supported
+- .NET 9 is the latest STS (short-term support) version
+- .NET 10 is the latest LTS version
+- .NET 11 is in preview
- ```markdown
- ai-usage: ai-assisted
- ```
-
-- When Copilot generates the article through GitHub without the use of a human:
+IMPORTANT: For any Markdown files generated by AI, always disclose that they were created with the assistance of AI. If missing, add the `ai-usage` frontmatter key/value pair:
- ```markdown
- ai-usage: ai-generated
- ```
+| Frontmatter value | When to use |
+|-------------------|-------------|
+| ai-assisted | When Copilot adds new content to an existing article -or- fixes issues by rewriting content |
+| ai-generated | When Copilot generates an article with or without a template -or- when Copilot writes all of the content of an article |
-- When using an IDE with a human guiding AI:
+Don't apply or change the `ai-usage` value when doing reviews and edits
- ```markdown
- ai-usage: ai-assisted
- ```
+Don't apply the `ai-usage` metadata to files in the .github folder.
## Terminology
diff --git a/.github/prompts/InstallGuide.UpdateDependencies.prompt.md b/.github/prompts/InstallGuide.UpdateDependencies.prompt.md
deleted file mode 100644
index 43332c2f85ee3..0000000000000
--- a/.github/prompts/InstallGuide.UpdateDependencies.prompt.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-name: InstallGuide.UpdateDependencies
-agent: agent
-description: This prompt is used to update the .NET prerequisites for various Linux distributions in the documentation.
-tools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'web', 'github/get_file_contents', 'todo']
----
-You are a support engineer documenting the .NET prerequisites for various Linux distributions. You have old documentation that needs to be updated to reflect the latest .NET dependencies. Some of the information may be incorrect or outdated.
-
-The supported .NET versions are .NET 8, .NET 9, .NET 10, with .NET 11 in preview. .NET 11 shouldn't be documented as we don't document preview releases in the installation guide. The source of most up-to-date information is the `os-packages.json` file in the .NET GitHub repository. Use the GitHub MCP server to get the files.
-
-- **.NET 10**: `https://github.com/dotnet/core/blob/v10.0.8/release-notes/10.0/os-packages.json`
-- **.NET 9**: `https://github.com/dotnet/core/blob/v10.0.8/release-notes/9.0/os-packages.json`
-- **.NET 8**: Doesn't exist. For the most part, the packages are the same as .NET 9 except that zlib is required for .NET 8. Some packages may differ in name between .NET 8 and .NET 9.
-
-Cross-reference the distribution and find the required dependencies for that distribution. Then, update the dependencies section of the article to ensure it includes all required dependencies for that distribution. If there is no source material for the .NET version (like .NET 8), use the closest version available (like .NET 9) and make any necessary adjustments based on known differences. The article should already have dependencies that work for at least .NET 8.
-
-For .NET 9 and .NET 10, use the exact dependencies listed in the `os-packages.json` file.
-
-If existing versions are listed, ensure that any new dependencies are added to the list without removing existing ones, unless they are no longer required.
-
-zlib is required for .NET 8, but not for .NET 9 or .NET 10.
-
-Remove libgdiplus and any related notes.
\ No newline at end of file
diff --git a/.github/prompts/InstallGuide.UpdateSupportedOS.prompt.md b/.github/prompts/InstallGuide.UpdateSupportedOS.prompt.md
deleted file mode 100644
index 96c8ec4d3700e..0000000000000
--- a/.github/prompts/InstallGuide.UpdateSupportedOS.prompt.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-name: InstallGuide.UpdateSupportedOS
-agent: agent
-description: This prompt is used to update the supported operating systems for different versions of .NET in the documentation.
-tools: ['vscode', 'execute', 'read', 'agent', 'edit', 'search', 'web', 'github/get_file_contents', 'todo']
----
-You are a support engineer documenting which operating systems are supported with different versions of .NET. You have old documentation that needs to be updated to reflect the latest information. Some of the information may be incorrect or outdated.
-
-The supported .NET versions are .NET 8, .NET 9, .NET 10, with .NET 11 in preview. .NET 11 shouldn't be documented as we don't document preview releases in the installation guide. The source of most up-to-date information is the `supported-os.json` file in the .NET GitHub repository. Use the GitHub MCP server to get the files.
-
-- **.NET 10**: `https://github.com/dotnet/core/blob/v10.0.8/release-notes/10.0/supported-os.json`
-- **.NET 9**: `https://github.com/dotnet/core/blob/v10.0.8/release-notes/9.0/supported-os.json`
-- **.NET 8**: `https://github.com/dotnet/core/blob/v10.0.8/release-notes/8.0/supported-os.json`
-
-## Actions
-
-- Cross-reference the operating system and find which versions are supported
-- Update the appropriate sections of the article to reflect the latest information
-- Ensure that the tables listing supported operating systems for each .NET version are accurate and complete
-- If an operating system version is no longer supported for a specific .NET version, remove it from the list
-- If a new operating system version has been added for a specific .NET version, add it to the list
-- Ensure that any notes about end-of-life or end-of-support dates are accurate and up-to-date
-- Maintain the existing format and style of the documentation while making updates
diff --git a/.github/prompts/Snippets.Migrate.prompt.md b/.github/prompts/Snippets.Migrate.prompt.md
deleted file mode 100644
index 74b05679182f0..0000000000000
--- a/.github/prompts/Snippets.Migrate.prompt.md
+++ /dev/null
@@ -1,115 +0,0 @@
----
-agent: agent
-model: Claude Sonnet 4.6 (copilot)
-description: Migrate code from the old ~/samples/snippets/ location to the relative ./snippets location.
----
-
-# Migrate code snippets
-
-We no longer use the `~/samples/snippets/` location for code snippets. All code snippets must be migrated to the new `./snippets/` location, which is relative to the article using the snippet. Generally, snippets in the old location are outdated, incomplete, and often can't compile. The new location requires that all snippets be complete, compilable, and include project files. Additionally, the new location requires both C# and Visual Basic versions of each snippet.
-
-**IMPORTANT**: Unless otherwise asked to, **only** edit the article file in context. At the end of your operations you may ask for permission to edit other articles referencing the same snippets.
-
-## Repository structure for code snippets
-
-**IMPORTANT**: This repository has TWO different locations for code snippets:
-
-### Old location (legacy - to be migrated FROM)
-- Path: `~/samples/snippets/`
-- Example: `~/samples/snippets/csharp/VS_Snippets_Winforms/System.Windows.Forms.Clipboard/CS/form1.cs`
-
-**Problems with legacy code:**
-- Written for .NET Framework (outdated)
-- Often incomplete and can't compile
-- May lack project files
-- Uses outdated syntax and patterns
-
-**Legacy article references generally use old syntax:**
-```markdown
-[!code-{code-language}[description](~/samples/snippets/{path-to-file}#{snippet-identifier})]
-```
-### New location (current standard - migrate TO)
-- Path pattern: `./snippets/{article-filename-using-snippet}/[optional-sub-subject]/{code-language}/`
-- Example C#: `./snippets/anchors-in-regular-expressions/csharp/Form1.cs`
-- Example VB: `./snippets/anchors-in-regular-expressions/vb/Form1.vb`
-
-**Path components explained:**
-- `./`: Current folder of the article being edited
-- `snippets/`: Root folder for all snippets
-- `{article-filename-using-snippet}`: The markdown article filename WITHOUT the `.md` extension
- - Example: For article `anchors-in-regular-expressions.md` → use `anchors-in-regular-expressions`
-- `[optional-sub-subject]`: An optional subfolder to avoid clashes. Used when a snippet in the article can't be merged with existing snippets. Examples of this would be two different snippets that both use a `Program.cs` file. For example, if there were two snippets in the same file demonstrating an Async `main` and a non-Async `main`, you could create descriptive subfolders like `AsyncProgram/` and `SyncProgram/` to avoid conflicts.
-- `{code-language}`:
- - `csharp`: For C# code
- - `vb`: For Visual Basic code
-
-**IMPORTANT**: Exception to the rules about having multiple code languages: For language guide articles, only the guide's language is required — do not create a version in the other language. The C# Language guide only contains CS code snippets, and the VB Language guide only contains VB code snippets. All other articles should follow the full path pattern including the `{code-language}/` subfolder. For example, you wouldn't use the `./snippets/article-name/csharp/` or `./snippets/article-name/vb/` folder structures for an article in the C# language guide, the folder would simply be `./snippets/article-name/` and the code in C#. The same applies to the VB language guide.
-
-**Requirements for current code standards:**
-- ✅ MUST be complete and compilable
-- ✅ MUST include a project file
-- ✅ MUST target the latest .NET or .NET Framework version as appropriate based on article context
-- ✅ MUST provide BOTH C# and Visual Basic versions
-- ✅ MUST use appropriate syntax for the target framework
-- ✅ MUST use meaningful, descriptive snippet identifiers in CamelCase format
- - **Examples** of good snippet identifiers: `BasicClipboardData`, `CustomDataFormat`, `ClipboardImageHandling`
- - **Avoid** simplistic identifiers like `1`, `2`, `code1`, or `snippet1`
-
-**Current article references look like this:**
-```markdown
-:::code language="{code-language}" source="{relative-file-path}" id="{snippet-identifier}":::
-```
-
-## Migration steps (follow in order)
-
-**STEP-BY-STEP PROCESS:**
-
-### 1. Analyze existing code and article context
-- **Find**: Locate the legacy snippet file references to `~/samples/snippets/` (path may be relative, navigating back to the root `samples` folder)
-- **Identify**: Determine the programming language (C# or Visual Basic)
-- **Extract**: Note the snippet identifier used in the article reference
-
-### 2. Create new or reuse existing folder structure
-- **Pattern**: `./snippets/{article-filename-using-snippet}/[optional-sub-subject]/{code-language}/`
-- **Example**: For article `clipboard-operations.md` → create `./snippets/clipboard-operations/csharp/`
-- **Reuse**: If the article already has snippets in the new location, reuse the existing folder structure and try to merge the code into the existing snippets if possible. Use new classes and code files as needed. Code **ONLY** needs to compile, it doesn't have to run from the program main.
-- **Create**: If no existing folder structure exists for the article, create a new one following the pattern above.
-- **New projects**: **NEVER** create project files manually. Always use the `dotnet` CLI to ensure correct formatting and structure of new code. Projects should be console apps unless otherwise required (such as a Windows Forms-related snippet)
- - Specify a meaningful project name with the `-n` parameter.
- - Example 1: An article about clipboard handling, use `dotnet new console -n ClipboardExample`
- - Example 2: An article about events would be `dotnet new console -n EventsOverview`
-
-### 3. Migrate and update code
-- **Copy**: Copy only the snippet code (and any supporting code to compile the snippet) to the new location
-- **Complete**: Ensure code is fully functional and compilable
-
-### 4. Create both language versions
-- **Requirement**: MUST provide both C# and Visual Basic versions, except for language guide articles (C# or VB guide), where only the guide's language is required.
-- **Standard articles** (both languages required):
- - **C# path**: `./snippets/{article-filename-using-snippet}/csharp/`
- - **VB path**: `./snippets/{article-filename-using-snippet}/vb/`
-- **Language guide articles** (single language, no `{code-language}` subfolder):
- - **C# guide path**: `./snippets/{article-filename-using-snippet}/`
- - **VB guide path**: `./snippets/{article-filename-using-snippet}/`
-
-### 5. Update article references
-- **Replace**: Change from legacy `[!code-...]` format to modern `:::code...:::` format
-- **Before**: `[!code-csharp[description](~/samples/snippets/path/file.cs#snippet1)]`
-- **After**: `:::code language="csharp" source="./snippets/article-name/csharp/file.cs" id="BasicClipboardData":::`
-- **Note**: Use meaningful CamelCase identifiers instead of simple numbers
-
-### 6. Validate
-- **Build**: Ensure all code compiles successfully
-
-### 7. Delete
-- **Identify**:
- - Check if the old snippet file is used by any other articles. Search for the old snippet path across the repository to find any references. This can be done by searching for links to `samples/snippets/...` (the file path used in the snippet reference) since some articles may use a relative path to the `samples` folder instead of absolute paths.
-- **Delete**: If old snippet was migrated and is no longer used by any other article, delete it.
-
-## Common mistakes to avoid
-
-- ❌ **Don't** assume all code needs to be modernized - check article context first
-- ❌ **Don't** forget to create both C# and VB versions
-- ❌ **Don't** mix up the framework targeting (net vs framework)
-- ❌ **Don't** forget to update ALL article references to the migrated code
-- ❌ **Don't** leave incomplete or non-compilable code
diff --git a/.github/prompts/Snippets.Push.prompt.md b/.github/prompts/Snippets.Push.prompt.md
deleted file mode 100644
index 49b244a6f150d..0000000000000
--- a/.github/prompts/Snippets.Push.prompt.md
+++ /dev/null
@@ -1,114 +0,0 @@
----
-agent: agent
-model: Claude Sonnet 4.6 (copilot)
-description: Push inline code block snippets out of articles into standalone files with proper project structure.
----
-
-# Push inline code snippets to files
-
-**IMPORTANT**: Unless otherwise asked to, **only** extract snippets from the article file in context. At the end of your operations you may ask for permission to edit other articles that might benefit from the same snippet extraction.
-
-**IMPORTANT**: Don't share code across multiple articles. Each article should have its own copy of the snippet in its own folder structure.
-
-**IMPORTANT**: If only XAML snippets are present, only create C# projects to hold the XAML. Do not create VB projects for XAML-only snippets.
-
-## When to push snippets out of articles
-
-**PUSH SNIPPETS WHEN:**
-- Code blocks are longer than 6 lines
-- Code demonstrates complete, compilable examples
-- Code represents a complete application or significant functionality
-- User specifically requests snippet extraction
-
-**KEEP INLINE WHEN:**
-- Code blocks are 6 lines or shorter
-- Code is pseudo-code or conceptual examples
-
-## Target folder structure
-- Path pattern: `./snippets/{article-name}/[optional-sub-subject]/{code-language}/`
-- Example C#: `./snippets/create-app/csharp/`
-- Example VB: `./snippets/create-app/vb/`
-
-**Path components explained:**
-- `./`: Current folder of the article being edited
-- `snippets/`: Root folder for all snippets
-- `{article-name}`: The markdown article filename WITHOUT the `.md` extension
- - Example: For article `create-app.md` → use `create-app`
-- `[optional-sub-subject]`: An optional subfolder to avoid clashes. Used when snippets in the same article can't be merged — for example, two snippets that both require a `Program.cs` file but demonstrate different things. Use descriptive subfolder names like `AsyncProgram/` and `SyncProgram/`.
-- `{code-language}`:
- - `csharp`: For C# code (also use for XAML snippets)
- - `vb`: For Visual Basic code
-
-**Language guide exception**: For articles in the C# or VB language guides, only the guide's language is required — do not create a version in the other language, and omit the `{code-language}/` subfolder:
-- C# guide path: `./snippets/{article-name}/`
-- VB guide path: `./snippets/{article-name}/`
-
-## Push process
-
-### 1. Analyze and prepare
-- Locate code blocks >6 lines or complete examples (unless overridden by user request)
-- Identify the programming language(s) used
-- Determine if the article is in a language guide (C# or VB) to apply the language exception
-
-### 2. Decide how code will be placed
-- If the article talks about single-file apps, **STOP** and ask the user if they want to use a single-file app or a traditional project-based app
-- If the article doesn't talk about single-file apps, assume the code samples must be put into a project-based app
-
-### 2.1 Project-based apps
-- This is the default for moving code snippets from an article
-- **NEVER** create project files manually.
-- **ALWAYS** use the `dotnet` CLI. Default to console apps (`dotnet new console`) unless the snippet requires a different project type (for example, `dotnet new winforms` for a Windows Forms snippet). Don't specify an output folder with `-o`. Specify a meaningful project name with `-n` if possible.
-
-### 2.2 Single-file apps
-- This is not the default. You must have a good reason to use this mode, such as the user requested it or the article itself references single-file apps along with the snippets
-- Only C# is supported
-- VB snippets must use a project-based app approach
-- Multiple single-file apps can share the same folder for the article
-- Instead of `Program.cs`, they can be named anything
-- They are compiled with `dotnet run file.cs`
-- Folder must not have a project file
-
-### 3. Extract code
-- Copy and complete code to make it compilable. Code only needs to compile — it doesn't have to run from `Main`.
-- Add missing using statements, namespaces, and class declarations as needed.
-- Build to verify compilation with `dotnet build`.
-
-### 4. Add snippet markers and update article references
-- Add CamelCase region markers around each snippet. Snippet markers are added as comments in the language of the code file:
- - C#: `// ` and `// `
- - VB: `' ` and `' `
-- The angle brackets (`<` and `>`) are part of the comment markers only. The snippet identifier itself is the bare CamelCase name (for example, `SnippetId`), which is what you use in the `id` attribute.
-- Use the same identifiers across C# and VB versions.
-- Use meaningful, descriptive identifiers — avoid `1`, `2`, `code1`, or `snippet1`.
-- Replace each inline code block with a `:::code:::` reference:
- ```markdown
- :::code language="csharp" source="./snippets/doc-name/csharp/File.cs" id="ButtonClick":::
- :::code language="vb" source="./snippets/doc-name/vb/File.vb" id="ButtonClick":::
- ```
-- DO NOT use language tabs in the article — place references side-by-side, like so:
- ```markdown
- :::code language="csharp" source="./snippets/doc-name/csharp/File.cs" id="ButtonClick":::
- :::code language="vb" source="./snippets/doc-name/vb/File.vb" id="ButtonClick":::
- ```
-- Verify all paths and identifiers are correct.
-
-### 5. Update article frontmatter
-If both C# and VB examples are provided, ensure the following frontmatter is present at the top of the article:
-
-```yml
-dev_langs:
- - "csharp"
- - "vb"
-```
-
-If a single language is used (like in the language guides), omit the `dev_langs` section.
-
-## Common mistakes to avoid
-
-- ❌ Extracting short snippets (≤6 lines) without being asked
-- ❌ Creating project files manually instead of using `dotnet new` (when using project-based apps)
-- ❌ Missing C# or VB versions for standard articles
-- ❌ Creating VB projects for XAML-only snippets
-- ❌ Using language tabs instead of side-by-side references
-- ❌ Missing or inconsistent snippet region identifiers
-- ❌ Code that doesn't compile
diff --git a/.github/skills/create-snippet-folders/SKILL.md b/.github/skills/create-snippet-folders/SKILL.md
new file mode 100644
index 0000000000000..2434517d1a19a
--- /dev/null
+++ b/.github/skills/create-snippet-folders/SKILL.md
@@ -0,0 +1,60 @@
+---
+name: create-snippet-folders
+description: 'Creates article-relative ./snippets/ directories and returns their paths. Use when a snippet workflow needs folders composed from an article path plus caller-selected platform, conflict-avoidance subject, and code-language segments.'
+argument-hint: 'Provide the article file and each requested platform, subject, and language path'
+user-invocable: false
+version: 1.0
+owner: adegeo
+---
+
+# Create Snippet Folders
+
+Create the requested folders that hold code snippets for one documentation article, and return their paths to the calling workflow. Don't choose the structure, inspect project compatibility, create projects, write example code, or update the article.
+
+## Caller Decision Guide
+
+Before requesting directories, choose the path segments as follows:
+
+- Use a platform segment only when the article demonstrates both .NET and .NET Framework approaches:
+ - Use `net` for .NET 6 or later snippets.
+ - Use `framework` for .NET Framework snippets.
+ - Otherwise, omit the platform segment.
+- Use a descriptive subject segment when snippets can't coexist and compile in one project. For example, use `AsyncProgram` and `SyncProgram` when two examples both require a `Program.cs` file. Otherwise, omit the subject segment.
+- Use `csharp` for C# code or `vb` for Visual Basic code. Omit the language segment only when the caller requests the article's shared snippet root rather than a language-specific directory.
+
+## Input
+
+Require the calling workflow to provide:
+
+- The target Markdown article.
+- A list of requested directories. Each directory must specify:
+ - The platform segment: `net`, `framework`, or omitted.
+ - The subject segment, or omitted.
+ - The language segment: `csharp`, `vb`, or omitted.
+
+The caller must decide whether the article requires platform separation, a subject folder to prevent conflicts, and a language folder. If any segment decision is missing, return control to the caller without creating folders. Don't infer missing segments from the article or existing snippets.
+
+## Create the Structure
+
+For each requested directory:
+
+1. Use the folder that contains the target article as the base directory.
+2. Use the article filename without `.md` as `{article-name}`.
+3. Construct the path in this order:
+
+ `./snippets/{article-name}/[platform]/[subject]/[language]/`
+
+4. Omit every segment that the caller explicitly marks as omitted. Don't reorder or rename supplied segments.
+5. Create the directory and any missing parent directories. If the directory already exists, leave it and its contents unchanged.
+6. Return the article-relative and repository-relative path, and report whether the directory was created or already existed.
+
+## Example Requests
+
+Given `docs/core/create-app.md`, these inputs produce these paths:
+
+- Platform omitted, subject omitted, language `csharp`: `./snippets/create-app/csharp/`
+- Platform `net`, subject omitted, language `vb`: `./snippets/create-app/net/vb/`
+- Platform omitted, subject `AsyncProgram`, language `csharp`: `./snippets/create-app/AsyncProgram/csharp/`
+- Platform omitted, subject omitted, language omitted: `./snippets/create-app/`
+
+The skill treats all supplied segments as opaque path decisions except for validating the allowed platform and language values.
\ No newline at end of file
diff --git a/.github/skills/install-guide-updates/SKILL.md b/.github/skills/install-guide-updates/SKILL.md
new file mode 100644
index 0000000000000..ac1e496f5f6e9
--- /dev/null
+++ b/.github/skills/install-guide-updates/SKILL.md
@@ -0,0 +1,99 @@
+---
+name: install-guide-updates
+description: 'Updates .NET Linux installation-guide content for supported distribution versions and native dependencies. Use when refreshing Linux install articles, support tables, prerequisites, package lists, or end-of-life notes for .NET 8, .NET 9, and .NET 10.'
+argument-hint: 'Provide an installation article or Linux distribution to update'
+version: 1.0
+---
+
+# Update the .NET Linux Installation Guide
+
+Update an existing Linux installation article so that its supported operating system versions and native dependency lists agree with the pinned .NET release metadata.
+
+## Scope
+
+- Document .NET 8, .NET 9, and .NET 10.
+- Don't document .NET 11 or another preview release in the installation guide.
+- Preserve the article's existing structure, Markdown style, and distribution-specific package-manager syntax.
+- Limit edits to support information, end-of-life notes, prerequisites, and directly related text unless another change is required for consistency.
+
+## Authoritative Sources
+
+Use the GitHub MCP server to read the files from the `dotnet/core` repository using the matching tag. Don't infer metadata from the rendered GitHub pages when the source files are available.
+
+| .NET version | Tag | Supported operating systems | Native dependencies |
+| --- | --- | --- | --- |
+| .NET 10 | `v10.0.11` | `release-notes/10.0/supported-os.json` | `release-notes/10.0/os-packages.json` |
+| .NET 9 | `v9.0.19` | `release-notes/9.0/supported-os.json` | `release-notes/9.0/os-packages.json` |
+| .NET 8 | `v8.0.30` | `release-notes/8.0/supported-os.json` | Use the .NET 9 package data as described in step 4 |
+
+Source URLs:
+
+- `https://github.com/dotnet/core/blob/v10.0.11/release-notes/10.0/supported-os.json`
+- `https://github.com/dotnet/core/blob/v9.0.19/release-notes/9.0/supported-os.json`
+- `https://github.com/dotnet/core/blob/v8.0.30/release-notes/8.0/supported-os.json`
+- `https://github.com/dotnet/core/blob/v10.0.11/release-notes/10.0/os-packages.json`
+- `https://github.com/dotnet/core/blob/v9.0.19/release-notes/9.0/os-packages.json`
+
+## Workflow
+
+### 1. Identify the target
+
+1. Determine the installation article and Linux distribution from the user's request. If the user provides only one of them, search the installation-guide content for the matching article.
+2. Read the entire target article before you edit it.
+3. Identify every support table, version-specific prerequisite list, shared dependency list, and related end-of-life note in the article.
+4. Note how the article separates package names by distribution version and .NET version. Keep that organization unless it prevents the article from expressing accurate requirements.
+
+### 2. Retrieve release metadata
+
+1. Read all three `supported-os.json` files from the authoritative sources.
+2. Read the .NET 9 and .NET 10 `os-packages.json` files.
+3. Select entries that match the target distribution. Check distribution names, IDs, version labels, architectures, and qualifiers instead of relying on a partial name match.
+4. Record the source entries that control each planned documentation change. If no entry matches, stop and report the missing source data instead of guessing.
+
+### 3. Update operating system support
+
+1. Cross-reference the target distribution in each `supported-os.json` file.
+2. Make each support table accurate and complete for .NET 8, .NET 9, and .NET 10:
+ - Add newly supported distribution versions.
+ - Remove distribution versions that aren't supported for that .NET release.
+ - Preserve architecture or support qualifiers from the source when the article represents them.
+3. Update related end-of-life or end-of-support notes only when an authoritative source confirms the date. Don't invent or estimate dates.
+4. Remove preview-version rows and notes, including .NET 11.
+
+### 4. Update native dependencies
+
+1. For .NET 9 and .NET 10, use the exact dependencies listed for the target distribution in the corresponding `os-packages.json` file.
+2. For .NET 8, start with the closest matching .NET 9 dependency entry (use .NET 9 URL and tag) because no .NET 8 `os-packages.json` file exists:
+ - Add the distribution's zlib package. zlib is required for .NET 8, but not for .NET 9 or .NET 10.
+ - Preserve existing .NET 8 package-name differences when they are necessary for the applicable distribution version.
+ - Preserve other existing .NET 8 dependencies unless the release metadata or the article's supported package set shows that they are no longer required.
+3. If one command installs dependencies for multiple .NET versions, use version pivots or separate commands when necessary to keep the .NET 9 and .NET 10 lists exact and the .NET 8 zlib requirement clear.
+4. Remove `libgdiplus` from dependency lists and remove notes that tell users to install or configure it.
+5. Don't add a dependency merely because another distribution requires it.
+
+### 5. Reconcile the article
+
+1. Check prose, examples, tabs, includes, and notes for claims that conflict with the updated tables and dependency lists.
+2. Keep commands valid for the distribution version and package manager that each section covers.
+3. Retain existing dependencies that apply outside the version-specific .NET runtime lists only when the article explains their separate purpose.
+4. Apply the repository's Markdown writing instructions and AI-usage frontmatter requirements to every article you change.
+
+### 6. Validate the update
+
+1. Compare every documented support row with the matching `supported-os.json` entry.
+2. Compare every .NET 9 and .NET 10 dependency list with the matching `os-packages.json` entry. The package sets must match exactly.
+3. Verify that every .NET 8 dependency path includes the correct zlib package.
+4. Search the changed article for `libgdiplus`, `.NET 11`, and preview installation-guide content; remove any instances that violate this workflow.
+5. Check that Markdown tables, links, includes, selectors, and code blocks remain syntactically valid. Run the narrowest available repository validation for the changed files.
+6. Review the final diff for unrelated changes.
+
+## Completion Report
+
+Summarize:
+
+- The distribution and article that you updated.
+- Support versions added or removed for each .NET release.
+- Dependency changes for each .NET release.
+- The release metadata files used.
+- Validation commands and their results.
+- Any ambiguity or missing source data that requires maintainer review.
\ No newline at end of file
diff --git a/.github/skills/migrate-code-snippets/SKILL.md b/.github/skills/migrate-code-snippets/SKILL.md
new file mode 100644
index 0000000000000..e39e66ec1d9e6
--- /dev/null
+++ b/.github/skills/migrate-code-snippets/SKILL.md
@@ -0,0 +1,96 @@
+---
+name: migrate-code-snippets
+description: 'Migrates .NET documentation code from the legacy ~/samples/snippets/ location to article-relative ./snippets/ projects for an input article file. Use when replacing legacy [!code-*] references, creating compilable C# and Visual Basic snippet projects, or removing migrated legacy snippets.'
+argument-hint: 'Provide the Markdown article file whose legacy snippets need migration'
+owner: adegeo
+version: 2
+---
+
+# Migrate Code Snippets
+
+Migrate code snippets from the legacy `~/samples/snippets/` location to the `./snippets/` location relative to the article that uses the snippet. Legacy snippets are often outdated, incomplete, and unable to compile. New snippets must be complete, compilable, and include project files. Unless the article is part of a language guide, provide both C# and Visual Basic versions of each snippet.
+
+## Input
+
+This skill requires one Markdown article file as input. Treat the supplied file as the target article. If the user doesn't provide a file, ask for one before you begin the migration. Don't update other articles that reference the same legacy snippets.
+
+## Avoid Common Mistakes
+
+- Don't modernize the code.
+- Don't omit either the C# or Visual Basic version, except for language-guide articles.
+- Preserve whether the example targets .NET or .NET Framework.
+- Update every legacy snippet reference in the target article.
+- Don't leave incomplete or noncompilable code.
+
+## Legacy Snippets
+
+- Path: `~/samples/snippets/`
+- Example: `~/samples/snippets/csharp/VS_Snippets_Winforms/System.Windows.Forms.Clipboard/CS/form1.cs`
+
+Legacy code is often written for .NET Framework, incomplete, unable to compile, missing project files, or written with older syntax and patterns.
+
+Legacy article references generally use this syntax:
+
+```markdown
+[!code-{code-language}[description](~/samples/snippets/{path-to-file}#{snippet-identifier})]
+```
+
+## Migration Workflow
+
+Follow these steps in order.
+
+### 1. Analyze the Code and Article
+
+1. Locate every legacy snippet reference in the target article. References might use `~/samples/snippets/` or a relative path that navigates to the repository's `samples` folder.
+2. Identify the language of each reference.
+3. Record each source file and snippet identifier.
+4. Read the referenced legacy code and enough article context to preserve its behavior and target platform.
+5. Determine which examples require separate subject folders because their entry points, project types, target frameworks, or dependencies conflict.
+
+### 2. Create the Snippet Folder Structure
+
+Choose every required platform, subject, and language path segment. For a language-guide article, omit the language segment. Load and follow the `create-snippet-folders` skill with the target article and the complete list of chosen segments. Use the returned directories for the migrated files.
+
+### 3. Create or Reuse the Projects
+
+Reuse an existing project only when its language, platform, project type, and dependencies are compatible with the migrated code. For each new project, change to its intended snippet directory and use the `dotnet` CLI to create it. Never create project files manually, and don't specify an output folder with `-o`.
+
+Use `dotnet new console` unless the snippet requires another project type, such as Windows Forms. Specify a meaningful project name with `-n`, such as `ClipboardExample` or `EventsOverview`.
+
+### 4. Migrate the Code
+
+1. Copy the snippet code and only the supporting code required for it to compile.
+2. Preserve the original code and behavior. Don't modernize it.
+3. Add only the minimum scaffolding necessary for compilation.
+
+For every structure returned by the shared skill, provide the corresponding C# or Visual Basic version. The code must compile, but the project entry point doesn't need to run every snippet.
+
+### 5. Update the Article References
+
+Replace every legacy reference in the target article with the current directive and a meaningful CamelCase identifier.
+
+Before:
+
+```markdown
+[!code-csharp[description](~/samples/snippets/path/file.cs#snippet1)]
+```
+
+After:
+
+```markdown
+:::code language="csharp" source="./snippets/article-name/csharp/file.cs" id="BasicClipboardData":::
+```
+
+### 6. Validate the Projects
+
+Build every C# and Visual Basic project that the migration creates or changes. The projects don't need to run, but all builds must succeed.
+
+### 7. Remove Unused Legacy Files
+
+1. Search the entire repository for each migrated legacy snippet path. Account for references that use different relative paths to reach the same file.
+2. Delete a legacy snippet file only when no article still references it.
+3. Don't change other articles unless the user requested those changes. Report any remaining references and ask for permission to migrate them separately.
+
+### 8. Report the Migration
+
+Use each workflow step title as a heading, and summarize what you did for that step with bullet points. Include all build commands and results, remaining references from other articles, and any legacy files that you couldn't delete.
\ No newline at end of file
diff --git a/.github/skills/push-code-snippets/SKILL.md b/.github/skills/push-code-snippets/SKILL.md
new file mode 100644
index 0000000000000..a341d55278d43
--- /dev/null
+++ b/.github/skills/push-code-snippets/SKILL.md
@@ -0,0 +1,136 @@
+---
+name: push-code-snippets
+description: 'Extracts inline code blocks from an input .NET documentation article file into article-relative ./snippets/ files and compilable projects. Use when moving fenced C#, Visual Basic, or XAML examples out of Markdown, adding :::code references and snippet markers, or converting embedded samples to standalone snippet projects.'
+argument-hint: 'Provide the Markdown article file whose inline snippets need extraction'
+---
+
+# Push Code Snippets
+
+Move eligible inline code blocks from the target article into standalone files under an article-relative `./snippets/` folder. Add compilable project scaffolding and replace each extracted block with a `:::code` reference.
+
+## Input
+
+This skill requires one Markdown article file as input. Treat the supplied file as the target article. If the user doesn't provide a file, ask for one before you begin the extraction.
+
+## Select Snippets
+
+Extract an inline code block when any of these conditions apply:
+
+- The block is longer than six lines.
+- The block demonstrates a complete, compilable example.
+- The block represents a complete application or significant functionality.
+- The user explicitly requests its extraction.
+
+Keep blocks of six lines or fewer inline unless another condition applies. Keep pseudocode and conceptual examples inline.
+
+## Extraction Workflow
+
+Follow these steps in order.
+
+### 1. Analyze the Article
+
+1. Locate all eligible inline code blocks in the target article.
+2. Identify each block's language and platform.
+3. Determine whether the article belongs to the C# or Visual Basic language guide.
+4. Check whether the article discusses single-file applications.
+5. Determine which examples require separate subject folders because their entry points, project types, target frameworks, or dependencies conflict.
+
+### 2. Generate the Snippet Structure
+
+Choose every required platform, subject, and language path segment. For a language-guide article, omit the language segment. For XAML-only snippets, request only the `csharp` language segment.
+
+Load and follow the `generate-snippet-structure` skill with the target article and the complete list of chosen segments. Use the returned directories for the extracted files.
+
+### 3. Choose the Application Structure
+
+If the article discusses single-file applications, stop and ask the user whether to use single-file applications or traditional project-based applications.
+
+Otherwise, use project-based applications. Reuse an existing project only when its language, platform, project type, and dependencies are compatible with the new code. For each new project, change to its intended snippet directory and use the `dotnet` CLI to create it. Never create project files manually, and don't specify an output folder with `-o`. Specify a meaningful project name with `-n` when practical. Use `dotnet new console` unless the snippet requires another project type, such as `dotnet new winforms`.
+
+Use single-file applications only when the user requests them or confirms their use for an article that discusses them. Single-file applications:
+
+- Support only C#. Use a project for Visual Basic snippets.
+- Can share the article's snippet folder.
+- Can use descriptive filenames instead of `Program.cs`.
+- Must not have a project file in their folder.
+- Must be validated with `dotnet run file.cs`.
+
+### 4. Extract and Complete the Code
+
+1. Copy each selected block into the appropriate snippet file.
+2. Add only the imports, namespaces, types, and other scaffolding required for compilation.
+3. Preserve the example's documented behavior.
+4. For standard articles, provide both C# and Visual Basic versions unless the snippets contain only XAML.
+5. For language-guide articles, provide only the guide's language.
+
+The code must compile, but the project entry point doesn't need to execute every snippet.
+
+### 5. Add Markers and References
+
+Wrap each extracted snippet in comments with a meaningful CamelCase identifier. Use the same identifier in equivalent C# and Visual Basic examples.
+
+C# markers:
+
+```csharp
+//
+...code here...
+//
+```
+
+Visual Basic markers:
+
+```vb
+'
+...code here...
+'
+```
+
+Don't use identifiers such as `1`, `2`, `code1`, or `snippet1`.
+
+Replace each inline block with a `:::code` reference:
+
+```markdown
+:::code language="{code-language}" source="{relative-file-path}" id="{snippet-identifier}":::
+```
+
+For example:
+
+```markdown
+:::code language="csharp" source="./snippets/doc-name/csharp/File.cs" id="ButtonClick":::
+
+:::code language="vb" source="./snippets/doc-name/vb/File.vb" id="ButtonClick":::
+```
+
+Place C# and Visual Basic references one after the other. Don't put them in language tabs. Verify every source path and identifier against the created files.
+
+### 6. Update Article Frontmatter
+
+When the article includes both C# and Visual Basic examples, ensure its frontmatter contains an entry for each language:
+
+```yml
+dev_langs:
+ - "csharp"
+ - "vb"
+```
+
+Omit `dev_langs` when the article uses only one language, such as an article in a language guide.
+
+Markup languages don't require languages in the frontmatter. For example, XAML snippets don't require a `dev_langs` entry.
+
+Because this workflow rewrites an existing article, ensure its frontmatter contains `ai-usage: ai-assisted` unless the user asks only for a review without edits.
+
+### 7. Validate the Result
+
+1. Build every project that the extraction creates or changes with `dotnet build`.
+2. Run every single-file application with `dotnet run file.cs`.
+3. Verify that all `:::code` paths resolve and all identifiers match their markers.
+4. Report the validation commands and results, plus any eligible blocks that remain inline and why.
+
+## Avoid Common Mistakes
+
+- Don't extract short snippets without a qualifying reason.
+- Don't omit either C# or Visual Basic from a standard article.
+- Don't create Visual Basic projects for XAML-only snippets.
+- Don't use language tabs for snippet references.
+- Don't omit or mismatch snippet markers.
+- Don't leave extracted code in a noncompilable state.
\ No newline at end of file