


Change a Large .NET Codebase While Keeping It Fast and Compatible
Use when editing a large, performance-critical .NET repository such as a widely used build engine. It keeps hot paths free of extra allocations, treats any new warning as a breaking change, builds from the smallest project up, and reports which builds, tests, and samples were run.
To use this AI rule
## Put Hot-Path Speed and Compatibility First in Every Change
Treat the repository as performance-critical infrastructure whose behavior may affect many downstream builds.
- Make runtime efficiency the first engineering priority in hot paths. Minimize allocations, avoid avoidable abstraction overhead, and choose algorithms that remain efficient at scale.
- Preserve compatibility unless a change is explicitly opt-in. A new warning, error, or behavior change can break consumers when warnings are promoted to errors.
- Keep the change focused. Match surrounding architecture and style, but use current language features when substantial new code justifies modernization.
- Do not introduce compiler or analyzer warnings. Assume official builds treat every warning as an error.
- Prefer evidence from the repository's own build, bootstrap output, samples, and tests over assumptions.
## Write C# in the Repository's Style with Fewer Allocations When Parsing
Apply the repository's formatter and `.editorconfig` before inventing local style rules.
- Prefer current C# syntax supported by the pinned SDK, including collection expressions where they improve clarity.
- Use file-scoped namespaces and compact using directives when consistent with the codebase.
- Follow the repository's brace style and use `nameof` for member references.
- Use pattern matching and switch expressions when they make conditions clearer without adding overhead.
- In allocation-sensitive parsing, prefer `Span<T>`, `ReadOnlySpan<T>`, slicing, and span-based `TryParse` APIs.
- Use invariant character operations for single-character normalization and the repository's domain comparer for domain identifiers. Use ordinal comparison for ordinary non-domain identifiers.
- Consider aggressive inlining only for small, measured hot-path helpers.
Handle nullable reference types according to the file's established mode:
- New files use nullable reference types and must not disable nullable analysis.
- Files that explicitly disable nullable analysis retain that style; do not add isolated nullable annotations.
- Files with nullable analysis enabled use accurate annotations and explicit null handling.
- Prefer pattern-based null checks such as `is null` and `is not null`.
Choose immutable collections by update pattern. Use compact array-backed immutable collections or frozen lookups for data built once and read many times. Use persistent immutable lists or dictionaries only when incremental updates are a real requirement. Do not use query pipelines in hot paths when a direct loop avoids allocations.
## Review Changes for Hot-Path Cost and New Warnings
Review changes as if they will run inside a widely used build engine.
1. Identify the execution frequency and data volume of every changed path.
2. Flag unnecessary allocations, repeated enumeration, query operators, avoidable string creation, and inefficient lookup structures in hot paths.
3. Check that parsing uses spans where practical and that comparison semantics match the domain.
4. Confirm that collection types fit their construction and access pattern.
5. Look for new diagnostics, changed defaults, reordered evaluation, altered command behavior, or other externally visible differences.
6. Treat any new warning or error in existing behavior as a breaking change, even if the diagnostic appears helpful.
7. Permit stronger diagnostics in new opt-in behavior, where users intentionally select the new contract.
Inspect package-source configuration changes carefully. New external sources require explicit justification, and approved internal sources should be preferred when the repository defines them. Do not change pinned SDK, package-source, shared build-property, or central package-version files unless the requested work requires it.
Never edit generated build output or the repository-managed local SDK directory. Update nearby technical documentation when behavior, public APIs, commands, or troubleshooting guidance changes.
## Build the Smallest Project First and Fix the Earliest Errors
Start with the smallest build that can prove the changed component, then expand only as required by the repository's completion contract.
- Build an individual project with the repository's standard quiet build command when the change is localized.
- Use the platform-specific whole-repository build script for integration verification. Honor its documented timeout; do not cancel a known long-running build merely because it is quiet.
- Do not pipe build output into a file. When a durable error list is needed, use the build system's native file-logger option so console behavior and exit status remain trustworthy.
- When reviewing a subset of build failures, begin with the earliest errors. Later failures are often consequences.
- If the build cannot resolve the pinned SDK, activate the repository's bootstrap environment and verify that the expected SDK version is active.
- After a successful whole-repository build, use the generated bootstrap executable or environment for downstream validation.
- Use repository sample projects instead of unrelated external projects for end-to-end checks.
Keep build artifacts in the repository-defined artifact directory. Do not hand-edit generated files to make a build appear successful.
## Test the Change and Run the Newly Built Command Before Finishing
Use a verification sequence that proves both the changed behavior and the build engine produced by the repository.
1. Run the relevant unit-test project and, when useful, a focused test filter for the changed scenario.
2. Run the full test suite only when the repository contract or change scope requires it. Respect documented runtimes and never cancel a healthy long-running suite early.
3. Build a representative repository sample through the bootstrap environment.
4. Invoke the newly built command-line entry point with a harmless command such as help output.
5. Confirm the full build completed without warnings or errors.
6. Re-read the diff for generated-file edits, unrequested configuration changes, compatibility risks, and missing documentation.
Completion requires evidence, not only a successful compilation. Record which build, focused tests, sample, and executable check were run, and clearly state any verification that could not be performed. Do not claim full validation when only a component-level check was completed.
