Skip to content

Add an ArchUnitNET architecture-fitness suite with a ratcheting baseline#7

Closed
ChrisonSimtian wants to merge 1 commit into
mainfrom
feature/architecture-fitness-suite
Closed

Add an ArchUnitNET architecture-fitness suite with a ratcheting baseline#7
ChrisonSimtian wants to merge 1 commit into
mainfrom
feature/architecture-fitness-suite

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Owner

What

Adds tests/Fallout.Architecture.Tests — a solution-wide ArchUnitNET suite that codifies Fallout's intended runtime architecture so future work can't silently invert a dependency edge that still compiles. This is the broader-suite half of Fallout-build#95, and it absorbs the Fallout-build#88 Fallout.Core purity guard.

15 tests, all green. 14 are strict invariants that hold today; 1 — the namespace/assembly-alignment rule — carries a documented baseline of the current legacy debt.

Key decisions

  • ArchUnitNET, not the existing NetArchTest.Rules. NetArchTest is effectively unmaintained (last release 2023); ArchUnitNET is maintained and far more expressive. The [Foundation] Extract Fallout.Core domain project Fallout-build/Fallout#88 Fallout.Core guard was migrated onto it and NetArchTest.Rules was retired from Directory.Packages.props.
  • Rules are scoped by assembly, not namespace. The legacy NUKE namespaces deliberately span assemblies (Fallout.Common.* types live in Fallout.Build, Fallout.Build.Shared and Fallout.Common; the Fallout.Utilities.Net assembly still emits Fallout.Common.Utilities.Net.*), so namespace-based layering would be meaningless. Every subject/target uses ResideInAssembly(...), additionally filtered to first-party (Fallout.* / Nuke.*) types to strip tooling-generated noise (ThisAssembly, RefSafetyRulesAttribute, coverlet).
  • A one-way ratchet for known-broken areas. The architecture is partially broken by design right now, so rather than fail the build on day-one debt, each rule is allowed exactly its documented baseline (KnownViolations). The test fails on any new violation and on any baseline entry that has been fixed — so the debt register can only shrink.

Enforced strictly (empty baseline — these hold today)

  • Fallout.Core and Fallout.Utilities are foundations: no in-repo dependencies.
  • Each Fallout.Utilities.* satellite depends only on Fallout.Utilities.
  • Fallout.Tooling, Fallout.ProjectModel, Fallout.Build.Shared don't reach upward; Fallout.Solution is a thin facade over the vendored parser.
  • Nothing depends on the Fallout.Cli composition root.
  • Fallout.* never depends on the Nuke.* transition shims (they point inward only).
  • Fallout.Core takes no dependency on System.IO / System.Diagnostics.Process / System.Console / Serilog (the [Foundation] Extract Fallout.Core domain project Fallout-build/Fallout#88 purity bar).

Baselined (known debt, ratcheting down)

  • Namespace ↔ assembly drift — a type's namespace should be rooted at its assembly name. Ships with a ~220-entry baseline capturing today's Fallout.Common.* sprawl (chiefly under Fallout.Build/Common/Tooling), plus the satellites still emitting Fallout.Common.Utilities.* and the Fallout.Solutions.* facade types. Shrinks as the onion-architecture refactor renames things; each removed entry is a permanent gain the ratchet locks in.

Relationship to refactor/architecture

That branch already has an onion/ring architecture-test suite (NetArchTest, ring-based) targeting a structure not yet on main (Fallout.Domain, Fallout.Application.*, …). This PR is deliberately the fresh suite on main encoding today's assembly layering — independent of the refactor. When refactor/architecture lands, the two reconcile (ideally that suite also moves to ArchUnitNET so there's one tool).

Out of scope (not governed)

The Roslyn build-time tooling (Fallout.SourceGenerators, Fallout.Tooling.Generator, Fallout.Migrate[.Analyzers], Fallout.MSBuildTasks) and the vendored Fallout.Persistence.Solution parser — composition-root / build-time / vendored code outside the runtime layering.

Notes

  • Non-breaking; targets main. No version.json change.
  • The target/2026 label didn't exist on this repo — created it to follow the PR-creation flow.
  • How the suite works, and how to add a rule / regenerate the baseline: docs/architecture-tests.md.
Passed!  -  Failed: 0, Passed: 15, Skipped: 0, Total: 15  -  Fallout.Architecture.Tests.dll (net10.0)

🤖 Generated with Claude Code

Introduce tests/Fallout.Architecture.Tests, a solution-wide ArchUnitNET
suite that locks in the runtime layering so new code can't silently invert
a dependency edge that still compiles. Rules are scoped by assembly (the
legacy NUKE namespaces span assemblies), covering foundation purity, utility
-satellite confinement, downward-only layering, the Cli composition root, and
the Nuke.* shim direction.

Known-broken areas are governed by a one-way ratchet: each rule is allowed
exactly its documented baseline of pre-existing violations (KnownViolations),
and fails on any new violation or any baseline entry that has been fixed, so
the debt can only shrink. The namespace/assembly-alignment rule ships with a
~220-entry baseline capturing today's Fallout.Common.* sprawl.

Migrate the issue-Fallout-build#88 Fallout.Core purity guard off the unmaintained
NetArchTest.Rules onto ArchUnitNET and retire that package. Document the
suite in docs/architecture-tests.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian ChrisonSimtian added the target/2026 Releases on the 2026 calendar line label Jun 25, 2026
ChrisonSimtian added a commit that referenced this pull request Jun 29, 2026
…line

Brings the solution-wide architecture-fitness suite into the Core sweep so
the layering this PR tidies up is now enforced by tests and can't silently
drift back. Originally drafted as a standalone PR (#7), folded in here.

- tests/Fallout.Architecture.Tests: assembly-scoped ArchUnitNET rules —
  Core/Utilities foundation purity, utility-satellite confinement,
  downward-only layering, "nothing depends on the Cli composition root",
  "Fallout.* never depends on the Nuke.* shims", Core I/O-purity, and a
  namespace-rooted-at-assembly naming rule.
- Ratchet + KnownViolations: a one-way ratchet over a documented baseline.
  Known-broken areas are grandfathered; new violations fail, and fixed
  baseline entries must be removed — so the debt can only shrink. Lets us
  be deliberately less strict today while locking in every future gain.
- Migrated the issue-Fallout-build#88 Core purity guard off the unmaintained
  NetArchTest.Rules onto ArchUnitNET; removed that package and the old
  Fallout.Core.Tests guard.
- docs/architecture-tests.md, CHANGELOG, dependencies docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ChrisonSimtian

Copy link
Copy Markdown
Owner Author

Folding this work into the two onion-architecture PRs rather than landing it standalone:

Same suite, same ratchet, same baseline — just delivered alongside the refactors it enforces so the architecture work and its guardrails land together. Closing in favour of those.

ChrisonSimtian added a commit that referenced this pull request Jun 29, 2026
…line

Brings the solution-wide architecture-fitness suite into the Core sweep so
the layering this PR tidies up is now enforced by tests and can't silently
drift back. Originally drafted as a standalone PR (#7), folded in here.

- tests/Fallout.Architecture.Tests: assembly-scoped ArchUnitNET rules —
  Core/Utilities foundation purity, utility-satellite confinement,
  downward-only layering, "nothing depends on the Cli composition root",
  "Fallout.* never depends on the Nuke.* shims", Core I/O-purity, and a
  namespace-rooted-at-assembly naming rule.
- Ratchet + KnownViolations: a one-way ratchet over a documented baseline.
  Known-broken areas are grandfathered; new violations fail, and fixed
  baseline entries must be removed — so the debt can only shrink. Lets us
  be deliberately less strict today while locking in every future gain.
- Migrated the issue-Fallout-build#88 Core purity guard off the unmaintained
  NetArchTest.Rules onto ArchUnitNET; removed that package and the old
  Fallout.Core.Tests guard.
- docs/architecture-tests.md, CHANGELOG, dependencies docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ChrisonSimtian added a commit that referenced this pull request Jun 30, 2026
…line

Brings the solution-wide architecture-fitness suite into the Core sweep so
the layering this PR tidies up is now enforced by tests and can't silently
drift back. Originally drafted as a standalone PR (#7), folded in here.

- tests/Fallout.Architecture.Tests: assembly-scoped ArchUnitNET rules —
  Core/Utilities foundation purity, utility-satellite confinement,
  downward-only layering, "nothing depends on the Cli composition root",
  "Fallout.* never depends on the Nuke.* shims", Core I/O-purity, and a
  namespace-rooted-at-assembly naming rule.
- Ratchet + KnownViolations: a one-way ratchet over a documented baseline.
  Known-broken areas are grandfathered; new violations fail, and fixed
  baseline entries must be removed — so the debt can only shrink. Lets us
  be deliberately less strict today while locking in every future gain.
- Migrated the issue-Fallout-build#88 Core purity guard off the unmaintained
  NetArchTest.Rules onto ArchUnitNET; removed that package and the old
  Fallout.Core.Tests guard.
- docs/architecture-tests.md, CHANGELOG, dependencies docs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

target/2026 Releases on the 2026 calendar line

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant