{"owner":"microsoft","repo":"aspire","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md"],"skills":{"AGENTS.md":"# Agent Instructions\n\nInstructions for GitHub Copilot and other AI coding agents working with the Aspire repository.\n\n## Repository Overview\n\n**Aspire** provides tools, templates, and packages for building observable, production-ready distributed applications. At its core is an app model that defines services, resources, and connections in a code-first approach.\n\n### Key Components\n- **Aspire.Hosting**: Application host orchestration and resource management\n- **Aspire.Dashboard**: Web-based dashboard for monitoring and debugging\n- **Service Discovery**: Infrastructure for service-to-service communication\n- **Integrations**: 40+ packages for databases (SQL Server, PostgreSQL, Redis, MongoDB), message queues (RabbitMQ, Kafka), cloud services (Azure), and more\n- **CLI Tools**: Command-line interface for project creation and management\n- **Project Templates**: Starter templates for new Aspire applications\n\n### Technology Stack\n- .NET 10.0\n- C# 13 preview features\n- xUnit SDK v3 with Microsoft.Testing.Platform for testing\n- Microsoft.DotNet.Arcade.Sdk for build infrastructure\n- Native AOT compilation for CLI tools\n- Multi-platform support (Windows, Linux, macOS, containers)\n\n## General\n\n* Make only high confidence suggestions when reviewing code changes.\n* Always use the latest version C#, currently C# 13 features.\n* Never change global.json unless explicitly asked to.\n* Never change package.json or package-lock.json files unless explicitly asked to.\n* Never change NuGet.config files unless explicitly asked to.\n* Do not use cryptographic hashes such as SHA-256 when the hash is not security-related. Prefer `System.IO.Hashing.XxHash3` when you need a stable non-cryptographic hash.\n* When code needs a temporary directory, prefer the repository temp directory abstractions first (for example `IFileSystemService.TempDirectory` / `ITempFileSystemService`) and otherwise use `Directory.CreateTempSubdirectory()` instead of `Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())`; if you need a temporary file path, place it under a securely created temp directory.\n* Don't update files under `*/api/*.cs` (e.g. src/Aspire.Hosting/api/Aspire.Hosting.cs) as they are generated.\n* Do not make new parameters optional just to avoid updating call sites. A parameter should only be optional when it has a sensible semantic default and the API is frequently used (where call-site brevity outweighs explicitness). If a parameter is logically required, make it required and update all call sites.\n\n## Code Review Instructions\n\n### API Files and Public API Surface\n\nThe API files located in `*/api/*.cs` (e.g., `src/Aspire.Hosting/api/Aspire.Hosting.cs`) track the public API surface that has already been shipped in the latest release. These files are auto-generated and serve as a baseline for API compatibility checks.\n\nWhen reviewing pull requests:\n\n* **Do not comment when new public API is introduced and the API files are not regenerated**. This is expected behavior during active development between releases.\n* New public APIs should be reviewed for design, naming, and functionality, but the absence of API file updates during PR development is normal.\n* API files are regenerated as part of the release process when we ship a new version, not during individual PRs.\n* Only flag API file concerns if:\n  - API files are manually edited (they should never be manually modified)\n  - There are breaking changes to existing APIs without proper justification\n  - The PR explicitly claims to update API compatibility but doesn't regenerate the files\n\n### NuGet Feed Configuration\n\nThe NuGet.config file defines approved package sources for the internal build. External package feeds can break the internal build pipeline.\n\nWhen reviewing pull requests:\n\n* **Flag any changes to NuGet.config that add package sources not from these approved domains:**\n  - `https://pkgs.dev.azure.com/dnceng`\n  - `https://dnceng.pkgs.visualstudio.com/public`\n* **Flag any additions of external NuGet feeds** such as:\n  - `https://api.nuget.org/v3/index.json` (nuget.org)\n  - Any other public or third-party package sources\n* If a PR adds an external feed, request that:\n  - The packages be mirrored to an approved internal feed, or\n  - Use existing internal feeds that already mirror public packages (like dotnet-public, dotnet-eng)\n* The wildcard pattern mappings (`<package pattern=\"*\" />`) in dotnet-public and dotnet-eng feeds typically provide access to commonly-used public packages\n\n## Formatting\n\n* Apply code-formatting style defined in `.editorconfig`.\n* Prefer file-scoped namespace declarations and single-line using directives.\n* Insert a newline before the opening curly brace of any code block (e.g., after `if`, `for`, `while`, `foreach`, `using`, `try`, etc.).\n* Ensure that the final return statement of a method is on its own line.\n* Use pattern matching and switch expressions wherever possible.\n* Use `nameof` instead of string literals when referring to member names.\n* Place private class declarations at the bottom of the file.\n\n### Code comments\n\n* Err on the side of over-commenting code when the reasoning is not obvious. Comments should explain **WHY** code is written a particular way; the **WHY** is the most important part.\n* Do comment non-obvious implementation details: concurrency hazards, lifecycle constraints, compatibility requirements, platform quirks, upstream workarounds, and intentional deviations from the obvious helper or API.\n* When parsing strings, logs, command output, protocol payloads, or other loosely structured data, include a comment with an example of the raw format being parsed. Show edge cases, escaping rules, delimiters, optional fields, or malformed-but-observed inputs when they affect the parser.\n* When code follows an external standard, protocol, or ecosystem convention, include valid links to the relevant source material so future readers can verify the rule and understand why the code follows it.\n* Do not add comments that simply narrate clear code, such as \"set the timeout\" immediately before assigning a timeout.\n* Keep workaround comments close to the workaround. Include an issue link when the workaround is tied to an upstream bug, and describe the condition for removing it when that is known.\n\nGood comments explain the constraint or tradeoff:\n\n```csharp\n// Read both streams concurrently to avoid deadlock when a pipe buffer fills.\nvar stdoutTask = process.StandardOutput.ReadToEndAsync();\nvar stderrTask = process.StandardError.ReadToEndAsync();\n```\n\n```csharp\n// Endpoint adoption runs on the command path, so fail quickly when stale metadata\n// points at a dead or reused port.\nvar timeout = TimeSpan.FromSeconds(2);\n```\n\n```csharp\n// The temporary config is disposed when this method returns. That is intentional:\n// only `dotnet new install` consumes the config; later template creation uses the\n// already-installed template hive and ambient NuGet configuration.\nusing var temporaryConfig = await TemporaryNuGetConfig.CreateAsync(mappings);\n```\n\n```csharp\n// Workaround for an upstream library bug on Windows where URI SANs are formatted\n// differently than the verifier expects. Cryptographic verification still runs;\n// only the identity checks are performed manually from the certificate extensions.\nvar result = await VerifyWithManualIdentityFallbackAsync(bundle, cancellationToken);\n```\n\n```csharp\npublic required IReadOnlyList<PipelineStep> Steps\n{\n    get;\n    init\n    {\n        field = value;\n        // IMPORTANT: The ResourceNameComparer must be used here to ensure correct lookup behavior\n        // based on resource names, NOT the default reference equality. This is because resources\n        // may be swapped out (referred to as bait-and-switch) during model transformations.\n        StepToResourceMap = field.ToLookup(s => s.Resource, s => s, new ResourceNameComparer());\n    }\n}\n```\n\n```csharp\n// Output sensitive message content for GenAI.\n// A convention for libraries that output GenAI telemetry is to use\n// `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT`.\n// See:\n// - https://opentelemetry.io/blog/2024/otel-generative-ai/\n// - https://github.com/search?q=org%3Aopen-telemetry+OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT&type=code\ncontext.EnvironmentVariables[KnownOtelConfigNames.InstrumentationGenAiCaptureMessageContent] = \"true\";\n```\n\n```csharp\n// If we have multiple endpoints for the same scheme, differentiate them by appending a number.\n// Start numbering with the second endpoint so the first stays just http/https, which preserves\n// the same behavior as \"dotnet run\". Only do this in Run mode because, in Publish mode, those\n// extra endpoints with generic names would not be easily usable.\nvar endpointName = bindingAddress.Scheme;\nif (endpointCountByScheme[bindingAddress.Scheme] > 1)\n{\n    endpointName += endpointCountByScheme[bindingAddress.Scheme];\n}\n```\n\n```csharp\n// The implementation here is less than ideal, but we don't have a clean way of building resource\n// types that change their behavior based on context. In this case, publish mode needs the resource\n// to behave like a ContainerResource instead of a ProjectResource, so we remove the ProjectResource\n// from the application model and add a new ContainerResource in its place.\n//\n// There are still dangling references to the original ProjectResource in the application model, but\n// in publish mode it won't be used. This is a limitation of the current design.\nbuilder.ApplicationBuilder.Resources.Remove(builder.Resource);\n```\n\nParsing comments should show the raw shape and important edge cases:\n\n```csharp\n// Parse resource log lines emitted as:\n//   [2026-05-10T18:34:22.123Z] frontend stdout: Now listening on: http://localhost:5221\n// The message can contain additional ':' characters, so split only on the first\n// \" stdout: \" or \" stderr: \" delimiter after the resource name.\nvar match = s_logLineRegex.Match(line);\n```\n\n```csharp\n// The endpoint metadata sidecar uses the DevTools /json/version shape:\n//   { \"webSocketDebuggerUrl\": \"ws://127.0.0.1:50981/devtools/browser/<id>\" }\n// Older Chromium builds can omit the property while the browser is still starting;\n// treat that as a retryable probe failure rather than invalid metadata.\nvar endpoint = payload.WebSocketDebuggerUrl;\n```\n\nAvoid comments that restate the code:\n\n```csharp\n// Set the timeout to two seconds.\nvar timeout = TimeSpan.FromSeconds(2);\n\n// Create a list.\nvar resources = new List<Resource>();\n```\n\n### Nullable Reference Types\n\n* Declare variables non-nullable, and check for `null` at entry points.\n* Always use `is null` or `is not null` instead of `== null` or `!= null`.\n* Trust the C# null annotations and don't add null checks when the type system says a value cannot be null.\n\n### Building\n\n**Always run restore first to set up the local SDK.** Run `./restore.sh` (Linux/macOS) or `./restore.cmd` (Windows) first to install the local SDK. After restore, you can use standard `dotnet` commands, which will automatically use the local SDK when available due to the paths configuration in global.json.\n\n#### Prerequisites\n1. **Restore First**: Always run `./restore.sh` (Linux/macOS) or `./restore.cmd` (Windows) to set up the local .NET SDK (~30 seconds)\n\n#### Build Commands\n- **Full Build**: `./build.sh` (Linux/macOS) or `./build.cmd` (Windows) - defaults to restore + build (~3-5 minutes)\n- **Build Only**: `./build.sh --build` (assumes restore already done)\n- **Skip Native Build**: Add `/p:SkipNativeBuild=true` to avoid slow native AOT compilation (~1-2 minutes saved)\n- **Clean Build**: `./build.sh --rebuild`\n- **Package Generation**: `./build.sh --pack` to create NuGet packages\n- If you need to disable the terminal logger for `dotnet`/build-related commands, prefer setting `MSBUILDTERMINALLOGGER=false` instead of passing `-tl:false`; avoid `-tl:false` on commands that may invoke tests because it can be forwarded to the test host and fail under Microsoft.Testing.Platform native runner mode\n\n#### Build Troubleshooting\n- If temporarily introducing warnings during refactoring, add `/p:TreatWarningsAsErrors=false` to prevent build failure\n- **Important**: All warnings should be addressed before committing any final changes\n- Template engine warnings about \"Missing generatorVersions\" are expected and not errors\n- If build fails with SDK errors, run `./restore.sh` again to ensure correct .NET 10 RC is installed\n- Build artifacts go to `./artifacts/` directory\n\n#### Visual Studio / VS Code Setup\n- **VS Code**: Run `./build.sh` first, then use `./start-code.sh` to launch with correct environment\n- **Visual Studio**: Run `./build.cmd` first, then use `./startvs.cmd` to launch with local SDK environment\n\n### Start App Hosts in a background job\n\nWhen running an App Host from an interactive console (for example, PowerShell or a terminal session you plan to reuse), start it in a background job/process. If you start the App Host in the foreground and then reuse the console for another command (or stop the current interactive session), the App Host process can be terminated.\n\nRun the App Host in the background so it continues running while you execute other commands:\n\n**PowerShell (Start-Job)**\n\n```powershell\n# From the AppHost project directory\nStart-Job -Name \"AspireAppHost\" -ScriptBlock { dotnet run }\n\n# Inspect output / state\nGet-Job -Name \"AspireAppHost\" | Format-List *\nReceive-Job -Name \"AspireAppHost\" -Keep\n\n# Stop when done\nStop-Job -Name \"AspireAppHost\"\nRemove-Job -Name \"AspireAppHost\"\n```\n\n**bash (background process)**\n\n```bash\n# From the AppHost project directory\ndotnet run > apphost.log 2>&1 &\n\n# Find and stop later\nps aux | grep dotnet\nkill <pid>\n```\n\n### Testing\n\n* We use xUnit SDK v3 with Microsoft.Testing.Platform (https://learn.microsoft.com/dotnet/core/testing/microsoft-testing-platform-intro)\n* Do not emit \"Act\", \"Arrange\" or \"Assert\" comments.\n* We do not use any mocking framework at the moment.\n* Copy existing style in nearby files for test method names and capitalization.\n* Do not leave newly-added tests commented out. All added tests should be building and passing.\n* Do not use Directory.SetCurrentDirectory in tests as it can cause side effects when tests execute concurrently.\n* Prefer using shared test service implementations (e.g., project-level `TestServices/` or `Helpers/` directories, or the cross-project `tests/Shared/` folder) rather than creating private implementation classes within individual test files. Reusing existing test fakes and helpers keeps tests consistent, reduces duplication, and makes maintenance easier. Do not create private test classes when a shared one already exists or can be extended.\n* MTP diagnostic args (hang dump, crash dump, exit code handling) are defined in `eng/Testing.props` via `MtpBaseArgs`. Do not hardcode these args in workflow YAML. See [docs/ci/mtp-args-pipeline.md](docs/ci/mtp-args-pipeline.md) for details.\n* Use `Verify` (snapshot testing) for generated artifacts (files, serialized output, structured text). Prefer `await Verify(value, \"ext\")` over `Assert.Contains` / `Assert.DoesNotContain` / `Assert.Equal` on the same value. Run the test once to generate the `.received.` file, review it, then rename it to `.verified.` to accept it.\n* Avoid `Assert.DoesNotContain` as it is a weak assertion that easily goes out of date — it only proves something is absent without verifying what *is* present. Prefer `Assert.Equal` to check the entire string value, or `Assert.Collection` to verify the complete contents of a collection.\n\n## Running tests\n\n(1) Build from the root with `./build.sh` (~3-5 minutes).\n(2) If that produces errors, fix those errors and build again. Repeat until the build is successful.\n(3) To run tests for a specific project: `dotnet test --project tests/ProjectName.Tests/ProjectName.Tests.csproj --no-build --no-launch-profile -- --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"`\n\nNote that tests for a project can be executed without first building from the root.\n\n(4) To run specific tests, include the filter after `--`:\n```bash\ndotnet test --project tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj --no-launch-profile -- --filter-method \"*.TestingBuilderHasAllPropertiesFromRealBuilder\" --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n```\n\n(5) To apply a timeout for a specific test run use `--hangdump` and `--hangdump-timeout` options after `--`, for example:\n```bash\ndotnet test --project tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj --no-launch-profile -- --filter-method \"*.TestingBuilderHasAllPropertiesFromRealBuilder\" --hangdump --hangdump-timeout 2m\n```\nYou need both options (`--hangdump-timeout` does not work without `--hangdump`). Timeout can be expressed in minutes (e.g. `3m` for 3-minute timeout), or seconds (e.g. `30s` for 30-seconds timeout).\n\n**Important**: Avoid passing `--no-build` unless you have just built in the same session and there have been no code changes since. In automation or while iterating on code, omit `--no-build` so changes are compiled and picked up by the test run.\n\n### CRITICAL: Do NOT use VSTest-style `--filter` with `dotnet test`\n\nThis repo uses **Microsoft.Testing.Platform (MTP)** as the test runner, not VSTest. The classic `--filter` argument (before `--`) uses VSTest filter syntax and **will hang or behave unexpectedly** with MTP.\n\n```bash\n# WRONG - VSTest-style filter, will hang with MTP\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --filter \"FullyQualifiedName~ClassName\"\n\n# CORRECT - MTP-native filters go after the -- separator\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-class \"*.ClassName\"\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-method \"*.MethodName\"\n```\n\nAll test filtering must use MTP-native switches placed **after `--`**. See the filter switches listed below for the full set of options.\n\n### CRITICAL: Excluding Quarantined and Outerloop Tests\n\nWhen running tests in automated environments (including Copilot agent), **always exclude quarantined and outerloop tests** to avoid false negatives and long-running tests:\n\n```bash\n# Correct - excludes quarantined and outerloop tests (use this in automation)\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n\n# For specific test filters, combine with quarantine and outerloop exclusion\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-method \"TestName\" --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n```\n\nNever run all tests without the quarantine and outerloop filters in automated environments, as this will include flaky tests that are known to fail intermittently and long-running tests that slow down CI.\n\nValid test filter switches include: --filter-class, --filter-not-class, --filter-method, --filter-not-method, --filter-namespace, --filter-not-namespace, --filter-not-trait, --filter-trait\nThe switches `--filter-class` and `--filter-method` expect fully qualified names, unless a filter is used as a prefix like `--filter-class \"*.SomeClassName\"` or `--filter-method \"*.SomeMethodName\"`.\nThese switches can be repeated to run tests on multiple classes or methods at once, e.g., `--filter-method \"*.SomeMethodName1\" --filter-method \"*.SomeMethodName2\"`.\n\n### Test Verification Commands\n- **Single Test Project**: Typical runtime ~10-60 seconds per test project\n- **Full Test Suite**: Can take 30+ minutes, use targeted testing instead\n\n## Project Layout and Architecture\n\n### Directory Structure\n- **`/src`**: Main source code for all Aspire packages\n  - `Aspire.Hosting/`: Core hosting and orchestration infrastructure\n  - `Aspire.Dashboard/`: Web dashboard UI (Blazor application)\n  - `Components/`: 40+ integration packages for databases, messaging, cloud services\n  - `Aspire.Cli/`: Command-line interface tools\n- **`/tests`**: Comprehensive test suites mirroring src structure\n- **`/playground`**: Sample applications including TestShop for verification\n- **`/docs`**: Documentation including contributing guides and area ownership\n- **`/eng`**: Build scripts, tools, and engineering infrastructure\n- **`/.github`**: CI/CD workflows, issue templates, and GitHub automation\n- **`/extension`**: VS Code extension source code\n\n### Key Configuration Files\n- **`global.json`**: Pins .NET SDK version - never modify without explicit request\n- **`.editorconfig`**: Code formatting rules, null annotations, diagnostic configurations\n- **`Directory.Build.props`**: Shared MSBuild properties across all projects\n- **`Directory.Packages.props`**: Centralized package version management\n- **`Aspire.slnx`**: Main solution file (XML-based solution format)\n\n### Continuous Integration\n\n#### GitHub Actions (primary, runs on PRs)\n- **`tests.yml`**: Main test workflow running across Windows/Linux/macOS\n- **`tests-quarantine.yml`**: Runs quarantined tests separately every 6 hours\n- **`tests-outerloop.yml`**: Runs outerloop tests separately every 6 hours\n- **`ci.yml`**: Main CI workflow triggered on PRs and pushes to main/release branches\n- **Build validation**: Includes package generation, API compatibility checks, template validation\n- **Workflow matcher maintenance**: When changing CI workflow job or step names that are referenced by automation or tests, update the corresponding workflow helpers, behavior tests, and docs together. For the transient rerun workflow, keep `.github/workflows/auto-rerun-transient-ci-failures.js`, `tests/Infrastructure.Tests/WorkflowScripts/AutoRerunTransientCiFailuresTests.cs`, and `docs/ci/auto-rerun-transient-ci-failures.md` aligned with the live workflow YAML.\n- **⚠️ Quarantine and outerloop tests are easily broken** because they primarily run on schedule, not on most PRs. Changes to `tests-quarantine.yml`, `tests-outerloop.yml`, `specialized-test-runner.yml`, or `run-tests.yml` will automatically trigger the affected workflow(s) on the PR via `paths:` filters. Verify the triggered runs pass before merging.\n\n#### Azure DevOps (secondary, does NOT run tests on PRs)\n- **`eng/pipelines/azure-pipelines-public.yml`**: Weekly scheduled pipeline (Monday midnight UTC) that builds and runs tests on Helix\n- **⚠️ AzDO tests are easily broken** because they don't run on PRs — only weekly or via manual trigger (`/azp run aspire-tests`)\n- Changes to test infrastructure (`eng/Testing.props`, `eng/Testing.targets`, `tests/Directory.Build.*`, `tests/helix/*`) should be validated by triggering a manual AzDO run\n- See [docs/ci/azdo-public-pipeline.md](docs/ci/azdo-public-pipeline.md) for full architecture details including Helix test categories, archive process, and test routing\n\n### Dependencies and Hidden Requirements\n- **Local .NET SDK**: Automatically uses local SDK when available after running restore due to paths configuration in global.json\n- **Package References**: Centrally managed via Directory.Packages.props\n- **API Surface**: Public APIs tracked in `src/*/api/*.cs` files (auto-generated, don't edit)\n\n### Common Validation Steps\n1. **Build Verification**: `./build.sh` should complete without errors\n2. **Package Generation**: `./build.sh --pack` verifies all packages can be created\n3. **Specific Tests**: Target individual test projects related to your changes\n\n## Quarantined tests\n\n- Tests that are flaky and don't fail deterministically are marked with the `QuarantinedTest` attribute.\n- Such tests are not run as part of the regular tests workflow (`tests.yml`).\n    - Instead they are run in the `Quarantine` workflow (`tests-quarantine.yml`).\n- A github issue url is used with the attribute\n- To **reproduce or fix** a flaky/quarantined test, use the `fix-flaky-test` skill (`.agents/skills/fix-flaky-test/SKILL.md`).\n- To **quarantine or unquarantine** a test, use the `test-management` skill (`.agents/skills/test-management/SKILL.md`).\n\nExample: `[QuarantinedTest(\"..issue url..\")]`\n\n### Quarantine/Unquarantine via GitHub Commands (Preferred)\n\nUse these commands in any issue or PR comment. They require write access to the repository.\n\n```bash\n# Quarantine a flaky test (creates a new PR)\n/quarantine-test Namespace.Type.Method https://github.com/microsoft/aspire/issues/1234\n\n# Quarantine multiple tests at once\n/quarantine-test TestMethod1 TestMethod2 https://github.com/microsoft/aspire/issues/1234\n\n# Quarantine and push to an existing PR\n/quarantine-test TestMethod https://github.com/microsoft/aspire/issues/1234 --target-pr https://github.com/microsoft/aspire/pull/5678\n\n# Unquarantine a test (creates a new PR)\n/unquarantine-test Namespace.Type.Method\n\n# Unquarantine and push to an existing PR\n/unquarantine-test TestMethod --target-pr https://github.com/microsoft/aspire/pull/5678\n```\n\nWhen you comment on a PR, the changes are automatically pushed to that PR's branch (no need for `--target-pr`).\n\n### Quarantine/Unquarantine via Local Tool\n\nFor local development, use the QuarantineTools directly:\n\n```bash\n# Quarantine a test\ndotnet run --project tools/QuarantineTools -- -q -i https://github.com/microsoft/aspire/issues/1234 Full.Namespace.Type.Method\n\n# Unquarantine a test\ndotnet run --project tools/QuarantineTools -- -u Full.Namespace.Type.Method\n```\n\n## Disabled tests (ActiveIssue)\n\n- Tests that consistently fail due to a known bug or infrastructure issue are marked with the `ActiveIssue` attribute.\n- These tests are completely skipped until the underlying issue is resolved.\n- Use this for tests that are **blocked**, not for flaky tests (use `QuarantinedTest` for flaky tests).\n\nExample: `[ActiveIssue(\"https://github.com/microsoft/aspire/issues/1234\")]`\n\n### Disable/Enable via GitHub Commands (Preferred)\n\n```bash\n# Disable a test due to an active issue (creates a new PR)\n/disable-test Namespace.Type.Method https://github.com/microsoft/aspire/issues/1234\n\n# Disable and push to an existing PR\n/disable-test TestMethod https://github.com/microsoft/aspire/issues/1234 --target-pr https://github.com/microsoft/aspire/pull/5678\n\n# Enable a previously disabled test (creates a new PR)\n/enable-test Namespace.Type.Method\n\n# Enable and push to an existing PR\n/enable-test TestMethod --target-pr https://github.com/microsoft/aspire/pull/5678\n```\n\n### Disable/Enable via Local Tool\n\n```bash\n# Disable a test with ActiveIssue\ndotnet run --project tools/QuarantineTools -- -q -m activeissue -i https://github.com/microsoft/aspire/issues/1234 Full.Namespace.Type.Method\n\n# Enable a test (remove ActiveIssue)\ndotnet run --project tools/QuarantineTools -- -u -m activeissue Full.Namespace.Type.Method\n```\n\n## Outerloop tests\n\n- Tests that are long-running, resource-intensive, or require special infrastructure are marked with the `OuterloopTest` attribute.\n- In this repository, always use `OuterloopTest` for outerloop coverage; do not replace it with Arcade's `OuterLoop` attribute because our CI scripts and some test projects rely on assembly-level use of the custom trait.\n- Such tests are not run as part of the regular tests workflow (`tests.yml`).\n    - Instead they are run in the `Outerloop` workflow (`tests-outerloop.yml`).\n- An optional reason can be provided with the attribute\n\nExample: `[OuterloopTest(\"Long running integration test\")]`\n\n## Snapshot Testing with Verify\n\n* We use the Verify library (Verify.XunitV3) for snapshot testing in several test projects.\n* Snapshot files are stored in `Snapshots` directories within test projects.\n* When tests that use snapshot testing are updated and generate new output, the snapshots need to be accepted.\n* Use `dotnet verify accept -y` to accept all pending snapshot changes after running tests.\n* The verify tool is available globally as part of the copilot setup.\n\n## Editing resources\n\nThe `*.Designer.cs` files are in the repo, but are intended to match same named `*.resx` files. If you add/remove/change resources in a resx, make the matching changes in the `*.Designer.cs` file that matches that resx. The `*.Designer.cs` files are generated by a Visual Studio design-time tool (`ResXFileCodeGenerator` or `PublicResXFileCodeGenerator`) and there is no command-line tool to regenerate them, so they must be updated manually.\n\nSome projects also have `*.xlf` (XLIFF) translation files in an `xlf` subdirectory next to the `.resx` files. After modifying a `.resx` file, run the following command on the affected project to update the `.xlf` files:\n\n```shell\ndotnet build /t:UpdateXlf <path-to-project.csproj>\n```\n\nDo not manually edit `*.xlf` files. They are updated by the `UpdateXlf` MSBuild target (provided by [Microsoft.DotNet.XliffTasks](https://github.com/dotnet/arcade/tree/main/src/Microsoft.DotNet.XliffTasks)).\n\n## Markdown files\n\n* Markdown files should not have multiple consecutive blank lines.\n* Code blocks should be formatted with triple backticks (```) and include the language identifier for syntax highlighting.\n* JSON code blocks should be indented properly.\n\n## Localization files\n* Files matching the pattern `*/localize/templatestrings.*.json` are localization files. Do not translate their content. It is done by a dedicated workflow.\n## Trust These Instructions\n\nThese instructions are comprehensive and tested. Only search for additional information if:\n1. The instructions appear outdated or incorrect\n2. You encounter specific errors not covered here\n3. You need details about new features not yet documented\n\nFor most development tasks, following these instructions should be sufficient to build, test, and validate changes successfully.\n\n## Typescript\n\n* When possible, you should create Typescript files instead of Javascript files.\n* You must not use dynamic imports unless absolutely necessary. Instead, use static imports.\n\n## Aspire VS Code Extension\n\n* When displaying text to the user, ensure that the strings are localized. New localized strings must be put both in the extension `package.nls.json` and also `src/loc/strings.ts`.\n\n## Available Skills\n\nThe following specialized skills are available in `.agents/skills/`:\n\n- **cli-e2e-testing**: Guide for writing Aspire CLI end-to-end tests using Hex1b terminal automation\n- **ci-test-failures**: Diagnoses GitHub Actions test failures, extracts failed tests from runs, and creates or updates failing-test issues\n- **code-review**: Reviews a GitHub pull request for problems (bugs, security, correctness, convention violations). Use this when asked to review a PR or do a code review.\n- **fix-flaky-test**: Reproduces and fixes flaky/quarantined tests using the CI reproduce workflow (`reproduce-flaky-tests.yml`). Use this when investigating, reproducing, or fixing a flaky or quarantined test.\n- **cli-channel-debugging**: Emulates any Aspire CLI build identity (channel/version/commit/package source) from a locally built CLI via `ASPIRE_CLI_*` env vars or the install sidecar, to reproduce and fix channel/version-specific bugs locally. Use when asked to simulate a daily/staging/stable/PR build or decide which override knobs to set.\n- **dashboard-testing**: Guide for writing tests for the Aspire Dashboard using xUnit and bUnit\n- **test-management**: Quarantines or disables flaky/problematic tests using the QuarantineTools utility\n- **connection-properties**: Expert for creating and improving Connection Properties in Aspire resources\n- **dependency-update**: Guides dependency version updates by checking nuget.org, triggering the dotnet-migrate-package Azure DevOps pipeline, and monitoring runs\n- **api-review**: Reviews .NET API surface area PRs for design guideline violations, applies rules from .NET Framework Design Guidelines and Aspire conventions, and attributes findings to the author who introduced each API\n- **backport-pr**: Triggers the `/backport` bot on a source PR, waits for the bot-created backport PR, and fills in the shiproom template (Customer Impact, Testing, Risk, Regression?). Use when backporting a fix to a release branch.\n- **azdo-internal**: Triggers, monitors, and validates changes to the Aspire internal Azure DevOps pipeline (`microsoft-aspire`, definition 1602) on `dnceng/internal`. Use when asked to trigger an internal/AzDO build, check build status, push to the internal mirror, or validate `eng/` pipeline changes.\n- **startup-perf**: Measures Aspire startup profiling with CLI self-profile capture and dashboard export traces\n- **reviewing-aspire-architecture**: Reviews PRs for Aspire-specific architectural patterns across 15 dimensions including API design, resource model, Azure provisioning, pattern conformance, dashboard UX, CLI behavior, and more. Complements the code-review skill with domain knowledge that generic review cannot catch.\n- **vscode-extension**: Guide for developing, building, testing, and debugging the Aspire VS Code extension under `extension/`. Use when investigating an issue in, debugging, or working on a feature for the VS Code extension.\n- **deprecate-integration**: Soft-sunsets a shipped hosting integration: marks its API `[Obsolete]`, adds a README warning, hides the package from `aspire add`, removes integration-specific automation, suppresses the resulting warnings in first-party consumers, and ships one final obsolete release. Use when deprecating, sunsetting, or retiring an integration.\n\n## Pattern-Based Instructions\n\nAdditional instructions are automatically applied when editing files matching specific patterns:\n\n| Pattern | Instructions File |\n|---------|-------------------|\n| `src/**/*.cs` | `.github/instructions/xmldoc.instructions.md` - XML documentation standards |\n| `src/Aspire.Hosting/**/*.cs` | `.github/instructions/hosting-core.instructions.md` - Hosting core review patterns |\n| `src/Aspire.Hosting.Azure*/**/*.cs` | `.github/instructions/hosting-azure.instructions.md` - Hosting Azure review patterns |\n| `src/Aspire.Dashboard/**/*.{cs,razor,js}` | `.github/instructions/dashboard.instructions.md` - Dashboard review patterns |\n| `src/Components/**/*.cs` | `.github/instructions/components.instructions.md` - Client integration review patterns |\n| `src/Aspire.Hosting*/README.md` | `.github/instructions/hosting-readme.instructions.md` - Hosting integration READMEs |\n| `src/Components/**/README.md` | `.github/instructions/client-readme.instructions.md` - Client integration READMEs |\n| `tools/QuarantineTools/*` | `.github/instructions/quarantine.instructions.md` - QuarantineTools usage |\n| `tests/**/*.cs` | `.github/instructions/test-review-guidelines.instructions.md` - Flaky test patterns and test review guidelines |\n| `eng/scripts/get-aspire-cli*.sh`, `eng/scripts/get-aspire-cli*.ps1` | `.github/instructions/acquisition-tests.instructions.md` - CLI acquisition script tests |\n"},"files":{"AGENTS.md":"# Agent Instructions\n\nInstructions for GitHub Copilot and other AI coding agents working with the Aspire repository.\n\n## Repository Overview\n\n**Aspire** provides tools, templates, and packages for building observable, production-ready distributed applications. At its core is an app model that defines services, resources, and connections in a code-first approach.\n\n### Key Components\n- **Aspire.Hosting**: Application host orchestration and resource management\n- **Aspire.Dashboard**: Web-based dashboard for monitoring and debugging\n- **Service Discovery**: Infrastructure for service-to-service communication\n- **Integrations**: 40+ packages for databases (SQL Server, PostgreSQL, Redis, MongoDB), message queues (RabbitMQ, Kafka), cloud services (Azure), and more\n- **CLI Tools**: Command-line interface for project creation and management\n- **Project Templates**: Starter templates for new Aspire applications\n\n### Technology Stack\n- .NET 10.0\n- C# 13 preview features\n- xUnit SDK v3 with Microsoft.Testing.Platform for testing\n- Microsoft.DotNet.Arcade.Sdk for build infrastructure\n- Native AOT compilation for CLI tools\n- Multi-platform support (Windows, Linux, macOS, containers)\n\n## General\n\n* Make only high confidence suggestions when reviewing code changes.\n* Always use the latest version C#, currently C# 13 features.\n* Never change global.json unless explicitly asked to.\n* Never change package.json or package-lock.json files unless explicitly asked to.\n* Never change NuGet.config files unless explicitly asked to.\n* Do not use cryptographic hashes such as SHA-256 when the hash is not security-related. Prefer `System.IO.Hashing.XxHash3` when you need a stable non-cryptographic hash.\n* When code needs a temporary directory, prefer the repository temp directory abstractions first (for example `IFileSystemService.TempDirectory` / `ITempFileSystemService`) and otherwise use `Directory.CreateTempSubdirectory()` instead of `Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())`; if you need a temporary file path, place it under a securely created temp directory.\n* Don't update files under `*/api/*.cs` (e.g. src/Aspire.Hosting/api/Aspire.Hosting.cs) as they are generated.\n* Do not make new parameters optional just to avoid updating call sites. A parameter should only be optional when it has a sensible semantic default and the API is frequently used (where call-site brevity outweighs explicitness). If a parameter is logically required, make it required and update all call sites.\n\n## Code Review Instructions\n\n### API Files and Public API Surface\n\nThe API files located in `*/api/*.cs` (e.g., `src/Aspire.Hosting/api/Aspire.Hosting.cs`) track the public API surface that has already been shipped in the latest release. These files are auto-generated and serve as a baseline for API compatibility checks.\n\nWhen reviewing pull requests:\n\n* **Do not comment when new public API is introduced and the API files are not regenerated**. This is expected behavior during active development between releases.\n* New public APIs should be reviewed for design, naming, and functionality, but the absence of API file updates during PR development is normal.\n* API files are regenerated as part of the release process when we ship a new version, not during individual PRs.\n* Only flag API file concerns if:\n  - API files are manually edited (they should never be manually modified)\n  - There are breaking changes to existing APIs without proper justification\n  - The PR explicitly claims to update API compatibility but doesn't regenerate the files\n\n### NuGet Feed Configuration\n\nThe NuGet.config file defines approved package sources for the internal build. External package feeds can break the internal build pipeline.\n\nWhen reviewing pull requests:\n\n* **Flag any changes to NuGet.config that add package sources not from these approved domains:**\n  - `https://pkgs.dev.azure.com/dnceng`\n  - `https://dnceng.pkgs.visualstudio.com/public`\n* **Flag any additions of external NuGet feeds** such as:\n  - `https://api.nuget.org/v3/index.json` (nuget.org)\n  - Any other public or third-party package sources\n* If a PR adds an external feed, request that:\n  - The packages be mirrored to an approved internal feed, or\n  - Use existing internal feeds that already mirror public packages (like dotnet-public, dotnet-eng)\n* The wildcard pattern mappings (`<package pattern=\"*\" />`) in dotnet-public and dotnet-eng feeds typically provide access to commonly-used public packages\n\n## Formatting\n\n* Apply code-formatting style defined in `.editorconfig`.\n* Prefer file-scoped namespace declarations and single-line using directives.\n* Insert a newline before the opening curly brace of any code block (e.g., after `if`, `for`, `while`, `foreach`, `using`, `try`, etc.).\n* Ensure that the final return statement of a method is on its own line.\n* Use pattern matching and switch expressions wherever possible.\n* Use `nameof` instead of string literals when referring to member names.\n* Place private class declarations at the bottom of the file.\n\n### Code comments\n\n* Err on the side of over-commenting code when the reasoning is not obvious. Comments should explain **WHY** code is written a particular way; the **WHY** is the most important part.\n* Do comment non-obvious implementation details: concurrency hazards, lifecycle constraints, compatibility requirements, platform quirks, upstream workarounds, and intentional deviations from the obvious helper or API.\n* When parsing strings, logs, command output, protocol payloads, or other loosely structured data, include a comment with an example of the raw format being parsed. Show edge cases, escaping rules, delimiters, optional fields, or malformed-but-observed inputs when they affect the parser.\n* When code follows an external standard, protocol, or ecosystem convention, include valid links to the relevant source material so future readers can verify the rule and understand why the code follows it.\n* Do not add comments that simply narrate clear code, such as \"set the timeout\" immediately before assigning a timeout.\n* Keep workaround comments close to the workaround. Include an issue link when the workaround is tied to an upstream bug, and describe the condition for removing it when that is known.\n\nGood comments explain the constraint or tradeoff:\n\n```csharp\n// Read both streams concurrently to avoid deadlock when a pipe buffer fills.\nvar stdoutTask = process.StandardOutput.ReadToEndAsync();\nvar stderrTask = process.StandardError.ReadToEndAsync();\n```\n\n```csharp\n// Endpoint adoption runs on the command path, so fail quickly when stale metadata\n// points at a dead or reused port.\nvar timeout = TimeSpan.FromSeconds(2);\n```\n\n```csharp\n// The temporary config is disposed when this method returns. That is intentional:\n// only `dotnet new install` consumes the config; later template creation uses the\n// already-installed template hive and ambient NuGet configuration.\nusing var temporaryConfig = await TemporaryNuGetConfig.CreateAsync(mappings);\n```\n\n```csharp\n// Workaround for an upstream library bug on Windows where URI SANs are formatted\n// differently than the verifier expects. Cryptographic verification still runs;\n// only the identity checks are performed manually from the certificate extensions.\nvar result = await VerifyWithManualIdentityFallbackAsync(bundle, cancellationToken);\n```\n\n```csharp\npublic required IReadOnlyList<PipelineStep> Steps\n{\n    get;\n    init\n    {\n        field = value;\n        // IMPORTANT: The ResourceNameComparer must be used here to ensure correct lookup behavior\n        // based on resource names, NOT the default reference equality. This is because resources\n        // may be swapped out (referred to as bait-and-switch) during model transformations.\n        StepToResourceMap = field.ToLookup(s => s.Resource, s => s, new ResourceNameComparer());\n    }\n}\n```\n\n```csharp\n// Output sensitive message content for GenAI.\n// A convention for libraries that output GenAI telemetry is to use\n// `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT`.\n// See:\n// - https://opentelemetry.io/blog/2024/otel-generative-ai/\n// - https://github.com/search?q=org%3Aopen-telemetry+OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT&type=code\ncontext.EnvironmentVariables[KnownOtelConfigNames.InstrumentationGenAiCaptureMessageContent] = \"true\";\n```\n\n```csharp\n// If we have multiple endpoints for the same scheme, differentiate them by appending a number.\n// Start numbering with the second endpoint so the first stays just http/https, which preserves\n// the same behavior as \"dotnet run\". Only do this in Run mode because, in Publish mode, those\n// extra endpoints with generic names would not be easily usable.\nvar endpointName = bindingAddress.Scheme;\nif (endpointCountByScheme[bindingAddress.Scheme] > 1)\n{\n    endpointName += endpointCountByScheme[bindingAddress.Scheme];\n}\n```\n\n```csharp\n// The implementation here is less than ideal, but we don't have a clean way of building resource\n// types that change their behavior based on context. In this case, publish mode needs the resource\n// to behave like a ContainerResource instead of a ProjectResource, so we remove the ProjectResource\n// from the application model and add a new ContainerResource in its place.\n//\n// There are still dangling references to the original ProjectResource in the application model, but\n// in publish mode it won't be used. This is a limitation of the current design.\nbuilder.ApplicationBuilder.Resources.Remove(builder.Resource);\n```\n\nParsing comments should show the raw shape and important edge cases:\n\n```csharp\n// Parse resource log lines emitted as:\n//   [2026-05-10T18:34:22.123Z] frontend stdout: Now listening on: http://localhost:5221\n// The message can contain additional ':' characters, so split only on the first\n// \" stdout: \" or \" stderr: \" delimiter after the resource name.\nvar match = s_logLineRegex.Match(line);\n```\n\n```csharp\n// The endpoint metadata sidecar uses the DevTools /json/version shape:\n//   { \"webSocketDebuggerUrl\": \"ws://127.0.0.1:50981/devtools/browser/<id>\" }\n// Older Chromium builds can omit the property while the browser is still starting;\n// treat that as a retryable probe failure rather than invalid metadata.\nvar endpoint = payload.WebSocketDebuggerUrl;\n```\n\nAvoid comments that restate the code:\n\n```csharp\n// Set the timeout to two seconds.\nvar timeout = TimeSpan.FromSeconds(2);\n\n// Create a list.\nvar resources = new List<Resource>();\n```\n\n### Nullable Reference Types\n\n* Declare variables non-nullable, and check for `null` at entry points.\n* Always use `is null` or `is not null` instead of `== null` or `!= null`.\n* Trust the C# null annotations and don't add null checks when the type system says a value cannot be null.\n\n### Building\n\n**Always run restore first to set up the local SDK.** Run `./restore.sh` (Linux/macOS) or `./restore.cmd` (Windows) first to install the local SDK. After restore, you can use standard `dotnet` commands, which will automatically use the local SDK when available due to the paths configuration in global.json.\n\n#### Prerequisites\n1. **Restore First**: Always run `./restore.sh` (Linux/macOS) or `./restore.cmd` (Windows) to set up the local .NET SDK (~30 seconds)\n\n#### Build Commands\n- **Full Build**: `./build.sh` (Linux/macOS) or `./build.cmd` (Windows) - defaults to restore + build (~3-5 minutes)\n- **Build Only**: `./build.sh --build` (assumes restore already done)\n- **Skip Native Build**: Add `/p:SkipNativeBuild=true` to avoid slow native AOT compilation (~1-2 minutes saved)\n- **Clean Build**: `./build.sh --rebuild`\n- **Package Generation**: `./build.sh --pack` to create NuGet packages\n- If you need to disable the terminal logger for `dotnet`/build-related commands, prefer setting `MSBUILDTERMINALLOGGER=false` instead of passing `-tl:false`; avoid `-tl:false` on commands that may invoke tests because it can be forwarded to the test host and fail under Microsoft.Testing.Platform native runner mode\n\n#### Build Troubleshooting\n- If temporarily introducing warnings during refactoring, add `/p:TreatWarningsAsErrors=false` to prevent build failure\n- **Important**: All warnings should be addressed before committing any final changes\n- Template engine warnings about \"Missing generatorVersions\" are expected and not errors\n- If build fails with SDK errors, run `./restore.sh` again to ensure correct .NET 10 RC is installed\n- Build artifacts go to `./artifacts/` directory\n\n#### Visual Studio / VS Code Setup\n- **VS Code**: Run `./build.sh` first, then use `./start-code.sh` to launch with correct environment\n- **Visual Studio**: Run `./build.cmd` first, then use `./startvs.cmd` to launch with local SDK environment\n\n### Start App Hosts in a background job\n\nWhen running an App Host from an interactive console (for example, PowerShell or a terminal session you plan to reuse), start it in a background job/process. If you start the App Host in the foreground and then reuse the console for another command (or stop the current interactive session), the App Host process can be terminated.\n\nRun the App Host in the background so it continues running while you execute other commands:\n\n**PowerShell (Start-Job)**\n\n```powershell\n# From the AppHost project directory\nStart-Job -Name \"AspireAppHost\" -ScriptBlock { dotnet run }\n\n# Inspect output / state\nGet-Job -Name \"AspireAppHost\" | Format-List *\nReceive-Job -Name \"AspireAppHost\" -Keep\n\n# Stop when done\nStop-Job -Name \"AspireAppHost\"\nRemove-Job -Name \"AspireAppHost\"\n```\n\n**bash (background process)**\n\n```bash\n# From the AppHost project directory\ndotnet run > apphost.log 2>&1 &\n\n# Find and stop later\nps aux | grep dotnet\nkill <pid>\n```\n\n### Testing\n\n* We use xUnit SDK v3 with Microsoft.Testing.Platform (https://learn.microsoft.com/dotnet/core/testing/microsoft-testing-platform-intro)\n* Do not emit \"Act\", \"Arrange\" or \"Assert\" comments.\n* We do not use any mocking framework at the moment.\n* Copy existing style in nearby files for test method names and capitalization.\n* Do not leave newly-added tests commented out. All added tests should be building and passing.\n* Do not use Directory.SetCurrentDirectory in tests as it can cause side effects when tests execute concurrently.\n* Prefer using shared test service implementations (e.g., project-level `TestServices/` or `Helpers/` directories, or the cross-project `tests/Shared/` folder) rather than creating private implementation classes within individual test files. Reusing existing test fakes and helpers keeps tests consistent, reduces duplication, and makes maintenance easier. Do not create private test classes when a shared one already exists or can be extended.\n* MTP diagnostic args (hang dump, crash dump, exit code handling) are defined in `eng/Testing.props` via `MtpBaseArgs`. Do not hardcode these args in workflow YAML. See [docs/ci/mtp-args-pipeline.md](docs/ci/mtp-args-pipeline.md) for details.\n* Use `Verify` (snapshot testing) for generated artifacts (files, serialized output, structured text). Prefer `await Verify(value, \"ext\")` over `Assert.Contains` / `Assert.DoesNotContain` / `Assert.Equal` on the same value. Run the test once to generate the `.received.` file, review it, then rename it to `.verified.` to accept it.\n* Avoid `Assert.DoesNotContain` as it is a weak assertion that easily goes out of date — it only proves something is absent without verifying what *is* present. Prefer `Assert.Equal` to check the entire string value, or `Assert.Collection` to verify the complete contents of a collection.\n\n## Running tests\n\n(1) Build from the root with `./build.sh` (~3-5 minutes).\n(2) If that produces errors, fix those errors and build again. Repeat until the build is successful.\n(3) To run tests for a specific project: `dotnet test --project tests/ProjectName.Tests/ProjectName.Tests.csproj --no-build --no-launch-profile -- --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"`\n\nNote that tests for a project can be executed without first building from the root.\n\n(4) To run specific tests, include the filter after `--`:\n```bash\ndotnet test --project tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj --no-launch-profile -- --filter-method \"*.TestingBuilderHasAllPropertiesFromRealBuilder\" --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n```\n\n(5) To apply a timeout for a specific test run use `--hangdump` and `--hangdump-timeout` options after `--`, for example:\n```bash\ndotnet test --project tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj --no-launch-profile -- --filter-method \"*.TestingBuilderHasAllPropertiesFromRealBuilder\" --hangdump --hangdump-timeout 2m\n```\nYou need both options (`--hangdump-timeout` does not work without `--hangdump`). Timeout can be expressed in minutes (e.g. `3m` for 3-minute timeout), or seconds (e.g. `30s` for 30-seconds timeout).\n\n**Important**: Avoid passing `--no-build` unless you have just built in the same session and there have been no code changes since. In automation or while iterating on code, omit `--no-build` so changes are compiled and picked up by the test run.\n\n### CRITICAL: Do NOT use VSTest-style `--filter` with `dotnet test`\n\nThis repo uses **Microsoft.Testing.Platform (MTP)** as the test runner, not VSTest. The classic `--filter` argument (before `--`) uses VSTest filter syntax and **will hang or behave unexpectedly** with MTP.\n\n```bash\n# WRONG - VSTest-style filter, will hang with MTP\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --filter \"FullyQualifiedName~ClassName\"\n\n# CORRECT - MTP-native filters go after the -- separator\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-class \"*.ClassName\"\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-method \"*.MethodName\"\n```\n\nAll test filtering must use MTP-native switches placed **after `--`**. See the filter switches listed below for the full set of options.\n\n### CRITICAL: Excluding Quarantined and Outerloop Tests\n\nWhen running tests in automated environments (including Copilot agent), **always exclude quarantined and outerloop tests** to avoid false negatives and long-running tests:\n\n```bash\n# Correct - excludes quarantined and outerloop tests (use this in automation)\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n\n# For specific test filters, combine with quarantine and outerloop exclusion\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-method \"TestName\" --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n```\n\nNever run all tests without the quarantine and outerloop filters in automated environments, as this will include flaky tests that are known to fail intermittently and long-running tests that slow down CI.\n\nValid test filter switches include: --filter-class, --filter-not-class, --filter-method, --filter-not-method, --filter-namespace, --filter-not-namespace, --filter-not-trait, --filter-trait\nThe switches `--filter-class` and `--filter-method` expect fully qualified names, unless a filter is used as a prefix like `--filter-class \"*.SomeClassName\"` or `--filter-method \"*.SomeMethodName\"`.\nThese switches can be repeated to run tests on multiple classes or methods at once, e.g., `--filter-method \"*.SomeMethodName1\" --filter-method \"*.SomeMethodName2\"`.\n\n### Test Verification Commands\n- **Single Test Project**: Typical runtime ~10-60 seconds per test project\n- **Full Test Suite**: Can take 30+ minutes, use targeted testing instead\n\n## Project Layout and Architecture\n\n### Directory Structure\n- **`/src`**: Main source code for all Aspire packages\n  - `Aspire.Hosting/`: Core hosting and orchestration infrastructure\n  - `Aspire.Dashboard/`: Web dashboard UI (Blazor application)\n  - `Components/`: 40+ integration packages for databases, messaging, cloud services\n  - `Aspire.Cli/`: Command-line interface tools\n- **`/tests`**: Comprehensive test suites mirroring src structure\n- **`/playground`**: Sample applications including TestShop for verification\n- **`/docs`**: Documentation including contributing guides and area ownership\n- **`/eng`**: Build scripts, tools, and engineering infrastructure\n- **`/.github`**: CI/CD workflows, issue templates, and GitHub automation\n- **`/extension`**: VS Code extension source code\n\n### Key Configuration Files\n- **`global.json`**: Pins .NET SDK version - never modify without explicit request\n- **`.editorconfig`**: Code formatting rules, null annotations, diagnostic configurations\n- **`Directory.Build.props`**: Shared MSBuild properties across all projects\n- **`Directory.Packages.props`**: Centralized package version management\n- **`Aspire.slnx`**: Main solution file (XML-based solution format)\n\n### Continuous Integration\n\n#### GitHub Actions (primary, runs on PRs)\n- **`tests.yml`**: Main test workflow running across Windows/Linux/macOS\n- **`tests-quarantine.yml`**: Runs quarantined tests separately every 6 hours\n- **`tests-outerloop.yml`**: Runs outerloop tests separately every 6 hours\n- **`ci.yml`**: Main CI workflow triggered on PRs and pushes to main/release branches\n- **Build validation**: Includes package generation, API compatibility checks, template validation\n- **Workflow matcher maintenance**: When changing CI workflow job or step names that are referenced by automation or tests, update the corresponding workflow helpers, behavior tests, and docs together. For the transient rerun workflow, keep `.github/workflows/auto-rerun-transient-ci-failures.js`, `tests/Infrastructure.Tests/WorkflowScripts/AutoRerunTransientCiFailuresTests.cs`, and `docs/ci/auto-rerun-transient-ci-failures.md` aligned with the live workflow YAML.\n- **⚠️ Quarantine and outerloop tests are easily broken** because they primarily run on schedule, not on most PRs. Changes to `tests-quarantine.yml`, `tests-outerloop.yml`, `specialized-test-runner.yml`, or `run-tests.yml` will automatically trigger the affected workflow(s) on the PR via `paths:` filters. Verify the triggered runs pass before merging.\n\n#### Azure DevOps (secondary, does NOT run tests on PRs)\n- **`eng/pipelines/azure-pipelines-public.yml`**: Weekly scheduled pipeline (Monday midnight UTC) that builds and runs tests on Helix\n- **⚠️ AzDO tests are easily broken** because they don't run on PRs — only weekly or via manual trigger (`/azp run aspire-tests`)\n- Changes to test infrastructure (`eng/Testing.props`, `eng/Testing.targets`, `tests/Directory.Build.*`, `tests/helix/*`) should be validated by triggering a manual AzDO run\n- See [docs/ci/azdo-public-pipeline.md](docs/ci/azdo-public-pipeline.md) for full architecture details including Helix test categories, archive process, and test routing\n\n### Dependencies and Hidden Requirements\n- **Local .NET SDK**: Automatically uses local SDK when available after running restore due to paths configuration in global.json\n- **Package References**: Centrally managed via Directory.Packages.props\n- **API Surface**: Public APIs tracked in `src/*/api/*.cs` files (auto-generated, don't edit)\n\n### Common Validation Steps\n1. **Build Verification**: `./build.sh` should complete without errors\n2. **Package Generation**: `./build.sh --pack` verifies all packages can be created\n3. **Specific Tests**: Target individual test projects related to your changes\n\n## Quarantined tests\n\n- Tests that are flaky and don't fail deterministically are marked with the `QuarantinedTest` attribute.\n- Such tests are not run as part of the regular tests workflow (`tests.yml`).\n    - Instead they are run in the `Quarantine` workflow (`tests-quarantine.yml`).\n- A github issue url is used with the attribute\n- To **reproduce or fix** a flaky/quarantined test, use the `fix-flaky-test` skill (`.agents/skills/fix-flaky-test/SKILL.md`).\n- To **quarantine or unquarantine** a test, use the `test-management` skill (`.agents/skills/test-management/SKILL.md`).\n\nExample: `[QuarantinedTest(\"..issue url..\")]`\n\n### Quarantine/Unquarantine via GitHub Commands (Preferred)\n\nUse these commands in any issue or PR comment. They require write access to the repository.\n\n```bash\n# Quarantine a flaky test (creates a new PR)\n/quarantine-test Namespace.Type.Method https://github.com/microsoft/aspire/issues/1234\n\n# Quarantine multiple tests at once\n/quarantine-test TestMethod1 TestMethod2 https://github.com/microsoft/aspire/issues/1234\n\n# Quarantine and push to an existing PR\n/quarantine-test TestMethod https://github.com/microsoft/aspire/issues/1234 --target-pr https://github.com/microsoft/aspire/pull/5678\n\n# Unquarantine a test (creates a new PR)\n/unquarantine-test Namespace.Type.Method\n\n# Unquarantine and push to an existing PR\n/unquarantine-test TestMethod --target-pr https://github.com/microsoft/aspire/pull/5678\n```\n\nWhen you comment on a PR, the changes are automatically pushed to that PR's branch (no need for `--target-pr`).\n\n### Quarantine/Unquarantine via Local Tool\n\nFor local development, use the QuarantineTools directly:\n\n```bash\n# Quarantine a test\ndotnet run --project tools/QuarantineTools -- -q -i https://github.com/microsoft/aspire/issues/1234 Full.Namespace.Type.Method\n\n# Unquarantine a test\ndotnet run --project tools/QuarantineTools -- -u Full.Namespace.Type.Method\n```\n\n## Disabled tests (ActiveIssue)\n\n- Tests that consistently fail due to a known bug or infrastructure issue are marked with the `ActiveIssue` attribute.\n- These tests are completely skipped until the underlying issue is resolved.\n- Use this for tests that are **blocked**, not for flaky tests (use `QuarantinedTest` for flaky tests).\n\nExample: `[ActiveIssue(\"https://github.com/microsoft/aspire/issues/1234\")]`\n\n### Disable/Enable via GitHub Commands (Preferred)\n\n```bash\n# Disable a test due to an active issue (creates a new PR)\n/disable-test Namespace.Type.Method https://github.com/microsoft/aspire/issues/1234\n\n# Disable and push to an existing PR\n/disable-test TestMethod https://github.com/microsoft/aspire/issues/1234 --target-pr https://github.com/microsoft/aspire/pull/5678\n\n# Enable a previously disabled test (creates a new PR)\n/enable-test Namespace.Type.Method\n\n# Enable and push to an existing PR\n/enable-test TestMethod --target-pr https://github.com/microsoft/aspire/pull/5678\n```\n\n### Disable/Enable via Local Tool\n\n```bash\n# Disable a test with ActiveIssue\ndotnet run --project tools/QuarantineTools -- -q -m activeissue -i https://github.com/microsoft/aspire/issues/1234 Full.Namespace.Type.Method\n\n# Enable a test (remove ActiveIssue)\ndotnet run --project tools/QuarantineTools -- -u -m activeissue Full.Namespace.Type.Method\n```\n\n## Outerloop tests\n\n- Tests that are long-running, resource-intensive, or require special infrastructure are marked with the `OuterloopTest` attribute.\n- In this repository, always use `OuterloopTest` for outerloop coverage; do not replace it with Arcade's `OuterLoop` attribute because our CI scripts and some test projects rely on assembly-level use of the custom trait.\n- Such tests are not run as part of the regular tests workflow (`tests.yml`).\n    - Instead they are run in the `Outerloop` workflow (`tests-outerloop.yml`).\n- An optional reason can be provided with the attribute\n\nExample: `[OuterloopTest(\"Long running integration test\")]`\n\n## Snapshot Testing with Verify\n\n* We use the Verify library (Verify.XunitV3) for snapshot testing in several test projects.\n* Snapshot files are stored in `Snapshots` directories within test projects.\n* When tests that use snapshot testing are updated and generate new output, the snapshots need to be accepted.\n* Use `dotnet verify accept -y` to accept all pending snapshot changes after running tests.\n* The verify tool is available globally as part of the copilot setup.\n\n## Editing resources\n\nThe `*.Designer.cs` files are in the repo, but are intended to match same named `*.resx` files. If you add/remove/change resources in a resx, make the matching changes in the `*.Designer.cs` file that matches that resx. The `*.Designer.cs` files are generated by a Visual Studio design-time tool (`ResXFileCodeGenerator` or `PublicResXFileCodeGenerator`) and there is no command-line tool to regenerate them, so they must be updated manually.\n\nSome projects also have `*.xlf` (XLIFF) translation files in an `xlf` subdirectory next to the `.resx` files. After modifying a `.resx` file, run the following command on the affected project to update the `.xlf` files:\n\n```shell\ndotnet build /t:UpdateXlf <path-to-project.csproj>\n```\n\nDo not manually edit `*.xlf` files. They are updated by the `UpdateXlf` MSBuild target (provided by [Microsoft.DotNet.XliffTasks](https://github.com/dotnet/arcade/tree/main/src/Microsoft.DotNet.XliffTasks)).\n\n## Markdown files\n\n* Markdown files should not have multiple consecutive blank lines.\n* Code blocks should be formatted with triple backticks (```) and include the language identifier for syntax highlighting.\n* JSON code blocks should be indented properly.\n\n## Localization files\n* Files matching the pattern `*/localize/templatestrings.*.json` are localization files. Do not translate their content. It is done by a dedicated workflow.\n## Trust These Instructions\n\nThese instructions are comprehensive and tested. Only search for additional information if:\n1. The instructions appear outdated or incorrect\n2. You encounter specific errors not covered here\n3. You need details about new features not yet documented\n\nFor most development tasks, following these instructions should be sufficient to build, test, and validate changes successfully.\n\n## Typescript\n\n* When possible, you should create Typescript files instead of Javascript files.\n* You must not use dynamic imports unless absolutely necessary. Instead, use static imports.\n\n## Aspire VS Code Extension\n\n* When displaying text to the user, ensure that the strings are localized. New localized strings must be put both in the extension `package.nls.json` and also `src/loc/strings.ts`.\n\n## Available Skills\n\nThe following specialized skills are available in `.agents/skills/`:\n\n- **cli-e2e-testing**: Guide for writing Aspire CLI end-to-end tests using Hex1b terminal automation\n- **ci-test-failures**: Diagnoses GitHub Actions test failures, extracts failed tests from runs, and creates or updates failing-test issues\n- **code-review**: Reviews a GitHub pull request for problems (bugs, security, correctness, convention violations). Use this when asked to review a PR or do a code review.\n- **fix-flaky-test**: Reproduces and fixes flaky/quarantined tests using the CI reproduce workflow (`reproduce-flaky-tests.yml`). Use this when investigating, reproducing, or fixing a flaky or quarantined test.\n- **cli-channel-debugging**: Emulates any Aspire CLI build identity (channel/version/commit/package source) from a locally built CLI via `ASPIRE_CLI_*` env vars or the install sidecar, to reproduce and fix channel/version-specific bugs locally. Use when asked to simulate a daily/staging/stable/PR build or decide which override knobs to set.\n- **dashboard-testing**: Guide for writing tests for the Aspire Dashboard using xUnit and bUnit\n- **test-management**: Quarantines or disables flaky/problematic tests using the QuarantineTools utility\n- **connection-properties**: Expert for creating and improving Connection Properties in Aspire resources\n- **dependency-update**: Guides dependency version updates by checking nuget.org, triggering the dotnet-migrate-package Azure DevOps pipeline, and monitoring runs\n- **api-review**: Reviews .NET API surface area PRs for design guideline violations, applies rules from .NET Framework Design Guidelines and Aspire conventions, and attributes findings to the author who introduced each API\n- **backport-pr**: Triggers the `/backport` bot on a source PR, waits for the bot-created backport PR, and fills in the shiproom template (Customer Impact, Testing, Risk, Regression?). Use when backporting a fix to a release branch.\n- **azdo-internal**: Triggers, monitors, and validates changes to the Aspire internal Azure DevOps pipeline (`microsoft-aspire`, definition 1602) on `dnceng/internal`. Use when asked to trigger an internal/AzDO build, check build status, push to the internal mirror, or validate `eng/` pipeline changes.\n- **startup-perf**: Measures Aspire startup profiling with CLI self-profile capture and dashboard export traces\n- **reviewing-aspire-architecture**: Reviews PRs for Aspire-specific architectural patterns across 15 dimensions including API design, resource model, Azure provisioning, pattern conformance, dashboard UX, CLI behavior, and more. Complements the code-review skill with domain knowledge that generic review cannot catch.\n- **vscode-extension**: Guide for developing, building, testing, and debugging the Aspire VS Code extension under `extension/`. Use when investigating an issue in, debugging, or working on a feature for the VS Code extension.\n- **deprecate-integration**: Soft-sunsets a shipped hosting integration: marks its API `[Obsolete]`, adds a README warning, hides the package from `aspire add`, removes integration-specific automation, suppresses the resulting warnings in first-party consumers, and ships one final obsolete release. Use when deprecating, sunsetting, or retiring an integration.\n\n## Pattern-Based Instructions\n\nAdditional instructions are automatically applied when editing files matching specific patterns:\n\n| Pattern | Instructions File |\n|---------|-------------------|\n| `src/**/*.cs` | `.github/instructions/xmldoc.instructions.md` - XML documentation standards |\n| `src/Aspire.Hosting/**/*.cs` | `.github/instructions/hosting-core.instructions.md` - Hosting core review patterns |\n| `src/Aspire.Hosting.Azure*/**/*.cs` | `.github/instructions/hosting-azure.instructions.md` - Hosting Azure review patterns |\n| `src/Aspire.Dashboard/**/*.{cs,razor,js}` | `.github/instructions/dashboard.instructions.md` - Dashboard review patterns |\n| `src/Components/**/*.cs` | `.github/instructions/components.instructions.md` - Client integration review patterns |\n| `src/Aspire.Hosting*/README.md` | `.github/instructions/hosting-readme.instructions.md` - Hosting integration READMEs |\n| `src/Components/**/README.md` | `.github/instructions/client-readme.instructions.md` - Client integration READMEs |\n| `tools/QuarantineTools/*` | `.github/instructions/quarantine.instructions.md` - QuarantineTools usage |\n| `tests/**/*.cs` | `.github/instructions/test-review-guidelines.instructions.md` - Flaky test patterns and test review guidelines |\n| `eng/scripts/get-aspire-cli*.sh`, `eng/scripts/get-aspire-cli*.ps1` | `.github/instructions/acquisition-tests.instructions.md` - CLI acquisition script tests |\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# Agent Instructions\n\nInstructions for GitHub Copilot and other AI coding agents working with the Aspire repository.\n\n## Repository Overview\n\n**Aspire** provides tools, templates, and packages for building observable, production-ready distributed applications. At its core is an app model that defines services, resources, and connections in a code-first approach.\n\n### Key Components\n- **Aspire.Hosting**: Application host orchestration and resource management\n- **Aspire.Dashboard**: Web-based dashboard for monitoring and debugging\n- **Service Discovery**: Infrastructure for service-to-service communication\n- **Integrations**: 40+ packages for databases (SQL Server, PostgreSQL, Redis, MongoDB), message queues (RabbitMQ, Kafka), cloud services (Azure), and more\n- **CLI Tools**: Command-line interface for project creation and management\n- **Project Templates**: Starter templates for new Aspire applications\n\n### Technology Stack\n- .NET 10.0\n- C# 13 preview features\n- xUnit SDK v3 with Microsoft.Testing.Platform for testing\n- Microsoft.DotNet.Arcade.Sdk for build infrastructure\n- Native AOT compilation for CLI tools\n- Multi-platform support (Windows, Linux, macOS, containers)\n\n## General\n\n* Make only high confidence suggestions when reviewing code changes.\n* Always use the latest version C#, currently C# 13 features.\n* Never change global.json unless explicitly asked to.\n* Never change package.json or package-lock.json files unless explicitly asked to.\n* Never change NuGet.config files unless explicitly asked to.\n* Do not use cryptographic hashes such as SHA-256 when the hash is not security-related. Prefer `System.IO.Hashing.XxHash3` when you need a stable non-cryptographic hash.\n* When code needs a temporary directory, prefer the repository temp directory abstractions first (for example `IFileSystemService.TempDirectory` / `ITempFileSystemService`) and otherwise use `Directory.CreateTempSubdirectory()` instead of `Path.Combine(Path.GetTempPath(), Path.GetRandomFileName())`; if you need a temporary file path, place it under a securely created temp directory.\n* Don't update files under `*/api/*.cs` (e.g. src/Aspire.Hosting/api/Aspire.Hosting.cs) as they are generated.\n* Do not make new parameters optional just to avoid updating call sites. A parameter should only be optional when it has a sensible semantic default and the API is frequently used (where call-site brevity outweighs explicitness). If a parameter is logically required, make it required and update all call sites.\n\n## Code Review Instructions\n\n### API Files and Public API Surface\n\nThe API files located in `*/api/*.cs` (e.g., `src/Aspire.Hosting/api/Aspire.Hosting.cs`) track the public API surface that has already been shipped in the latest release. These files are auto-generated and serve as a baseline for API compatibility checks.\n\nWhen reviewing pull requests:\n\n* **Do not comment when new public API is introduced and the API files are not regenerated**. This is expected behavior during active development between releases.\n* New public APIs should be reviewed for design, naming, and functionality, but the absence of API file updates during PR development is normal.\n* API files are regenerated as part of the release process when we ship a new version, not during individual PRs.\n* Only flag API file concerns if:\n  - API files are manually edited (they should never be manually modified)\n  - There are breaking changes to existing APIs without proper justification\n  - The PR explicitly claims to update API compatibility but doesn't regenerate the files\n\n### NuGet Feed Configuration\n\nThe NuGet.config file defines approved package sources for the internal build. External package feeds can break the internal build pipeline.\n\nWhen reviewing pull requests:\n\n* **Flag any changes to NuGet.config that add package sources not from these approved domains:**\n  - `https://pkgs.dev.azure.com/dnceng`\n  - `https://dnceng.pkgs.visualstudio.com/public`\n* **Flag any additions of external NuGet feeds** such as:\n  - `https://api.nuget.org/v3/index.json` (nuget.org)\n  - Any other public or third-party package sources\n* If a PR adds an external feed, request that:\n  - The packages be mirrored to an approved internal feed, or\n  - Use existing internal feeds that already mirror public packages (like dotnet-public, dotnet-eng)\n* The wildcard pattern mappings (`<package pattern=\"*\" />`) in dotnet-public and dotnet-eng feeds typically provide access to commonly-used public packages\n\n## Formatting\n\n* Apply code-formatting style defined in `.editorconfig`.\n* Prefer file-scoped namespace declarations and single-line using directives.\n* Insert a newline before the opening curly brace of any code block (e.g., after `if`, `for`, `while`, `foreach`, `using`, `try`, etc.).\n* Ensure that the final return statement of a method is on its own line.\n* Use pattern matching and switch expressions wherever possible.\n* Use `nameof` instead of string literals when referring to member names.\n* Place private class declarations at the bottom of the file.\n\n### Code comments\n\n* Err on the side of over-commenting code when the reasoning is not obvious. Comments should explain **WHY** code is written a particular way; the **WHY** is the most important part.\n* Do comment non-obvious implementation details: concurrency hazards, lifecycle constraints, compatibility requirements, platform quirks, upstream workarounds, and intentional deviations from the obvious helper or API.\n* When parsing strings, logs, command output, protocol payloads, or other loosely structured data, include a comment with an example of the raw format being parsed. Show edge cases, escaping rules, delimiters, optional fields, or malformed-but-observed inputs when they affect the parser.\n* When code follows an external standard, protocol, or ecosystem convention, include valid links to the relevant source material so future readers can verify the rule and understand why the code follows it.\n* Do not add comments that simply narrate clear code, such as \"set the timeout\" immediately before assigning a timeout.\n* Keep workaround comments close to the workaround. Include an issue link when the workaround is tied to an upstream bug, and describe the condition for removing it when that is known.\n\nGood comments explain the constraint or tradeoff:\n\n```csharp\n// Read both streams concurrently to avoid deadlock when a pipe buffer fills.\nvar stdoutTask = process.StandardOutput.ReadToEndAsync();\nvar stderrTask = process.StandardError.ReadToEndAsync();\n```\n\n```csharp\n// Endpoint adoption runs on the command path, so fail quickly when stale metadata\n// points at a dead or reused port.\nvar timeout = TimeSpan.FromSeconds(2);\n```\n\n```csharp\n// The temporary config is disposed when this method returns. That is intentional:\n// only `dotnet new install` consumes the config; later template creation uses the\n// already-installed template hive and ambient NuGet configuration.\nusing var temporaryConfig = await TemporaryNuGetConfig.CreateAsync(mappings);\n```\n\n```csharp\n// Workaround for an upstream library bug on Windows where URI SANs are formatted\n// differently than the verifier expects. Cryptographic verification still runs;\n// only the identity checks are performed manually from the certificate extensions.\nvar result = await VerifyWithManualIdentityFallbackAsync(bundle, cancellationToken);\n```\n\n```csharp\npublic required IReadOnlyList<PipelineStep> Steps\n{\n    get;\n    init\n    {\n        field = value;\n        // IMPORTANT: The ResourceNameComparer must be used here to ensure correct lookup behavior\n        // based on resource names, NOT the default reference equality. This is because resources\n        // may be swapped out (referred to as bait-and-switch) during model transformations.\n        StepToResourceMap = field.ToLookup(s => s.Resource, s => s, new ResourceNameComparer());\n    }\n}\n```\n\n```csharp\n// Output sensitive message content for GenAI.\n// A convention for libraries that output GenAI telemetry is to use\n// `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT`.\n// See:\n// - https://opentelemetry.io/blog/2024/otel-generative-ai/\n// - https://github.com/search?q=org%3Aopen-telemetry+OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT&type=code\ncontext.EnvironmentVariables[KnownOtelConfigNames.InstrumentationGenAiCaptureMessageContent] = \"true\";\n```\n\n```csharp\n// If we have multiple endpoints for the same scheme, differentiate them by appending a number.\n// Start numbering with the second endpoint so the first stays just http/https, which preserves\n// the same behavior as \"dotnet run\". Only do this in Run mode because, in Publish mode, those\n// extra endpoints with generic names would not be easily usable.\nvar endpointName = bindingAddress.Scheme;\nif (endpointCountByScheme[bindingAddress.Scheme] > 1)\n{\n    endpointName += endpointCountByScheme[bindingAddress.Scheme];\n}\n```\n\n```csharp\n// The implementation here is less than ideal, but we don't have a clean way of building resource\n// types that change their behavior based on context. In this case, publish mode needs the resource\n// to behave like a ContainerResource instead of a ProjectResource, so we remove the ProjectResource\n// from the application model and add a new ContainerResource in its place.\n//\n// There are still dangling references to the original ProjectResource in the application model, but\n// in publish mode it won't be used. This is a limitation of the current design.\nbuilder.ApplicationBuilder.Resources.Remove(builder.Resource);\n```\n\nParsing comments should show the raw shape and important edge cases:\n\n```csharp\n// Parse resource log lines emitted as:\n//   [2026-05-10T18:34:22.123Z] frontend stdout: Now listening on: http://localhost:5221\n// The message can contain additional ':' characters, so split only on the first\n// \" stdout: \" or \" stderr: \" delimiter after the resource name.\nvar match = s_logLineRegex.Match(line);\n```\n\n```csharp\n// The endpoint metadata sidecar uses the DevTools /json/version shape:\n//   { \"webSocketDebuggerUrl\": \"ws://127.0.0.1:50981/devtools/browser/<id>\" }\n// Older Chromium builds can omit the property while the browser is still starting;\n// treat that as a retryable probe failure rather than invalid metadata.\nvar endpoint = payload.WebSocketDebuggerUrl;\n```\n\nAvoid comments that restate the code:\n\n```csharp\n// Set the timeout to two seconds.\nvar timeout = TimeSpan.FromSeconds(2);\n\n// Create a list.\nvar resources = new List<Resource>();\n```\n\n### Nullable Reference Types\n\n* Declare variables non-nullable, and check for `null` at entry points.\n* Always use `is null` or `is not null` instead of `== null` or `!= null`.\n* Trust the C# null annotations and don't add null checks when the type system says a value cannot be null.\n\n### Building\n\n**Always run restore first to set up the local SDK.** Run `./restore.sh` (Linux/macOS) or `./restore.cmd` (Windows) first to install the local SDK. After restore, you can use standard `dotnet` commands, which will automatically use the local SDK when available due to the paths configuration in global.json.\n\n#### Prerequisites\n1. **Restore First**: Always run `./restore.sh` (Linux/macOS) or `./restore.cmd` (Windows) to set up the local .NET SDK (~30 seconds)\n\n#### Build Commands\n- **Full Build**: `./build.sh` (Linux/macOS) or `./build.cmd` (Windows) - defaults to restore + build (~3-5 minutes)\n- **Build Only**: `./build.sh --build` (assumes restore already done)\n- **Skip Native Build**: Add `/p:SkipNativeBuild=true` to avoid slow native AOT compilation (~1-2 minutes saved)\n- **Clean Build**: `./build.sh --rebuild`\n- **Package Generation**: `./build.sh --pack` to create NuGet packages\n- If you need to disable the terminal logger for `dotnet`/build-related commands, prefer setting `MSBUILDTERMINALLOGGER=false` instead of passing `-tl:false`; avoid `-tl:false` on commands that may invoke tests because it can be forwarded to the test host and fail under Microsoft.Testing.Platform native runner mode\n\n#### Build Troubleshooting\n- If temporarily introducing warnings during refactoring, add `/p:TreatWarningsAsErrors=false` to prevent build failure\n- **Important**: All warnings should be addressed before committing any final changes\n- Template engine warnings about \"Missing generatorVersions\" are expected and not errors\n- If build fails with SDK errors, run `./restore.sh` again to ensure correct .NET 10 RC is installed\n- Build artifacts go to `./artifacts/` directory\n\n#### Visual Studio / VS Code Setup\n- **VS Code**: Run `./build.sh` first, then use `./start-code.sh` to launch with correct environment\n- **Visual Studio**: Run `./build.cmd` first, then use `./startvs.cmd` to launch with local SDK environment\n\n### Start App Hosts in a background job\n\nWhen running an App Host from an interactive console (for example, PowerShell or a terminal session you plan to reuse), start it in a background job/process. If you start the App Host in the foreground and then reuse the console for another command (or stop the current interactive session), the App Host process can be terminated.\n\nRun the App Host in the background so it continues running while you execute other commands:\n\n**PowerShell (Start-Job)**\n\n```powershell\n# From the AppHost project directory\nStart-Job -Name \"AspireAppHost\" -ScriptBlock { dotnet run }\n\n# Inspect output / state\nGet-Job -Name \"AspireAppHost\" | Format-List *\nReceive-Job -Name \"AspireAppHost\" -Keep\n\n# Stop when done\nStop-Job -Name \"AspireAppHost\"\nRemove-Job -Name \"AspireAppHost\"\n```\n\n**bash (background process)**\n\n```bash\n# From the AppHost project directory\ndotnet run > apphost.log 2>&1 &\n\n# Find and stop later\nps aux | grep dotnet\nkill <pid>\n```\n\n### Testing\n\n* We use xUnit SDK v3 with Microsoft.Testing.Platform (https://learn.microsoft.com/dotnet/core/testing/microsoft-testing-platform-intro)\n* Do not emit \"Act\", \"Arrange\" or \"Assert\" comments.\n* We do not use any mocking framework at the moment.\n* Copy existing style in nearby files for test method names and capitalization.\n* Do not leave newly-added tests commented out. All added tests should be building and passing.\n* Do not use Directory.SetCurrentDirectory in tests as it can cause side effects when tests execute concurrently.\n* Prefer using shared test service implementations (e.g., project-level `TestServices/` or `Helpers/` directories, or the cross-project `tests/Shared/` folder) rather than creating private implementation classes within individual test files. Reusing existing test fakes and helpers keeps tests consistent, reduces duplication, and makes maintenance easier. Do not create private test classes when a shared one already exists or can be extended.\n* MTP diagnostic args (hang dump, crash dump, exit code handling) are defined in `eng/Testing.props` via `MtpBaseArgs`. Do not hardcode these args in workflow YAML. See [docs/ci/mtp-args-pipeline.md](docs/ci/mtp-args-pipeline.md) for details.\n* Use `Verify` (snapshot testing) for generated artifacts (files, serialized output, structured text). Prefer `await Verify(value, \"ext\")` over `Assert.Contains` / `Assert.DoesNotContain` / `Assert.Equal` on the same value. Run the test once to generate the `.received.` file, review it, then rename it to `.verified.` to accept it.\n* Avoid `Assert.DoesNotContain` as it is a weak assertion that easily goes out of date — it only proves something is absent without verifying what *is* present. Prefer `Assert.Equal` to check the entire string value, or `Assert.Collection` to verify the complete contents of a collection.\n\n## Running tests\n\n(1) Build from the root with `./build.sh` (~3-5 minutes).\n(2) If that produces errors, fix those errors and build again. Repeat until the build is successful.\n(3) To run tests for a specific project: `dotnet test --project tests/ProjectName.Tests/ProjectName.Tests.csproj --no-build --no-launch-profile -- --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"`\n\nNote that tests for a project can be executed without first building from the root.\n\n(4) To run specific tests, include the filter after `--`:\n```bash\ndotnet test --project tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj --no-launch-profile -- --filter-method \"*.TestingBuilderHasAllPropertiesFromRealBuilder\" --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n```\n\n(5) To apply a timeout for a specific test run use `--hangdump` and `--hangdump-timeout` options after `--`, for example:\n```bash\ndotnet test --project tests/Aspire.Hosting.Testing.Tests/Aspire.Hosting.Testing.Tests.csproj --no-launch-profile -- --filter-method \"*.TestingBuilderHasAllPropertiesFromRealBuilder\" --hangdump --hangdump-timeout 2m\n```\nYou need both options (`--hangdump-timeout` does not work without `--hangdump`). Timeout can be expressed in minutes (e.g. `3m` for 3-minute timeout), or seconds (e.g. `30s` for 30-seconds timeout).\n\n**Important**: Avoid passing `--no-build` unless you have just built in the same session and there have been no code changes since. In automation or while iterating on code, omit `--no-build` so changes are compiled and picked up by the test run.\n\n### CRITICAL: Do NOT use VSTest-style `--filter` with `dotnet test`\n\nThis repo uses **Microsoft.Testing.Platform (MTP)** as the test runner, not VSTest. The classic `--filter` argument (before `--`) uses VSTest filter syntax and **will hang or behave unexpectedly** with MTP.\n\n```bash\n# WRONG - VSTest-style filter, will hang with MTP\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --filter \"FullyQualifiedName~ClassName\"\n\n# CORRECT - MTP-native filters go after the -- separator\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-class \"*.ClassName\"\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-method \"*.MethodName\"\n```\n\nAll test filtering must use MTP-native switches placed **after `--`**. See the filter switches listed below for the full set of options.\n\n### CRITICAL: Excluding Quarantined and Outerloop Tests\n\nWhen running tests in automated environments (including Copilot agent), **always exclude quarantined and outerloop tests** to avoid false negatives and long-running tests:\n\n```bash\n# Correct - excludes quarantined and outerloop tests (use this in automation)\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n\n# For specific test filters, combine with quarantine and outerloop exclusion\ndotnet test --project tests/Project.Tests/Project.Tests.csproj --no-launch-profile -- --filter-method \"TestName\" --filter-not-trait \"quarantined=true\" --filter-not-trait \"outerloop=true\"\n```\n\nNever run all tests without the quarantine and outerloop filters in automated environments, as this will include flaky tests that are known to fail intermittently and long-running tests that slow down CI.\n\nValid test filter switches include: --filter-class, --filter-not-class, --filter-method, --filter-not-method, --filter-namespace, --filter-not-namespace, --filter-not-trait, --filter-trait\nThe switches `--filter-class` and `--filter-method` expect fully qualified names, unless a filter is used as a prefix like `--filter-class \"*.SomeClassName\"` or `--filter-method \"*.SomeMethodName\"`.\nThese switches can be repeated to run tests on multiple classes or methods at once, e.g., `--filter-method \"*.SomeMethodName1\" --filter-method \"*.SomeMethodName2\"`.\n\n### Test Verification Commands\n- **Single Test Project**: Typical runtime ~10-60 seconds per test project\n- **Full Test Suite**: Can take 30+ minutes, use targeted testing instead\n\n## Project Layout and Architecture\n\n### Directory Structure\n- **`/src`**: Main source code for all Aspire packages\n  - `Aspire.Hosting/`: Core hosting and orchestration infrastructure\n  - `Aspire.Dashboard/`: Web dashboard UI (Blazor application)\n  - `Components/`: 40+ integration packages for databases, messaging, cloud services\n  - `Aspire.Cli/`: Command-line interface tools\n- **`/tests`**: Comprehensive test suites mirroring src structure\n- **`/playground`**: Sample applications including TestShop for verification\n- **`/docs`**: Documentation including contributing guides and area ownership\n- **`/eng`**: Build scripts, tools, and engineering infrastructure\n- **`/.github`**: CI/CD workflows, issue templates, and GitHub automation\n- **`/extension`**: VS Code extension source code\n\n### Key Configuration Files\n- **`global.json`**: Pins .NET SDK version - never modify without explicit request\n- **`.editorconfig`**: Code formatting rules, null annotations, diagnostic configurations\n- **`Directory.Build.props`**: Shared MSBuild properties across all projects\n- **`Directory.Packages.props`**: Centralized package version management\n- **`Aspire.slnx`**: Main solution file (XML-based solution format)\n\n### Continuous Integration\n\n#### GitHub Actions (primary, runs on PRs)\n- **`tests.yml`**: Main test workflow running across Windows/Linux/macOS\n- **`tests-quarantine.yml`**: Runs quarantined tests separately every 6 hours\n- **`tests-outerloop.yml`**: Runs outerloop tests separately every 6 hours\n- **`ci.yml`**: Main CI workflow triggered on PRs and pushes to main/release branches\n- **Build validation**: Includes package generation, API compatibility checks, template validation\n- **Workflow matcher maintenance**: When changing CI workflow job or step names that are referenced by automation or tests, update the corresponding workflow helpers, behavior tests, and docs together. For the transient rerun workflow, keep `.github/workflows/auto-rerun-transient-ci-failures.js`, `tests/Infrastructure.Tests/WorkflowScripts/AutoRerunTransientCiFailuresTests.cs`, and `docs/ci/auto-rerun-transient-ci-failures.md` aligned with the live workflow YAML.\n- **⚠️ Quarantine and outerloop tests are easily broken** because they primarily run on schedule, not on most PRs. Changes to `tests-quarantine.yml`, `tests-outerloop.yml`, `specialized-test-runner.yml`, or `run-tests.yml` will automatically trigger the affected workflow(s) on the PR via `paths:` filters. Verify the triggered runs pass before merging.\n\n#### Azure DevOps (secondary, does NOT run tests on PRs)\n- **`eng/pipelines/azure-pipelines-public.yml`**: Weekly scheduled pipeline (Monday midnight UTC) that builds and runs tests on Helix\n- **⚠️ AzDO tests are easily broken** because they don't run on PRs — only weekly or via manual trigger (`/azp run aspire-tests`)\n- Changes to test infrastructure (`eng/Testing.props`, `eng/Testing.targets`, `tests/Directory.Build.*`, `tests/helix/*`) should be validated by triggering a manual AzDO run\n- See [docs/ci/azdo-public-pipeline.md](docs/ci/azdo-public-pipeline.md) for full architecture details including Helix test categories, archive process, and test routing\n\n### Dependencies and Hidden Requirements\n- **Local .NET SDK**: Automatically uses local SDK when available after running restore due to paths configuration in global.json\n- **Package References**: Centrally managed via Directory.Packages.props\n- **API Surface**: Public APIs tracked in `src/*/api/*.cs` files (auto-generated, don't edit)\n\n### Common Validation Steps\n1. **Build Verification**: `./build.sh` should complete without errors\n2. **Package Generation**: `./build.sh --pack` verifies all packages can be created\n3. **Specific Tests**: Target individual test projects related to your changes\n\n## Quarantined tests\n\n- Tests that are flaky and don't fail deterministically are marked with the `QuarantinedTest` attribute.\n- Such tests are not run as part of the regular tests workflow (`tests.yml`).\n    - Instead they are run in the `Quarantine` workflow (`tests-quarantine.yml`).\n- A github issue url is used with the attribute\n- To **reproduce or fix** a flaky/quarantined test, use the `fix-flaky-test` skill (`.agents/skills/fix-flaky-test/SKILL.md`).\n- To **quarantine or unquarantine** a test, use the `test-management` skill (`.agents/skills/test-management/SKILL.md`).\n\nExample: `[QuarantinedTest(\"..issue url..\")]`\n\n### Quarantine/Unquarantine via GitHub Commands (Preferred)\n\nUse these commands in any issue or PR comment. They require write access to the repository.\n\n```bash\n# Quarantine a flaky test (creates a new PR)\n/quarantine-test Namespace.Type.Method https://github.com/microsoft/aspire/issues/1234\n\n# Quarantine multiple tests at once\n/quarantine-test TestMethod1 TestMethod2 https://github.com/microsoft/aspire/issues/1234\n\n# Quarantine and push to an existing PR\n/quarantine-test TestMethod https://github.com/microsoft/aspire/issues/1234 --target-pr https://github.com/microsoft/aspire/pull/5678\n\n# Unquarantine a test (creates a new PR)\n/unquarantine-test Namespace.Type.Method\n\n# Unquarantine and push to an existing PR\n/unquarantine-test TestMethod --target-pr https://github.com/microsoft/aspire/pull/5678\n```\n\nWhen you comment on a PR, the changes are automatically pushed to that PR's branch (no need for `--target-pr`).\n\n### Quarantine/Unquarantine via Local Tool\n\nFor local development, use the QuarantineTools directly:\n\n```bash\n# Quarantine a test\ndotnet run --project tools/QuarantineTools -- -q -i https://github.com/microsoft/aspire/issues/1234 Full.Namespace.Type.Method\n\n# Unquarantine a test\ndotnet run --project tools/QuarantineTools -- -u Full.Namespace.Type.Method\n```\n\n## Disabled tests (ActiveIssue)\n\n- Tests that consistently fail due to a known bug or infrastructure issue are marked with the `ActiveIssue` attribute.\n- These tests are completely skipped until the underlying issue is resolved.\n- Use this for tests that are **blocked**, not for flaky tests (use `QuarantinedTest` for flaky tests).\n\nExample: `[ActiveIssue(\"https://github.com/microsoft/aspire/issues/1234\")]`\n\n### Disable/Enable via GitHub Commands (Preferred)\n\n```bash\n# Disable a test due to an active issue (creates a new PR)\n/disable-test Namespace.Type.Method https://github.com/microsoft/aspire/issues/1234\n\n# Disable and push to an existing PR\n/disable-test TestMethod https://github.com/microsoft/aspire/issues/1234 --target-pr https://github.com/microsoft/aspire/pull/5678\n\n# Enable a previously disabled test (creates a new PR)\n/enable-test Namespace.Type.Method\n\n# Enable and push to an existing PR\n/enable-test TestMethod --target-pr https://github.com/microsoft/aspire/pull/5678\n```\n\n### Disable/Enable via Local Tool\n\n```bash\n# Disable a test with ActiveIssue\ndotnet run --project tools/QuarantineTools -- -q -m activeissue -i https://github.com/microsoft/aspire/issues/1234 Full.Namespace.Type.Method\n\n# Enable a test (remove ActiveIssue)\ndotnet run --project tools/QuarantineTools -- -u -m activeissue Full.Namespace.Type.Method\n```\n\n## Outerloop tests\n\n- Tests that are long-running, resource-intensive, or require special infrastructure are marked with the `OuterloopTest` attribute.\n- In this repository, always use `OuterloopTest` for outerloop coverage; do not replace it with Arcade's `OuterLoop` attribute because our CI scripts and some test projects rely on assembly-level use of the custom trait.\n- Such tests are not run as part of the regular tests workflow (`tests.yml`).\n    - Instead they are run in the `Outerloop` workflow (`tests-outerloop.yml`).\n- An optional reason can be provided with the attribute\n\nExample: `[OuterloopTest(\"Long running integration test\")]`\n\n## Snapshot Testing with Verify\n\n* We use the Verify library (Verify.XunitV3) for snapshot testing in several test projects.\n* Snapshot files are stored in `Snapshots` directories within test projects.\n* When tests that use snapshot testing are updated and generate new output, the snapshots need to be accepted.\n* Use `dotnet verify accept -y` to accept all pending snapshot changes after running tests.\n* The verify tool is available globally as part of the copilot setup.\n\n## Editing resources\n\nThe `*.Designer.cs` files are in the repo, but are intended to match same named `*.resx` files. If you add/remove/change resources in a resx, make the matching changes in the `*.Designer.cs` file that matches that resx. The `*.Designer.cs` files are generated by a Visual Studio design-time tool (`ResXFileCodeGenerator` or `PublicResXFileCodeGenerator`) and there is no command-line tool to regenerate them, so they must be updated manually.\n\nSome projects also have `*.xlf` (XLIFF) translation files in an `xlf` subdirectory next to the `.resx` files. After modifying a `.resx` file, run the following command on the affected project to update the `.xlf` files:\n\n```shell\ndotnet build /t:UpdateXlf <path-to-project.csproj>\n```\n\nDo not manually edit `*.xlf` files. They are updated by the `UpdateXlf` MSBuild target (provided by [Microsoft.DotNet.XliffTasks](https://github.com/dotnet/arcade/tree/main/src/Microsoft.DotNet.XliffTasks)).\n\n## Markdown files\n\n* Markdown files should not have multiple consecutive blank lines.\n* Code blocks should be formatted with triple backticks (```) and include the language identifier for syntax highlighting.\n* JSON code blocks should be indented properly.\n\n## Localization files\n* Files matching the pattern `*/localize/templatestrings.*.json` are localization files. Do not translate their content. It is done by a dedicated workflow.\n## Trust These Instructions\n\nThese instructions are comprehensive and tested. Only search for additional information if:\n1. The instructions appear outdated or incorrect\n2. You encounter specific errors not covered here\n3. You need details about new features not yet documented\n\nFor most development tasks, following these instructions should be sufficient to build, test, and validate changes successfully.\n\n## Typescript\n\n* When possible, you should create Typescript files instead of Javascript files.\n* You must not use dynamic imports unless absolutely necessary. Instead, use static imports.\n\n## Aspire VS Code Extension\n\n* When displaying text to the user, ensure that the strings are localized. New localized strings must be put both in the extension `package.nls.json` and also `src/loc/strings.ts`.\n\n## Available Skills\n\nThe following specialized skills are available in `.agents/skills/`:\n\n- **cli-e2e-testing**: Guide for writing Aspire CLI end-to-end tests using Hex1b terminal automation\n- **ci-test-failures**: Diagnoses GitHub Actions test failures, extracts failed tests from runs, and creates or updates failing-test issues\n- **code-review**: Reviews a GitHub pull request for problems (bugs, security, correctness, convention violations). Use this when asked to review a PR or do a code review.\n- **fix-flaky-test**: Reproduces and fixes flaky/quarantined tests using the CI reproduce workflow (`reproduce-flaky-tests.yml`). Use this when investigating, reproducing, or fixing a flaky or quarantined test.\n- **cli-channel-debugging**: Emulates any Aspire CLI build identity (channel/version/commit/package source) from a locally built CLI via `ASPIRE_CLI_*` env vars or the install sidecar, to reproduce and fix channel/version-specific bugs locally. Use when asked to simulate a daily/staging/stable/PR build or decide which override knobs to set.\n- **dashboard-testing**: Guide for writing tests for the Aspire Dashboard using xUnit and bUnit\n- **test-management**: Quarantines or disables flaky/problematic tests using the QuarantineTools utility\n- **connection-properties**: Expert for creating and improving Connection Properties in Aspire resources\n- **dependency-update**: Guides dependency version updates by checking nuget.org, triggering the dotnet-migrate-package Azure DevOps pipeline, and monitoring runs\n- **api-review**: Reviews .NET API surface area PRs for design guideline violations, applies rules from .NET Framework Design Guidelines and Aspire conventions, and attributes findings to the author who introduced each API\n- **backport-pr**: Triggers the `/backport` bot on a source PR, waits for the bot-created backport PR, and fills in the shiproom template (Customer Impact, Testing, Risk, Regression?). Use when backporting a fix to a release branch.\n- **azdo-internal**: Triggers, monitors, and validates changes to the Aspire internal Azure DevOps pipeline (`microsoft-aspire`, definition 1602) on `dnceng/internal`. Use when asked to trigger an internal/AzDO build, check build status, push to the internal mirror, or validate `eng/` pipeline changes.\n- **startup-perf**: Measures Aspire startup profiling with CLI self-profile capture and dashboard export traces\n- **reviewing-aspire-architecture**: Reviews PRs for Aspire-specific architectural patterns across 15 dimensions including API design, resource model, Azure provisioning, pattern conformance, dashboard UX, CLI behavior, and more. Complements the code-review skill with domain knowledge that generic review cannot catch.\n- **vscode-extension**: Guide for developing, building, testing, and debugging the Aspire VS Code extension under `extension/`. Use when investigating an issue in, debugging, or working on a feature for the VS Code extension.\n- **deprecate-integration**: Soft-sunsets a shipped hosting integration: marks its API `[Obsolete]`, adds a README warning, hides the package from `aspire add`, removes integration-specific automation, suppresses the resulting warnings in first-party consumers, and ships one final obsolete release. Use when deprecating, sunsetting, or retiring an integration.\n\n## Pattern-Based Instructions\n\nAdditional instructions are automatically applied when editing files matching specific patterns:\n\n| Pattern | Instructions File |\n|---------|-------------------|\n| `src/**/*.cs` | `.github/instructions/xmldoc.instructions.md` - XML documentation standards |\n| `src/Aspire.Hosting/**/*.cs` | `.github/instructions/hosting-core.instructions.md` - Hosting core review patterns |\n| `src/Aspire.Hosting.Azure*/**/*.cs` | `.github/instructions/hosting-azure.instructions.md` - Hosting Azure review patterns |\n| `src/Aspire.Dashboard/**/*.{cs,razor,js}` | `.github/instructions/dashboard.instructions.md` - Dashboard review patterns |\n| `src/Components/**/*.cs` | `.github/instructions/components.instructions.md` - Client integration review patterns |\n| `src/Aspire.Hosting*/README.md` | `.github/instructions/hosting-readme.instructions.md` - Hosting integration READMEs |\n| `src/Components/**/README.md` | `.github/instructions/client-readme.instructions.md` - Client integration READMEs |\n| `tools/QuarantineTools/*` | `.github/instructions/quarantine.instructions.md` - QuarantineTools usage |\n| `tests/**/*.cs` | `.github/instructions/test-review-guidelines.instructions.md` - Flaky test patterns and test review guidelines |\n| `eng/scripts/get-aspire-cli*.sh`, `eng/scripts/get-aspire-cli*.ps1` | `.github/instructions/acquisition-tests.instructions.md` - CLI acquisition script tests |\n","category":"root","tokens":8708}]}