Project: ManagedCode.Storage Stack: .NET 10 / C# / xUnit / VSTest / Coverlet / GitHub Pages docs
Follows MCAF
This file defines how AI agents work in this solution.
- Root
AGENTS.mdholds the global workflow, shared commands, cross-cutting rules, maintainability limits, and global skill catalog. - Every
.csprojroot in this multi-project solution keeps a localAGENTS.mdwith project-specific entry points, boundaries, commands, risks, and applicable skills. - Local
AGENTS.mdfiles may tighten root rules, but they must not weaken them silently.
- Solution root:
ManagedCode.Storage.slnx - Projects or modules with local
AGENTS.mdfiles:ManagedCode.Storage.Core/ManagedCode.Storage.TestFakes/ManagedCode.Storage.VirtualFileSystem/Integraions/ManagedCode.Storage.Client/Integraions/ManagedCode.Storage.Client.SignalR/Integraions/ManagedCode.Storage.Orleans/Integraions/ManagedCode.Storage.Server/Storages/ManagedCode.Storage.Aws/Storages/ManagedCode.Storage.Azure/Storages/ManagedCode.Storage.Azure.DataLake/Storages/ManagedCode.Storage.CloudKit/Storages/ManagedCode.Storage.Dropbox/Storages/ManagedCode.Storage.FileSystem/Storages/ManagedCode.Storage.Google/Storages/ManagedCode.Storage.GoogleDrive/Storages/ManagedCode.Storage.OneDrive/Storages/ManagedCode.Storage.Sftp/Tests/ManagedCode.Storage.Tests/
- Read the solution-root
AGENTS.mdfirst. - Read the nearest local
AGENTS.mdfor the area you will edit. - Apply the stricter rule when both files speak to the same topic.
- Local
AGENTS.mdfiles may refine or tighten root rules, but they must not silently weaken them. - If a local rule needs an exception, document it explicitly in the nearest local
AGENTS.md, ADR, or feature doc.
Learn the user's stable habits, preferences, and corrections. Record durable rules here instead of relying on chat history.
Before doing any non-trivial task, evaluate the latest user message.
If it contains a durable rule, correction, preference, or workflow change, update AGENTS.md first.
If it is only task-local scope, do not turn it into a lasting rule.
Update this file when the user gives:
- a repeated correction
- a permanent requirement
- a lasting preference
- a workflow change
- a high-signal frustration that indicates a rule was missed
Extract rules aggressively when the user says things equivalent to:
- "never", "don't", "stop", "avoid"
- "always", "must", "make sure", "should"
- "remember", "keep in mind", "note that"
- "from now on", "going forward"
- "the workflow is", "we do it like this"
Preferences belong in ## Preferences:
- positive preferences go under
Likes - negative preferences go under
Dislikes - comparisons should become explicit rules or preferences
Corrections should update an existing rule when possible instead of creating duplicates.
Treat these as strong signals and record them immediately:
- anger, swearing, sarcasm, or explicit frustration
- ALL CAPS, repeated punctuation, or "don't do this again"
- the same mistake happening twice
- the user manually undoing or rejecting a recurring pattern
Do not record:
- one-off instructions for the current task
- temporary exceptions
- requirements that are already captured elsewhere without change
Rule format:
- one instruction per bullet
- place it in the right section
- capture the why, not only the literal wording
- remove obsolete rules when a better one replaces them
List only the skills this solution actually uses.
mcaf-solution-governance— use when bootstrapping or refining root and localAGENTS.md, maintainability limits, rule precedence, or solution topology.mcaf-architecture-overview— use when creating or updatingdocs/Architecture.mdafter module, boundary, or contract changes.mcaf-documentation— use for durable docs, docs-site synchronization, Mermaid-heavy docs updates, and repo documentation structure changes.mcaf-adr-writing— use when documenting cross-cutting architectural or standards decisions indocs/ADR/.mcaf-feature-spec— use when documenting non-trivial feature behavior indocs/Features/.mcaf-dotnet— entry skill for .NET work and routing to specialized.NETskills.mcaf-dotnet-analyzer-config— use when the repo-root.editorconfigor analyzer severity ownership changes.mcaf-dotnet-code-analysis— use when SDK analyzer policy inDirectory.Build.propsor project files changes.mcaf-dotnet-features— use when modern C# or .NET 10 feature choices matter.mcaf-testing— use for scenario coverage planning and verification strategy.mcaf-dotnet-netarchtest— use when architecture dependency rules inTests/ManagedCode.Storage.Tests/Architecture/change.mcaf-dotnet-xunit— use for xUnit tests inTests/ManagedCode.Storage.Tests/.mcaf-dotnet-quality-ci— use for the repo quality pass and CI-aligned verification.mcaf-dotnet-complexity— use when work risks breaching file, type, function, or nesting limits.mcaf-dotnet-coverlet— use when coverage commands, thresholds, or coverage tooling change.mcaf-dotnet-format— use when formatter or analyzer command wiring changes.mcaf-solid-maintainability— use when reshaping responsibilities or SOLID boundaries.mcaf-ci-cd— use for GitHub Actions, branch protection, andbuild-and-testworkflow changes.
If the stack is .NET, follow these skill-management rules explicitly:
mcaf-dotnetis the entry skill and routes to specialized.NETskills.- Keep exactly one framework skill: this repo uses
mcaf-dotnet-xunit. - Add tool-specific
.NETskills only when the repository actually uses those tools in CI or local verification. - Keep only
mcaf-*skills in repository-local agent skill directories. - When upgrading skills, recheck
restore,build,test,format, andcoveragecommands against the repo toolchain.
restore:dotnet restore ManagedCode.Storage.slnxbuild:dotnet build ManagedCode.Storage.slnxtest:dotnet test Tests/ManagedCode.Storage.Tests/ManagedCode.Storage.Tests.csproj --configuration Releasecoverage:dotnet test Tests/ManagedCode.Storage.Tests/ManagedCode.Storage.Tests.csproj --configuration Release /p:CollectCoverage=true /p:CoverletOutput=coverage /p:CoverletOutputFormat=opencoverformat:dotnet format ManagedCode.Storage.slnx
Toolchain notes:
- Tests run on
xUnitoverVSTestviaMicrosoft.NET.Test.Sdkandxunit.runner.visualstudio. formatintentionally applies fixes instead of running in verify-only mode.- CI verifies formatting with
dotnet format ManagedCode.Storage.slnx --verify-no-changes. coverageusescoverlet.msbuildthroughdotnet testMSBuild properties.- Architecture dependency rules use
NetArchTest.RulesinsideTests/ManagedCode.Storage.Tests/Architecture/and run through the normaltestcommand. - Explicit
LangVersionshould only be introduced if a project intentionally differs from the SDK default.
- Multi-project solutions MUST keep one root
AGENTS.mdplus one localAGENTS.mdin each project root. - Each local
AGENTS.mdMUST document:- project purpose
- entry points
- boundaries
- local commands
- applicable skills
- local risks or protected areas
- Keep provider and integration local files focused on public DI extensions, public contracts, and boundary-specific risks.
- If a project grows enough that the root file becomes vague, add or tighten the local
AGENTS.mdbefore continuing implementation.
file_max_loc:400type_max_loc:200function_max_loc:50max_nesting_depth:3exception_policy:Document any justified exception in the nearest ADR, feature doc, or local AGENTS.md with the reason, scope, and removal or refactor plan.
- Read the assignment, inspect code and docs, and define scope before planning.
- Start from
docs/Architecture.mdand the nearest localAGENTS.md. - Treat
docs/Architecture.mdas the architecture map for every non-trivial task. - If the architecture map is missing, stale, or diagram-free, update it before implementation.
- Define scope before coding:
- in scope
- out of scope
- For non-trivial work, create a root-level
<slug>.plan.mdfile before making code or doc changes. - Keep the plan file current until the task is complete; it must track ordered steps, risks, baseline failures, verification steps, and done criteria.
- Write a multi-step plan before implementation.
- Implement code and tests together.
- Run verification in layers:
- changed tests
- related suite
- broader regressions
- After all required tests pass, run
format, thenbuild. - Summarize changes, risks, and test results before marking the task complete.
- Always run required builds and tests yourself; do not ask the user to execute them.
- Docs live in
docs/andREADME.md. docs/Architecture.mdis the required global map and the first stop for agents.- Keep a GitHub Pages docs site in sync with
docs/, usingDOCS-EXAMPLE/as the reference template for structure and CI or pipeline behavior. - Keep
docs/templates/ADR-Template.mdanddocs/templates/Feature-Template.mdaligned with the current MCAF references. - When adding new docs pages under
docs/Features/,docs/ADR/, ordocs/API/, also update the correspondingindex.mdso the page is discoverable in the docs catalog and navigation. - Docs site navigation must not include a
Templatespage. - When referencing repo file paths in docs, make them clickable with the corresponding GitHub
blobortreeURL. - Update docs when behavior changes.
- Update configuration examples when required.
- Documentation must include clear schemas or diagrams, preferably Mermaid, for every non-trivial feature and integration.
- When adding new projects or providers, ensure
README.mdclearly documents installation, DI wiring, and basic usage examples. - Where feasible, prefer provider options that can build vendor SDK clients from credentials while still allowing client injection for advanced scenarios.
- Avoid ownership flags like
ownsClient; prefer a clear wrapper or factory boundary so lifetime and disposal rules stay predictable. - For providers that rely on vendor SDK clients, document how to obtain credentials, keys, or tokens and include a minimal code snippet that builds the required SDK client instance.
- CloudKit docs must explicitly clarify that
ContainerIdis a CloudKit container identifier, not a secret, and document the optionalHttpClientandICloudKitClientinjection points. - Credentials docs should keep provider sections consistent: What you need, Typical steps, Minimal SDK or DI snippet, Suggested configuration keys.
- Keep the testing strategy discoverable from
docs/Development/setup.md. - Validate all Mermaid diagrams against the docs site renderer version
10.9.5and fix any syntax errors before shipping docs changes. - Docs site must include
sitemap.xmland reference it fromrobots.txt. - Docs site must display the project version from
Directory.Build.props, not CI run numbers. - Docs site footer should keep copyright, license, sitemap, and version compact and preferably single-line.
- Docs site should display the short project name
Storagein the site title or nav while keepingManagedCode.Storagein package-name content. - Do not add ADRs for docs-site generation or pipeline changes; document docs-site build, SEO, and GitHub Pages workflow details under
docs/Development/instead. - Docs site must not generate redirect or alias pages like
/Storage/; keep a single canonical home URL. - After changing the generator, workflow, or layout, smoke-check the built HTML is not empty.
- Every behavior change needs sufficient automated tests to cover its cases; one test is the minimum, not the target.
- Each public API endpoint has at least one test; complex endpoints need tests for different inputs and errors.
- Integration tests must exercise real flows end-to-end, not just call endpoints in isolation.
- Prefer integration or API tests over isolated unit tests.
- Keep mocks to an absolute minimum; prefer real flows using fakes or containers where possible.
- Never write tests that only validate mocked interactions; every test must assert concrete, observable behavior such as state, output, errors, or side effects.
- When faking external APIs, match the official API docs for endpoints, status codes, payloads, and field naming, and prefer
HttpMessageHandler-based fakes over ad-hoc mocks. - No mocks for internal systems such as databases, queues, or caches; use containers or fakes as appropriate.
- Mocks are allowed only for external third-party systems.
- Never delete or weaken a test to make it pass.
- Each test must verify a real flow or scenario; tests without meaningful assertions are forbidden.
- Check coverage to find gaps, not to chase a number.
- Tests use
xUnit+Shouldly; choose[Fact]for atomic cases and[Theory]for data-driven permutations. - Tests run on
VSTest; do not mix inMicrosoft.Testing.Platformassumptions. - Coverage uses the repo-defined
coverlet.msbuildflow and must not regress without a written exception. - Place provider suites under
Tests/ManagedCode.Storage.Tests/Storages/and reuseTests/ManagedCode.Storage.Tests/Common/helpers for Testcontainers infrastructure such as Azurite, LocalStack, and FakeGcsServer. - Add fakes or harnesses in
ManagedCode.Storage.TestFakes/when introducing new providers.
- Ensure storage-related changes keep broad automated coverage around 85-90% using generic, provider-agnostic tests across file systems, storages, and integrations.
- Deliver ASP.NET integrations that expose upload or download controllers, SignalR streaming, and matching HTTP and SignalR clients built on the storage layer for files, streams, and chunked transfers.
- Provide base ASP.NET controllers with minimal routing so consumers can inherit and customize routes, authorization, and behavior without rigid defaults.
- Favor controller extension patterns and optionally expose interfaces to guide consumers toward recommended controller actions.
- For comprehensive storage-platform upgrades, follow the nine-step flow: harden SignalR streaming, harden controller upload paths, add keyed DI registrations and cross-provider sync fixtures, extend VFS with keyed support and large-file trials, create streamed large-file or CRC helpers, run end-to-end suites, verify Blazor upload extensions, expand docs with VFS and provider identity guidance, and finish with the full preview-enabled test suite.
- Normalize MIME lookups through
MimeHelper; avoid ad-hoc MIME resolution helpers so all content-type logic flows through its APIs.
ManagedCode.Storage.slnxorchestrates the .NET 10 projects.- Keep the canonical
AGENTS.mdin the repository root; for multi-project solutions add or update localAGENTS.mdfiles per project so project-specific guidance stays close to each codebase slice. - Core abstractions live in
ManagedCode.Storage.Core/. - The virtual file system lives in
ManagedCode.Storage.VirtualFileSystem/. - Providers live in
Storages/ManagedCode.Storage.*. - Integrations live in
Integraions/. - Test doubles live in
ManagedCode.Storage.TestFakes/. - Tests live in
Tests/ManagedCode.Storage.Tests/. - Keep shared assets such as
logo.pngat the repository root.
- Start work immediately with no permission-seeking.
- Ask questions only for architecture blockers not covered by docs or ADRs.
- Report only when the task is complete.
- When installing or updating MCAF assets, install only current skills with the
mcaf-prefix so repository automation stays aligned with the maintained MCAF skill set and avoids stale skill drift.
- The repo-root
.editorconfigis the source of truth for formatting, naming, style, and analyzer severity. - Use NuGet Central Package Management via
Directory.Packages.props; keep package versions out of individual.csprojfiles so versions stay aligned across the repository. - Follow standard C# conventions: 4-space indentation, PascalCase types, camelCase locals.
- Nullability is enabled: annotate optional members and avoid
!unless justified. - Suffix async APIs with
Async; keep test names aligned with existing patterns such asDownloadFile_WhenFileExists_ReturnsSuccess. - Remove unused usings and let analyzers guide layout.
- When a
foreachloop starts by transforming the iteration variable, prefer mapping the sequence explicitly with.Select(...)so the intent is clearer. - Avoid buffering whole files into
MemoryStreamin product code; assume multi-GB files and stream directly to the destination while using incremental hashing or CRC when verification is needed. - No magic literals; extract them to constants, enums, configuration, or dedicated value types when it improves clarity.
- Write commit subjects in the imperative mood such as
add ftp retry policyand keep them provider-scoped. - Group related edits in one commit and avoid WIP spam.
- PRs should summarize impact, list touched projects, reference issues, and note new configuration or secrets.
- Include the
dotnetcommands you ran and add logs when CI needs context. - Keep a required CI check named
build-and-testrunning on every PR and push tomainso branch protection always receives a status.
- Never commit secrets, keys, access tokens, or connection strings.
- Never commit
.trxartifacts. - Never mock internal systems in integration tests; use containers or fakes instead.
- Never skip tests to make a branch green.
- Never force-push to
main. - Never approve or merge on behalf of a human maintainer.
Always:
- Read root and local
AGENTS.mdfiles before editing code. - Read the relevant docs before changing behavior or architecture.
- Run the required verification commands yourself.
Ask first:
- changing public API contracts
- adding new dependencies
- modifying database schema
- deleting code files