ark
Architectural boundary enforcer for .NET solutions. Parses .csproj project graphs and C# source files to catch layer violations before they reach CI.
$ ark check
× Layer 'Domain' (MyApp.Domain) must not depend on layer 'Infrastructure' (MyApp.Infrastructure.Data)
╭─[MyApp.Domain/MyApp.Domain.csproj:6:27]
6 │ <ProjectReference Include="..\MyApp.Infrastructure.Data\MyApp.Infrastructure.Data.csproj" />
· ──────────────────────────────────────────────────────────────────
╰─
What it checks
| Check | What it catches |
|---|---|
| Project references | .csproj <ProjectReference> that cross forbidden layer boundaries |
| Package policies | <PackageReference> packages banned from specific layers (e.g. EF Core in Domain) |
| Source imports | using directives in .cs files referencing a forbidden layer's namespace (tree-sitter) |
Violations are reported with source spans pointing directly to the offending line.
Quick start
# 1. Scaffold architecture.toml interactively
# 2. Check for violations
Installation
Pre-built binaries (Linux, Windows x86/arm) are available on the releases page.
Or install via Cargo:
Or build from source:
# binary: target/release/ark
Configuration
ark reads architecture.toml from the solution root. Run ark init to generate a starter file, or write one by hand:
= [
{ = "Presentation", = ["*.Api", "*.Web", "*.Host"] },
{ = "Application", = ["*.Application", "*.UseCases"] },
{ = "Domain", = ["*.Domain", "*.Core"] },
{ = "Infrastructure", = ["*.Infrastructure", "*.Persistence"] },
]
# Any dependency not listed here is forbidden by default.
= [
{ = "Presentation", = "Application", = true },
{ = "Application", = "Domain", = true },
{ = "Infrastructure", = "Domain", = true },
{ = "Domain", = "Infrastructure", = false },
]
= [
{ = "Domain", = ["Microsoft.EntityFrameworkCore", "Microsoft.AspNetCore"] },
]
= ["*.Tests", "*.Specs", "*.IntegrationTests"]
Layer patterns use glob syntax — *.Domain matches any project name ending in .Domain. Any dependency not listed in dependency_rules is forbidden by default.
C# source scanning
Add namespace_patterns to a layer to also check using directives in .cs files for that layer (powered by tree-sitter):
= [
{ = "Domain", = ["*.Domain"], = ["MyApp.Domain.*"] },
]
Omit namespace_patterns to skip source scanning for that layer.
Commands
ark check
Run all architectural checks and report violations.
ark baseline
Brownfield adoption: snapshot existing violations so ark check only fails on new ones. Teams can quarantine known debt and clean it up incrementally.
Commit ark-baseline.json alongside your config. Stale entries (violations that no longer exist) surface as warnings so you know when debt has been paid off.
ark explain
Show which layer a project belongs to and what it can depend on.
Project: MyApp.Domain
Layer: Domain
Dependency rules:
→ Application forbidden [default]
→ Infrastructure forbidden [explicit]
→ Presentation forbidden [explicit]
Other projects in this layer:
MyApp.Core
Useful when a project shows up as unmatched or when onboarding to an unfamiliar solution.
ark graph
Export the project dependency graph.
ark init
Interactively scaffold architecture.toml from your real solution structure.
The wizard:
- Scans all
.csprojfiles and builds a dependency graph - Groups projects into architectural tiers by topological depth
- Walks you through naming each tier as a layer
- Reviews each detected inter-layer dependency — allow or forbid
- Writes
architecture.tomltailored to your solution
For brownfield teams with existing violations, run ark baseline right after to snapshot the current state.
CI integration
GitHub Actions
- name: Check architecture
run: |
curl -sSL https://github.com/TheEskhaton/ark/releases/latest/download/ark-latest-x86_64-unknown-linux-gnu.tar.gz | tar xz
./ark check
Or via Cargo (slower, but no binary download needed):
- name: Check architecture
run: |
cargo install ark-cli --quiet
ark check
ark exits 0 on clean, 1 on violations.
Global flags
ark --root <path> # solution root (default: current directory)
ark --config <path> # config file (default: architecture.toml)
Useful when running ark from a directory other than the solution root:
Exit codes
| Code | Meaning |
|---|---|
0 |
No violations |
1 |
One or more violations found |
Use --strict to also exit 1 on warnings (e.g. projects that match no layer).
Performance
ark uses rayon for parallel project and file parsing.
| Operation | Target | Typical (ABP Framework, ~500 projects) |
|---|---|---|
| Project graph scan | < 50 ms | ~30 ms |
| Full source scan (tree-sitter) | < 500 ms | ~200 ms |
License
MIT