Examples and use cases
Start with a runnable example, then adapt its policy to your projects. The downloads contain small, package-free .NET 10 solutions, complete YAML, build configuration and source. Install the CLI and a .NET 10 SDK; no Architecture Guardian source build is required.
| Sample | Download | What it demonstrates |
|---|---|---|
| Clean Architecture | Download ZIP | Domain ports, inward layer directions, forbidden Application → Infrastructure access |
| Modular monolith | Download ZIP | Orders/Billing contracts, a forbidden module dependency and a logical module cycle |
Review the files before restoring/scanning: --trusted authorizes their MSBuild
logic. Extract the archive and run commands inside its top-level sample directory.
Named configurations enable alternative source/references under the same policy.
Clean Architecture
Section titled “Clean Architecture”In the extracted CleanArchitecture directory:
dotnet restore CleanArchitecture.slnx -p:Configuration=Compliantarchguard inspect CleanArchitecture.slnx --policy architecture.guardian.yaml --configuration Compliant --trustedarchguard scan CleanArchitecture.slnx --policy architecture.guardian.yaml --configuration Compliant --trustedExpect Analysis completed: 0 diagnostic(s). Gate passed. and exit 0.
The policy assigns all four projects to Shop. Application and Infrastructure may
depend on Domain; Host may compose Application, Infrastructure and Domain. Domain
has no cross-layer permission. The sample selects AG001–AG003 as errors.
Now enable an Application use that bypasses the Domain port:
dotnet restore CleanArchitecture.slnx -p:Configuration=AG002archguard scan CleanArchitecture.slnx --policy architecture.guardian.yaml --configuration AG002 --trustedThe code compiles, but AG002 rejects Application → Infrastructure. Expect one
finding, source evidence, Gate failed and exit 1. In
Shop.Application/Checkout.cs, BypassPort constructs Infrastructure’s
OrderStore directly. The ordinary Submit method depends on Domain.IOrderStore.
Use that port and keep implementation selection in Host when repairing the edge.
For your application, map its real projects and allowed directions. Layer names alone do not impose a universal Clean Architecture layout. See modules and layers and AG002.
Modular-monolith boundaries
Section titled “Modular-monolith boundaries”In the extracted ModularMonolith directory:
dotnet restore ModularMonolith.slnx -p:Configuration=Compliantarchguard scan ModularMonolith.slnx --policy architecture.guardian.yaml --configuration Compliant --trustedExpect exit 0. Orders consumes Billing’s declared api contract rather than its
application implementation. The two modules have independent contract projects.
Select a context that consumes implementation instead:
dotnet restore ModularMonolith.slnx -p:Configuration=AG001archguard scan ModularMonolith.slnx --policy architecture.guardian.yaml --configuration AG001 --trustedExpect one AG001 finding and exit 1. This sample selects AG001–AG003. In your
repository, add AG004 when cross-module semantic access must remain limited to
contract projects even with a broader AG001 module permission. A C# public type
in another module’s implementation is not automatically an architectural API.
Detect a cycle through approved contracts
Section titled “Detect a cycle through approved contracts”dotnet restore ModularMonolith.slnx -p:Configuration=AG003archguard scan ModularMonolith.slnx --policy architecture.guardian.yaml --configuration AG003 --trustedExpect one AG003 finding and exit 1. Both cross-module edges have contract
permissions and the projects build without a reference cycle. The logical module
graph still contains Billing → Orders → Billing. Remove or invert one business
dependency, or introduce an independent shared contract module when appropriate.
Adding permissions does not remove the cycle.
Keep technology out of Domain code
Section titled “Keep technology out of Domain code”Use AG006 on an existing Domain layer to ban explicit technology dependencies, with narrow namespace exceptions. This fragment belongs inside that layer:
domainInfrastructure: forbiddenNamespaces: [System.Data] allowedNamespaces: [System.Data.SqlTypes]Add AG006: error to the complete policy’s rules. Bound uses of System.Data
outside the allowed subtree violate AG006; unused imports alone do not. There is
no built-in infrastructure blacklist: choose restrictions for your intended design.
Use AG005 for independent module/layer restrictions on exact assembly names and namespace subtrees. AG006 exceptions do not override AG005 or AG002. See the YAML walkthrough, AG005 and AG006.
Adopt enforcement in an existing codebase
Section titled “Adopt enforcement in an existing codebase”Run a full scan and review its findings. If some debt is deliberately accepted, write a baseline only after completed analysis:
archguard baseline update MyApp.slnx --policy architecture.guardian.yaml --baseline architecture.baseline.json --configuration Release --trustedarchguard scan MyApp.slnx --policy architecture.guardian.yaml --baseline architecture.baseline.json --configuration Release --trustedUse your restored input and commit the reviewed baseline. Later scans classify existing, new and resolved findings and gate only new ones. Keep full scans for release approval. Never refresh baselines automatically in CI. See baselines.
For a PR-relative gate, prepare both trees’ SDKs/package caches and use
--base <explicit-commit> instead. Comparison evaluates complete contexts,
including policy changes and dependencies outside changed files. It does not scan
only edited lines. See Git analysis and CI integration.
Architecture-aware AI agents
Section titled “Architecture-aware AI agents”Configure MCP or give an agent access to the installed CLI. The useful loop is: retrieve policy and resolved ownership, implement the change, analyze, explain current findings, correct dependencies, and analyze again.
MCP list_rules reads policy metadata; get_architecture resolves ownership in a
trusted prepared context. Validate with analyze_solution and use a fresh diagnostic
ID with explain_violation. Require completed coverage and a passed gate alongside
normal build/tests and review. See the agent workflow.
Understand incomplete results
Section titled “Understand incomplete results”Both downloads include an intentionally broken Incomplete configuration. Restore
Compliant first, then scan with --configuration Incomplete. Expect exit 2,
available findings and operational issues, with no passing gate. This demonstrates
incomplete coverage; it is not a code pattern to copy.
Distinguish boundary violations from unavailable analysis. Use diagnostics and outcomes and troubleshooting to decide the next action.