Skip to content

refactor(arch)!: Infrastructure-ring kickoff — Components + Tool layer re-homed (onion steps 4a/4b)#350

Closed
ChrisonSimtian wants to merge 5 commits into
spike/onion-applicationfrom
spike/onion-infrastructure
Closed

refactor(arch)!: Infrastructure-ring kickoff — Components + Tool layer re-homed (onion steps 4a/4b)#350
ChrisonSimtian wants to merge 5 commits into
spike/onion-applicationfrom
spike/onion-infrastructure

Conversation

@ChrisonSimtian

Copy link
Copy Markdown
Collaborator

⚠️ Breaking change — namespace moves (ADR-0006). Native Fallout.* consumers rewrite their usings: Fallout.ComponentsFallout.Application.Components; Fallout.Common.Tools.*Fallout.Application.Tools.*; Fallout.Common.ToolingFallout.Application.Tooling (and Fallout.Infrastructure.Tooling for the process/resolver executor). Assemblies/package IDs are unchanged — namespaces only. Batched to the (still-unreleased) 2026 major.

Third leg of the onion realignment (ADR-0006), stacked on #349 (Application ring) → #343 (Domain ring) → experimental. Base is spike/onion-application until the stack merges down.

What moves

Step 4a — composition components → Application (65d2d413)

  • Fallout.Components (ICompile, IRestore, IPack, IHas*, Configuration, …) → Fallout.Application.Components. It composes the tool/CI vocabulary, so it's Application-ring.
  • Nuke.Components shim is unchanged for consumers — its public Nuke.Components.* face is preserved (generator source prefix repointed).

Step 4b — tool layer split across rings (56df225b)

Types → namespace
Fallout.Common.Tools.* wrappers Fallout.Application.Tools.*
Tool vocabulary, ports (IProcess/IProcessRunner), attributes, ProcessException Fallout.Application.Tooling
Executor — ProcessTasks, SystemProcessRunner, Process2, ProcessExtensions, ToolExecutor, tool/package/version resolvers, ToolingExtensions Fallout.Infrastructure.Tooling

⚠️ Known interim state (tracked)

ToolTasks (Application) still calls ProcessTasks (Infrastructure) directly, and tool/package path resolution still does I/O from the Application side — a tracked Application→Infrastructure dependency. The rings are namespaces, not yet separate assemblies, so nothing enforces it. A follow-up inverts these behind ports (IToolPathResolver, package-resolver ports, route ToolTasks.Run through IProcessRunner) before the rings become separate projects.

The Nuke.Common.Tools/…Tooling shim aliases lapse (the generator only mirrors the Fallout.Common.* prefix), consistent with steps 1–2 and the deferred shim/migration redesign.

Tooling — tools/OnionRewriter

Generalized from a single-prefix mover to: a Rule[] table, per-type overrides (split one namespace across rings), multi-assembly rules, lost-ancestor usings (a moved file loses implicit access to its old parent namespace — e.g. Fallout.Common's EnvironmentInfo/NotNull/Assert), and cref rewriting (descend into doc-comment trivia). Lessons #8#11 in docs/spikes/0003.

Verification

  • dotnet build fallout.slnx — green (0 errors; 26 warnings, baseline 28).
  • Full dotnet test fallout.slnx — green. 7 cake-migration Verify snapshots re-accepted (namespace-only churn).
  • CHANGELOG updated under the 2026 breaking-changes section (steps 4a/4b).

🤖 Generated with Claude Code

@ChrisonSimtian ChrisonSimtian added breaking-change Change is breaking — requires major version bump per CLAUDE.md semver policy. target/2026 Targets the 2026 calendar-version line (current). See ADR-0004. labels May 31, 2026
@ChrisonSimtian

Copy link
Copy Markdown
Collaborator Author

Added 2934d9f8port inversion + Application-ring fitness gate, resolving the "Known interim state" flagged above.

The impure tool-execution services now sit behind ports in Fallout.Application.Tooling (IProcessExecutor, IToolPathResolver, IToolVersionResolver) resolved via a ToolingServices locator; Fallout.Infrastructure.Tooling registers thin adapters through a module initializer. The Application ring no longer references Fallout.Infrastructure.* — guarded by a NetArchTest gate in the new tests/Fallout.Architecture.Tests (Fallout.Application.*Fallout.Infrastructure.*, green). ProcessExtensions (pure IProcess/Output helpers) was reclassified back to Application.Tooling.

Catch-all Fallout.Common.* code outside the Application ring (CI adapters, a couple of attributes, the Fallout.Cli composition root, MSBuildTasks) still reaches Infrastructure by design — that folds in with step 5 as those namespaces get rings.

ChrisonSimtian and others added 5 commits June 3, 2026 14:51
…n step 3

ADR-0006 step 3 (first piece of the Infrastructure ring). The single impure step of
running a tool — spawning an OS process — now goes through an injectable IProcessRunner
port (default SystemProcessRunner) instead of a static Process.Start. This lets the
tooling vocabulary stay pure (prerequisite for moving the wrappers to Application in
step 4) and makes builds unit-testable by swapping the runner. Non-breaking; behaviour
identical — Tooling builds, 64/64 tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… lessons)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…tep 4a)

Move the build-composition interface family (ICompile, IRestore, IPack,
IPublish, ITest, IHas*, Configuration, …) from Fallout.Components into the
Application ring: Fallout.Components → Fallout.Application.Components. It
composes the tool/CI vocabulary, so it belongs in Application (ADR-0006).

Native consumers rewrite `using Fallout.Components;` →
`using Fallout.Application.Components;`. The Nuke.Components transition shim
is unaffected for consumers — its public Nuke.Components.* face is unchanged;
ShimMarker's generator source prefix is repointed to the new namespace
(a string literal the semantic rewriter intentionally leaves alone). The
Fallout.Components assembly/project keeps its filename until the later
mechanical rename step.

Tooling: generalize tools/OnionRewriter to a Rule[] table (multi-assembly,
multi-prefix) so the remaining infra-ring steps just add rules. Fix a
nested-type classification bug surfaced here — a nested type's
ContainingNamespace is its enclosing namespace, so keying the moved-set by the
symbol's own name misclassified SignPathSettings as residual and added a
dangling using to the evacuated namespace; classify by the outermost
enclosing type instead, and never re-import a non-surviving namespace.

Full suite green (Components.Tests, Nuke.Components.Shim.Tests, no Verify churn).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ture (onion step 4b)

Split the tool layer across the Application and Infrastructure rings
(ADR-0006). The tool wrappers Fallout.Common.Tools.* and the vocabulary they
build on — ToolTasks, ToolOptions, Output, Configure<T>, the IProcess/
IProcessRunner ports, requirement & attribute types, ProcessException — move
to Fallout.Application.Tools.* / Fallout.Application.Tooling. The impure
executor that shared the Fallout.Common.Tooling namespace (ProcessTasks,
SystemProcessRunner, Process2, ProcessExtensions, ToolExecutor, and the
tool/package/version resolvers) moves to Fallout.Infrastructure.Tooling.

Per the maintainer's "true homes, defer port fix" call: types land where they
belong, accepting ToolTasks(App) → ProcessTasks(Infra) and resolver I/O as a
tracked Application→Infrastructure dependency to be inverted behind ports in a
follow-up (the rings are namespaces, not yet separate assemblies, so nothing
enforces it). The Nuke.Common.Tools/Tooling shim aliases lapse, consistent
with steps 1–2 and the deferred shim redesign.

Native consumers rewrite `using Fallout.Common.Tools.*;` →
`using Fallout.Application.Tools.*;` and `using Fallout.Common.Tooling;` →
`using Fallout.Application.Tooling;` (+ Fallout.Infrastructure.Tooling where
they touch the executor). Assembly/project files unchanged; namespaces only.

Tooling: OnionRewriter gains per-type overrides (split one namespace across
rings), multi-assembly rules, lost-ancestor usings (a moved file loses
implicit access to its old parent namespace — e.g. Fallout.Common's
EnvironmentInfo/NotNull/Assert — so add an explicit using), and cref rewriting
(descend into doc-comment trivia so cref imports/FQNs follow the move).

Full suite green; 7 cake-migration Verify snapshots re-accepted (namespace-only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…lication ring (onion 4b follow-up)

Clears the Application→Infrastructure dependency that step 4b left tracked. The
impure tool-execution services now sit behind ports in Fallout.Application.Tooling
— IProcessExecutor, IToolPathResolver, IToolVersionResolver — resolved through a
ToolingServices locator. Fallout.Infrastructure.Tooling registers thin adapters
(forwarding to ProcessTasks / the resolvers) via a module initializer, so the
Application ring reaches Infrastructure only through the ports.

All Application-ring call sites are routed through the ports: ToolTasks.Run /
.ToolPath, ToolResolver, the tool wrappers (MSpec/DotCover/Xunit/Codecov/
PowerShell/Docker), Latest{NuGet,Npm}VersionAttribute, ToolRequirement version
lookups, Configure's DefaultLogOutput, CredentialStore, ToolRequirementService,
BuildManager's resolver config-push, InvokeBuildServerConfigurationGeneration,
and FalloutBuild.

ProcessExtensions (pure IProcess/Output helpers — AssertWaitForExit, StdToJson,
…) is reclassified from Infrastructure.Tooling back to Application.Tooling, where
the vocabulary that uses it lives (a step-4b misclassification). A
ModuleInitializerAttribute polyfill covers Fallout.Tooling's netstandard2.0 TFM.

New tests/Fallout.Architecture.Tests runs a NetArchTest fitness gate asserting
Fallout.Application.* has no dependency on Fallout.Infrastructure.* — green. It
lives in its own project so loading every ring's assembly cannot perturb the
AppDomain-scan/Verify tests in Fallout.Build.Tests.

Catch-all Fallout.Common.* code outside the Application ring (CI adapters, a few
attributes, the Cli composition root, MSBuildTasks) still reaches Infrastructure;
that folds in with step 5 as those namespaces get rings.

Full suite green; solution-generator snapshot re-accepted (new project entry).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ChrisonSimtian

Copy link
Copy Markdown
Collaborator Author

Collapsed into #359. The onion realignment now reviews as one PR (commit history kept). Nothing lost — #359 contains all of this work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking-change Change is breaking — requires major version bump per CLAUDE.md semver policy. target/2026 Targets the 2026 calendar-version line (current). See ADR-0004.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant