ArchLinterNet.Testing
0.8.1
See the version list below for details.
dotnet add package ArchLinterNet.Testing --version 0.8.1
NuGet\Install-Package ArchLinterNet.Testing -Version 0.8.1
<PackageReference Include="ArchLinterNet.Testing" Version="0.8.1" />
<PackageVersion Include="ArchLinterNet.Testing" Version="0.8.1" />
<PackageReference Include="ArchLinterNet.Testing" />
paket add ArchLinterNet.Testing --version 0.8.1
#r "nuget: ArchLinterNet.Testing, 0.8.1"
#:package ArchLinterNet.Testing@0.8.1
#addin nuget:?package=ArchLinterNet.Testing&version=0.8.1
#tool nuget:?package=ArchLinterNet.Testing&version=0.8.1
<p align="center"> <img src="docs/assets/logo.png" alt="ArchLinterNet" width="420"> </p>
<p align="center"> <a href="https://www.nuget.org/packages/ArchLinterNet.Cli/"><img alt="NuGet version" src="https://img.shields.io/nuget/v/ArchLinterNet.Cli.svg"></a> <a href="https://www.nuget.org/packages/ArchLinterNet.Cli/"><img alt="NuGet downloads" src="https://img.shields.io/nuget/dt/ArchLinterNet.Cli"></a> <a href="https://github.com/eugenemalaschuk-source/arch-linter-net/actions/workflows/main-quality.yml"><img alt="Main quality" src="https://github.com/eugenemalaschuk-source/arch-linter-net/actions/workflows/main-quality.yml/badge.svg?branch=main"></a> <a href="https://raw.githubusercontent.com/eugenemalaschuk-source/arch-linter-net/architecture-health-badge/architecture-health-publication.json" title="Open the canonical Architecture Health publication receipt; this Shields image is a snapshot compatibility view"><img alt="Architecture Health snapshot" src="https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Feugenemalaschuk-source%2Farch-linter-net%2Farchitecture-health-badge%2Farchitecture-health.json"></a> <a href="https://sonarcloud.io/summary/overall?id=eugenemalaschuk-source_arch-linter-net&branch=main"><img alt="Sonar Quality Gate" src="https://sonarcloud.io/api/project_badges/measure?project=eugenemalaschuk-source_arch-linter-net&metric=alert_status&branch=main"></a> <a href="https://app.codecov.io/github/eugenemalaschuk-source/arch-linter-net"><img alt="Test coverage" src="https://codecov.io/github/eugenemalaschuk-source/arch-linter-net/graph/badge.svg?branch=main"></a> <a href="https://eugenemalaschuk-source.github.io/arch-linter-net/"><img alt="Documentation" src="https://img.shields.io/badge/docs-GitHub%20Pages-blue"></a> <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-blue.svg"></a> </p>
YAML-first architecture governance for .NET repositories.
ArchLinterNet turns architecture decisions into executable, reviewable contracts. It governs namespace and assembly boundaries, project/package metadata, semantic roles and contexts, public API surfaces, architecture coverage, migration debt, and CI change gates — with deterministic diagnostics that humans and automation can consume.
One packed ArchLinterNet CLI covers the complete static architecture-governance cycle: declare and check policy, prove applicability, validate topology and visible contract surfaces, govern finding and waiver debt, measure budgets, bind repository-local SARIF, compare change, project Architecture Health, and render PR Markdown and the real Health badge. CI invokes and transports the resulting canonical artifacts; it is not a second governance implementation.
The goal is not just to lint dependencies. ArchLinterNet makes architecture rules explicit and safe to evolve as normal repository code.
Versioning and updates
ArchLinterNet follows Semantic Versioning with an explicit release-train convention while the project remains in the 0.x initial-development range:
0.Y.0is a capability release: a reviewed user-facing product increment. Minor releases may include compatibility changes while the project is pre-1.0, so review the release notes before upgrading.0.Y.ZwithZ > 0is a maintenance release for the same0.Ycapability line: correctness/integration fixes, reliability fixes, documentation corrections, and behavior-preserving engineering cleanup. Unrelated next-minor capability work is intentionally excluded.*-preview.Nis an early-validation preview release and may still change before stable publication.X.Y.Z-main.Nis an internal development/dogfood build, not a public stable release.
Within a released minor line, consumers should normally prefer the latest available patch after reviewing its release notes. See Versioning and release meaning for the complete public contract and Adopt or upgrade ArchLinterNet for upgrade steps.
Why ArchLinterNet?
Architecture rules often start as diagrams, ADRs, review comments, handwritten test helpers, or tribal knowledge. That works for a while, but the rules quickly become hard to discover, hard to reuse across repositories, and hard for humans or AI agents to review consistently.
ArchLinterNet uses a repository-owned YAML policy file as the source of truth:
architecture/arch.yml (recommended; any selected filename works)
↓
ArchLinterNet CLI / test adapter
↓
strict or audit architecture validation
↓
human diagnostics + JSON/SARIF/CI artifacts
Use it when you want architecture rules to be declarative, reviewable, CI-friendly, and independent from one-off test code.
Quick start
Create a root policy. This quick start uses the recommended concise path architecture/arch.yml; the filename is configurable and has no runtime semantics. New policy authoring should prefer version: 2, which defaults manual waivers to strict lifecycle governance; existing version: 1 policies remain supported with compatibility defaults.
version: 2
name: Example Architecture Contract
layers:
application:
namespace: MyApp.Application
domain:
namespace: MyApp.Domain
infrastructure:
namespace: MyApp.Infrastructure
analysis:
target_assemblies:
- MyApp.Application
- MyApp.Domain
- MyApp.Infrastructure
contracts:
strict:
- id: application-not-infrastructure
name: application-must-not-depend-on-infrastructure
source: application
forbidden: [infrastructure]
reason: Application code must depend on abstractions, not concrete infrastructure.
strict_layers:
- id: clean-architecture-layering
name: clean-architecture-layering
layers: [infrastructure, application, domain]
reason: Dependencies must point inward toward the domain.
Run from this repository during development:
dotnet run --project src/ArchLinterNet.Cli -- --policy architecture/arch.yml --mode strict
After installing the .NET tool from NuGet.org:
arch-linter-net --policy architecture/arch.yml --mode strict
For repository/CI adoption, prefer a local tool manifest and run dotnet arch-linter-net ...; see Installation.
Main capabilities
ArchLinterNet focuses on static architecture governance:
- YAML root policies, deterministic local imports, packaged schemas, and reusable bounded source sets.
- Namespace/layer dependency, allow-only, ordered-layer, protected-surface, cycle, independence, assembly, and module-container governance.
- External dependency, NuGet package, framework-reference, project-metadata, method-body, and Unity
.asmdefrules. - Type placement, source-layout conventions, attribute usage, inheritance, interface implementation, composition boundaries, and public API surface snapshots.
- Semantic classification from implemented code facts, selector-backed layers, contextual dependency/allow-only rules, and semantic port/ACL boundaries.
- Coverage contracts for
namespace,project,assembly,dependency_edge,rule_input, andsemantic_roleinventory. - Native declared topology with capture/diff/verify, recursive contract-surface exposure, architecture metrics, absolute/baseline-relative budgets, and repository-local external SARIF evidence.
- Project/solution discovery, explicit build-state preflight, opt-in
--ensure-built, condition sets, persistent analysis cache, and bounded parallel scanning. - Strict gates, audit discovery, migration baselines, structured waiver lifecycle, effective policy inventory, policy consistency, policy-context export, and policy-weakening review.
- Architecture change snapshots/reports, history forensics, dependency graphs/path explanation, Architecture Health, deterministic PR Markdown, Health and legacy architecture-policy badge projections, and public API lifecycle commands.
- Human, normalized JSON, SARIF where applicable, repeatable report sinks, timings, analysis profiles, and CI-oriented coverage artifacts.
- CEL-backed
whenpredicates at documented closed locations — standard CEL under a safe profile, not an open-ended scripting language.
ArchLinterNet does not validate runtime dependency-injection behavior, authorization/security correctness, code ownership, arbitrary semantic data flow, or undocumented custom YAML contract families.
Documentation
Public product documentation is published through MkDocs and GitHub Pages:
- Documentation home
- Getting started
- Complete single-tool governance workflow
- Installation
- CLI reference
- Policy format
- Structured waivers
- Architecture Health
- Versioning and release meaning
- Contract families
- Coverage contracts
- Supported capabilities and non-goals
- Real-repository workflow
- CI integration
- Adopt or upgrade ArchLinterNet
- Extended governance adoption
- Reference entrypoints
- Verify release provenance
- AI policy authoring
The public capability references are checked against runtime/schema/CLI inventories by make lint-docs, so a new executable capability cannot silently leave the main documentation matrix stale.
Internal project documentation remains in repository Markdown files such as docs/internal/, openspec/, .github/, and root governance files. It is not part of the published product site.
GitHub Pages is deployed only by the public release workflow. A merge to main refreshes focused quality telemetry and development/dogfood main.N packages, but does not deploy MkDocs. A successfully processed red Sonar quality gate remains visible through the direct Sonar badge/dashboard while Main quality represents successful current-SHA telemetry delivery; scanner, upload, processing, revision, import, or Codecov delivery failures still make that workflow red.
Local documentation workflow
make venv # create Python virtual environment
make docs-serve # preview MkDocs locally
make docs-build # build the static documentation site
make fmt-docs # auto-format markdown documentation
make lint-docs # strict structure + semantic documentation validation
Generated site/ output is a build artifact and should not be committed.
Architecture Health badge
Private repositories default to none: no automatic cloud setup or badge
publication/egress. Core governance, required PR checks, private reports and
public github-raw snapshots remain independent of Relay.
Private Relay is experimental / opt-in. Relay code is included, but full hosted/lifecycle acceptance is still pending. This is not an adoption-stable or completed turnkey service: the adopter owns the Relay infrastructure and must approve disclosure and verify the exact release/candidate. No free hosting or SLA is promised. Experimental status never waives known security, privacy, integrity, data-corruption or false-PASS defects; unsafe paths remain blockers.
The no-App bootstrap is read-only and delivers a private, content-verified handoff for an owner-reviewed protected setup PR. OIDC publication updates only Relay state, not consumer badge commits on every PR or renewal.
After explicitly opting into Relay, the recommended README view is the
adopter-owned Relay's strict, local fixed-template SVG. Register the
headline-plus-freshness/v1 profile and use the profile-selected route (or its
explicit .svg route) as the one README image:
<img alt="Architecture Health" src="https://<relay-origin>/badge-relay/v1/<opaque-alias>.svg">
That SVG visibly places the canonical architecture label, Health-owned
message and color beside absolute UTC verified at and valid until text.
It is deliberately generated by a fixed local template: it does not embed a
source URL, provenance, SHA, PR/run, token, arbitrary metadata, script, link,
external asset, or caller-controlled markup. A headline-only registration
cannot silently use this bounded-current view.
The exact JSON route remains available for integrations that need the canonical byte string. Project canonical Architecture Health and canonical policy inventory into that snapshot-compatible Shields payload without rerunning analysis:
arch-linter-net badge architecture-health \
--input architecture-health.json \
--output architecture-health-badge.json
The payload headline contains the non-compensating Health category, accumulated
explicit ignore debt, and effective policy-control count. It is not a score,
coverage percentage, test result, or generic workflow status. UNASSESSABLE · ? ignores · ? rules explicitly means the required Health/inventory evidence
was not available; it never means zero debt. Bare JSON and Shields endpoint
views are snapshot compatibility views: they do not claim bounded-current
rendering and headline-only JSON does not gain freshness fields.
The README badge links to the canonical v2 publication receipt. Use that receipt to verify the repository, analyzed and merged commit/tree identities, pull request, producer and publisher run/attempt provenance, payload digest, status/reason, and publication time; then compare its digest with the raw badge payload. The receipt is the source of truth for canonical publication freshness. A new receipt for the current merged tree is fresh evidence even when the deterministic Gate, Health, ignore, and rule values are unchanged.
The Relay checks now < valid_until at origin time for every GET, HEAD, and
conditional request before ETag/304 handling. A stopped publisher therefore
expires without a cron job; an expired, revoked, corrupt, or storage-uncertain
origin returns the fixed unavailable representation with no-store and no
ready ETag. Ready max-age never exceeds the whole seconds remaining in the
lease, and a new lease/generation changes the ETag even when the headline is
unchanged.
An origin guarantee cannot recall copies already held by a browser, GitHub's README image proxy (Camo), another proxy, or an offline client. If a cached image looks old, compare the origin representation and headers with the observed copy; cache delay is not current-origin proof, and no fixed delay is promised. Publication never creates cache-busting commits or mutates canonical payload values merely to make a refresh visible. See CI integration: verify Architecture Health badge freshness for the layer-by-layer diagnostic.
badge architecture-policy remains available for integrations that need the
older, narrower strict-validation signal:
arch-linter-net badge architecture-policy --input architecture-strict.json
Project health and assurance
<details> <summary>Security, maintainability, and supply-chain status</summary>
<p> <a href="https://github.com/eugenemalaschuk-source/arch-linter-net/actions/workflows/codeql.yml"><img alt="CodeQL" src="https://github.com/eugenemalaschuk-source/arch-linter-net/actions/workflows/codeql.yml/badge.svg"></a> <a href="https://scorecard.dev/viewer/?uri=github.com/eugenemalaschuk-source/arch-linter-net"><img alt="OpenSSF Scorecard" src="https://api.scorecard.dev/projects/github.com/eugenemalaschuk-source/arch-linter-net/badge"></a> <a href="https://www.bestpractices.dev/en/projects/13572/passing"><img alt="OpenSSF Best Practices" src="https://www.bestpractices.dev/projects/13572/badge"></a> <a href="https://sonarcloud.io/summary/overall?id=eugenemalaschuk-source_arch-linter-net&branch=main"><img alt="Sonar Quality Gate" src="https://sonarcloud.io/api/project_badges/measure?project=eugenemalaschuk-source_arch-linter-net&metric=alert_status&branch=main"></a> <a href="https://sonarcloud.io/summary/overall?id=eugenemalaschuk-source_arch-linter-net&branch=main"><img alt="Sonar Maintainability" src="https://sonarcloud.io/api/project_badges/measure?project=eugenemalaschuk-source_arch-linter-net&metric=sqale_rating&branch=main"></a> <a href="https://sonarcloud.io/summary/overall?id=eugenemalaschuk-source_arch-linter-net&branch=main"><img alt="Sonar Reliability" src="https://sonarcloud.io/api/project_badges/measure?project=eugenemalaschuk-source_arch-linter-net&metric=reliability_rating&branch=main"></a> <a href="https://sonarcloud.io/summary/overall?id=eugenemalaschuk-source_arch-linter-net&branch=main"><img alt="Sonar Security" src="https://sonarcloud.io/api/project_badges/measure?project=eugenemalaschuk-source_arch-linter-net&metric=security_rating&branch=main"></a> </p>
The Main quality badge tracks successful current-SHA post-merge telemetry delivery. That run requires all three Linux coverage shards, one canonical complete coverage receipt, successful Sonar scanner/upload/processing/revision/import verification, and a successful Codecov upload. A processed Sonar Quality Gate failure remains a warning and direct Sonar branch badge/dashboard signal rather than being misclassified as a failed telemetry refresh. The Architecture Health badge is different: a required PR Architecture Coverage job creates the exact ArchLinterNet payload, and a trusted post-merge publisher releases it only after proving the PR head and squash-merged main commit have the same Git tree. Missing, stale, or mismatched evidence replaces the stable endpoint with an explicit unassessable badge; it never leaves an old healthy payload represented as current. This publication does not rerun the architecture matrix or deploy MkDocs. SonarCloud also analyzes trusted pull requests, decorates the PR, and evaluates the quality gate on new code before merge:
| Quality signal | Source |
|---|---|
| Build/test | Required pull-request validation runs make acceptance-equivalent unit/E2E/packed-artifact gates before merge |
| Test coverage (line %) | PR CI and post-merge Main Quality Telemetry collect coverage; the merged-main run uploads Cobertura XML to Codecov so the primary coverage badge follows main |
| Architecture Health | Canonical Health, accumulated explicit ignore debt, and effective policy controls from required PR evidence promoted only after exact merged-tree proof; it is not generic CI, a score, or coverage |
| SonarCloud PR quality gate | trusted pull_request runs analyze new code, publish a SonarCloud PR result link, and fail CI when the Sonar quality gate fails |
| SonarCloud main quality signals | Main Quality Telemetry analyzes the merged revision with OpenCover/TRX/Python coverage; successful delivery may coexist with a red direct Sonar Quality Gate badge because the processed gate result is telemetry, while delivery/integrity failures keep Main quality red |
| OpenSSF Scorecard | trusted pull requests produce reviewable SARIF; default-branch and scheduled runs publish the supply-chain score to the public Scorecard API and GitHub code scanning |
| Architecture validation | strict ArchLinterNet self-policy check (architecture/dependencies.arch.yml), including the reviewed public API snapshots under architecture/api/; read-only, never rewrites either |
| Architecture coverage | strict/audit coverage JSON artifacts + Markdown report + sticky PR comment on the required pull-request gate |
See CI integration for how the PR gate, merged-main test coverage upload, SonarCloud analysis, and the separate architecture coverage gate fit together.
</details>
NuGet and repository links
NuGet packages should expose only public user-facing links:
- project/documentation URL: the GitHub Pages MkDocs site;
- repository URL: this GitHub repository;
- package README: this concise product README;
- license: repository license expression.
NuGet metadata must not point users to internal backlog governance, OpenSpec archives, or maintenance-agent instructions as product documentation.
Security
Report suspected vulnerabilities privately through GitHub Private Vulnerability Reporting. Do not disclose unresolved vulnerabilities in public issues, pull requests, or discussions. See the security policy for supported preview releases, reporting guidance, and disclosure expectations.
License
MIT.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- ArchLinterNet.Core (>= 0.8.1)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 0.9.1 | 58 | 9/28/2026 |
| 0.9.0 | 41 | 9/28/2026 |
| 0.9.0-preview.1 | 248 | 9/22/2026 |
| 0.8.2 | 244 | 9/19/2026 |
| 0.8.1 | 86 | 9/19/2026 |
| 0.8.0 | 429 | 9/5/2026 |
| 0.7.4 | 104 | 8/28/2026 |
| 0.7.3 | 98 | 8/27/2026 |
| 0.7.2 | 95 | 8/27/2026 |
| 0.7.1 | 109 | 8/26/2026 |
| 0.7.0 | 181 | 8/23/2026 |
| 0.6.5 | 111 | 8/15/2026 |
| 0.6.4 | 142 | 8/13/2026 |
| 0.6.3 | 100 | 8/12/2026 |
| 0.6.2 | 101 | 8/12/2026 |
| 0.6.1 | 99 | 8/10/2026 |
| 0.6.0 | 118 | 8/6/2026 |
| 0.5.0 | 116 | 7/19/2026 |
| 0.4.2 | 115 | 7/10/2026 |
| 0.4.1 | 114 | 7/10/2026 |
See GitHub release notes for v0.8.1. Private Relay is experimental / opt-in. Its full hosted/lifecycle acceptance is pending. Stable core governance plus private reports and public github-raw snapshots remain independent of Relay. Private default: none. There is no automatic cloud setup or badge egress. Adopter-owned infrastructure and explicit disclosure consent are required. Experimental is not a waiver for known security or privacy or integrity or data-corruption or false-PASS defects.