diff --git a/docs/architecture-tests.md b/docs/architecture-tests.md
index cf7c02f9..79dacbc4 100644
--- a/docs/architecture-tests.md
+++ b/docs/architecture-tests.md
@@ -31,7 +31,7 @@ Current rules:
| File | Rule(s) |
|---|---|
-| `LayeringSpecs` | `Core` / `Utilities` are foundations (no in-repo deps); utility satellites depend only on `Utilities`; `Tooling` / `ProjectModel` / `Build.Shared` don't reach upward; `Solution` is a thin facade; nothing depends on the `Cli` composition root; `Fallout.*` never depends on the `Nuke.*` shims. |
+| `LayeringSpecs` | `Core` / `Utilities` and the `Application.Tooling.Execution` / `Application.Tooling.Requirements` contract leaves are foundations (no in-repo deps); utility satellites depend only on `Utilities`; `Tooling` / `ProjectModel` / `Build.Shared` don't reach upward; `Solution` is a thin facade; nothing depends on the `Cli` composition root; `Fallout.*` never depends on the `Nuke.*` shims. |
| `PuritySpecs` | `Fallout.Core` takes no dependency on `System.IO`, `System.Diagnostics.Process`, `System.Console`, or Serilog (issue #88). |
| `NamingSpecs` | A type's namespace should be rooted at its assembly name. The main debt-bearing rule. |
diff --git a/fallout.slnx b/fallout.slnx
index 927adef1..d6058e85 100644
--- a/fallout.slnx
+++ b/fallout.slnx
@@ -26,6 +26,8 @@
+
+
diff --git a/src/Fallout.Application.Tooling.Execution/Fallout.Application.Tooling.Execution.csproj b/src/Fallout.Application.Tooling.Execution/Fallout.Application.Tooling.Execution.csproj
new file mode 100644
index 00000000..3750545b
--- /dev/null
+++ b/src/Fallout.Application.Tooling.Execution/Fallout.Application.Tooling.Execution.csproj
@@ -0,0 +1,8 @@
+
+
+
+ netstandard2.0;net10.0
+ Application-layer process-execution contract for Fallout tools — the IProcess abstraction and its Output model. No I/O, no logging. Targets netstandard2.0 so the source-generator and MSBuild-task layers can consume it.
+
+
+
diff --git a/src/Fallout.Tooling/IProcess.cs b/src/Fallout.Application.Tooling.Execution/IProcess.cs
similarity index 100%
rename from src/Fallout.Tooling/IProcess.cs
rename to src/Fallout.Application.Tooling.Execution/IProcess.cs
diff --git a/src/Fallout.Tooling/Output.cs b/src/Fallout.Application.Tooling.Execution/Output.cs
similarity index 100%
rename from src/Fallout.Tooling/Output.cs
rename to src/Fallout.Application.Tooling.Execution/Output.cs
diff --git a/src/Fallout.Tooling/OutputType.cs b/src/Fallout.Application.Tooling.Execution/OutputType.cs
similarity index 100%
rename from src/Fallout.Tooling/OutputType.cs
rename to src/Fallout.Application.Tooling.Execution/OutputType.cs
diff --git a/src/Fallout.Application.Tooling.Requirements/Fallout.Application.Tooling.Requirements.csproj b/src/Fallout.Application.Tooling.Requirements/Fallout.Application.Tooling.Requirements.csproj
new file mode 100644
index 00000000..7d7dd195
--- /dev/null
+++ b/src/Fallout.Application.Tooling.Requirements/Fallout.Application.Tooling.Requirements.csproj
@@ -0,0 +1,8 @@
+
+
+
+ netstandard2.0;net10.0
+ Application-layer tool-requirement marker interfaces — how a target declares the tools/packages it needs present before it runs. No I/O, no logging. Targets netstandard2.0 so the source-generator and MSBuild-task layers can consume it.
+
+
+
diff --git a/src/Fallout.Application.Tooling.Requirements/ToolRequirements.cs b/src/Fallout.Application.Tooling.Requirements/ToolRequirements.cs
new file mode 100644
index 00000000..7ecd57bd
--- /dev/null
+++ b/src/Fallout.Application.Tooling.Requirements/ToolRequirements.cs
@@ -0,0 +1,13 @@
+namespace Fallout.Common.Tooling;
+
+public interface IRequireTool;
+public interface IRequireToolWithVersion;
+
+
+public interface IRequirePathTool : IRequireTool;
+
+public interface IRequireNuGetPackage : IRequireTool, IRequireToolWithVersion;
+
+public interface IRequireNpmPackage : IRequireTool, IRequireToolWithVersion;
+
+public interface IRequireAptGetPackage : IRequireTool;
diff --git a/src/Fallout.Tooling/Fallout.Tooling.csproj b/src/Fallout.Tooling/Fallout.Tooling.csproj
index 2200aa63..1e871d08 100644
--- a/src/Fallout.Tooling/Fallout.Tooling.csproj
+++ b/src/Fallout.Tooling/Fallout.Tooling.csproj
@@ -5,6 +5,8 @@
+
+
diff --git a/src/Fallout.Tooling/ToolRequirement.cs b/src/Fallout.Tooling/ToolRequirement.cs
index 21e591c3..70e5fe3b 100644
--- a/src/Fallout.Tooling/ToolRequirement.cs
+++ b/src/Fallout.Tooling/ToolRequirement.cs
@@ -3,19 +3,6 @@
namespace Fallout.Common.Tooling;
-public interface IRequireTool;
-public interface IRequireToolWithVersion;
-
-
-public interface IRequirePathTool : IRequireTool;
-
-public interface IRequireNuGetPackage : IRequireTool, IRequireToolWithVersion;
-
-public interface IRequireNpmPackage : IRequireTool, IRequireToolWithVersion;
-
-public interface IRequireAptGetPackage : IRequireTool;
-
-
public class ToolRequirement;
public class PathToolRequirement(string pathExecutable) : ToolRequirement
diff --git a/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj b/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj
index 64047c19..f554c916 100644
--- a/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj
+++ b/tests/Fallout.Architecture.Specs/Fallout.Architecture.Specs.csproj
@@ -26,6 +26,8 @@
+
+
diff --git a/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs b/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs
index 6b56baf5..773d7529 100644
--- a/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs
+++ b/tests/Fallout.Architecture.Specs/FalloutArchitecture.cs
@@ -26,6 +26,8 @@ internal static class FalloutArchitecture
public const string UtilitiesTextJson = "Fallout.Utilities.Text.Json";
public const string UtilitiesTextYaml = "Fallout.Utilities.Text.Yaml";
public const string Solution = "Fallout.Solution";
+ public const string ToolingExecution = "Fallout.Application.Tooling.Execution";
+ public const string ToolingRequirements = "Fallout.Application.Tooling.Requirements";
public const string Tooling = "Fallout.Tooling";
public const string ProjectModel = "Fallout.ProjectModel";
public const string BuildShared = "Fallout.Build.Shared";
@@ -52,8 +54,8 @@ internal static class FalloutArchitecture
public static readonly string[] RuntimeLibraries =
[
Core, Utilities, UtilitiesIoCompression, UtilitiesIoGlobbing, UtilitiesNet, UtilitiesTextJson,
- UtilitiesTextYaml, Solution, Tooling, ProjectModel, BuildShared, Build, Common, Components, Cli,
- NukeCommon, NukeBuild, NukeComponents,
+ UtilitiesTextYaml, Solution, ToolingExecution, ToolingRequirements, Tooling, ProjectModel, BuildShared,
+ Build, Common, Components, Cli, NukeCommon, NukeBuild, NukeComponents,
];
private static readonly IReadOnlyDictionary Loaded = LoadProductionAssemblies();
diff --git a/tests/Fallout.Architecture.Specs/LayeringSpecs.cs b/tests/Fallout.Architecture.Specs/LayeringSpecs.cs
index 29a7f414..9e1ccd4e 100644
--- a/tests/Fallout.Architecture.Specs/LayeringSpecs.cs
+++ b/tests/Fallout.Architecture.Specs/LayeringSpecs.cs
@@ -42,6 +42,16 @@ public void Utility_satellite_depends_only_on_Fallout_Utilities(string satellite
$"{satellite} is a utility satellite and may depend only on Fallout.Utilities",
KnownViolations.None);
+ [Theory]
+ [InlineData(Arch.ToolingExecution)]
+ [InlineData(Arch.ToolingRequirements)]
+ public void Tooling_contract_leaf_is_a_foundation(string leaf) =>
+ Ratchet.Enforce(
+ Arch.TypesIn(leaf)
+ .Should().NotDependOnAny(Arch.TypesIn(Arch.AllAssembliesExcept(leaf))),
+ $"{leaf} is a pure Application-layer tooling-contract leaf and must reference no other Fallout/Nuke assembly",
+ KnownViolations.None);
+
[Fact]
public void Tooling_does_not_depend_on_upper_layers() =>
Ratchet.Enforce(