diff --git a/Directory.Build.props b/Directory.Build.props
index 0c8259874..afdfc3ac1 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -69,4 +69,22 @@
+
+
+ <_FalloutOuterApiAssemblies>;Fallout.Common;Fallout.Build;Fallout.Build.Shared;Fallout.Components;Fallout.Core;Fallout.Tooling;Fallout.ProjectModel;Fallout.Utilities;Fallout.Utilities.IO.Compression;Fallout.Utilities.IO.Globbing;Fallout.Utilities.Net;Fallout.Utilities.Text.Json;Fallout.Utilities.Text.Yaml;Fallout.Solution;Fallout.NuGet.Analysis;Fallout.Tooling.Generator;Nuke.Common;Nuke.Build;Nuke.Components;
+ true
+
+
+
+
+
+
+
+
diff --git a/Directory.Packages.props b/Directory.Packages.props
index 644d92315..089b70214 100644
--- a/Directory.Packages.props
+++ b/Directory.Packages.props
@@ -13,6 +13,7 @@
+
diff --git a/docs/api-encapsulation-audit.md b/docs/api-encapsulation-audit.md
new file mode 100644
index 000000000..9690d4bfb
--- /dev/null
+++ b/docs/api-encapsulation-audit.md
@@ -0,0 +1,52 @@
+# API encapsulation audit
+
+Companion to the `[PublicAPI]` annotation pass (PR #6). Stamping `[assembly: PublicAPI]`
+on the outer (consumer-facing) layer declares each assembly's **entire** public surface as
+intentional API. This audit records public types that are `public` by accident and the
+decisions taken. (GitHub issues are disabled on this fork, so this doc is the tracker.)
+
+> **Caveat that drives every call here:** repo-only grep is insufficient for a framework.
+> A type with zero in-repo references can be internal plumbing **or** an extensibility
+> surface only external consumers touch. Verify intent (NUKE history, `public`/`protected
+> virtual` reachability) before flipping anything in an outer assembly.
+
+## Tier 1 — done (non-breaking, inner-layer assemblies)
+
+Flipped to `internal` in PR #6 (no consumer-facing API in these assemblies):
+
+| Type | Assembly | Note |
+|---|---|---|
+| `TaskItemExtensions` | `Fallout.MSBuildTasks` | not packed; in-assembly helper |
+| `CodeAnalysisExtensions` | `Fallout.SourceGenerators` | not packed; in-assembly helper |
+| `Migration` + nested `Summary` | `Fallout.Migrate` | tool exe; used only by `Program` + tests (IVT). `Migration` internalized with `Summary` to keep accessibility consistent (CS0050) |
+
+## Tier 2 — deferred (breaking; batch to the yearly major cut)
+
+High-confidence implementation details, but in **outer/packed** assemblies — flipping is
+breaking, so it follows the breaking-change flow (gate behind `[Experimental(...)]` or hold
+on a topic branch; CHANGELOG + `breaking-change` label at PR time).
+
+**`Fallout.Build`**
+- `InMemorySink` (`Logging.cs`) — nested log sink, in-assembly only
+- `ConsoleUtility` (`Utilities/ConsoleUtility.cs`) — console I/O helper, in-assembly only
+- `Terminal` + `Terminal.Rider` / `Terminal.VSCode` / `Terminal.VisualStudio` (`Terminal.cs`) — env-detection markers
+
+**`Fallout.Persistence.Solution`** (csproj already documents intent to narrow these)
+- `StringTable`, `PathShim`, `Extensions`
+
+Before flipping: confirm no external consumer usage and no extensibility reachability for each.
+
+## Tier 3 — keep public (intentional extensibility; not candidates)
+
+The ~49 CI Configuration types (`*Step` / `*Trigger` / `*Job` / `*Parameter` / `*Dependency`
++ abstract bases under `Fallout.Common/CI/**/Configuration/`) and abstract attribute bases
+(`FileSystemGlobbingAttributeBase`, `AzureKeyVaultAttributeBase`). These are unreferenced
+in-repo precisely *because* only external consumers use them: consumers subclass e.g.
+`GitHubActionsAttribute`, override `public override ConfigurationEntity GetConfiguration(...)`,
+and build these objects. The blanket `[assembly: PublicAPI]` is correct for them — it stops
+Rider flagging them as unused. **No action.**
+
+## Clean
+
+`Fallout.Components`, `Fallout.Core`, `Fallout.Tooling`, `Fallout.ProjectModel`, all
+`Fallout.Utilities*`, and the `Fallout.Solution` facade audited clean — no accidental publics.
diff --git a/src/Fallout.MSBuildTasks/TaskItemExtensions.cs b/src/Fallout.MSBuildTasks/TaskItemExtensions.cs
index 9ec6b435f..f8db05d03 100644
--- a/src/Fallout.MSBuildTasks/TaskItemExtensions.cs
+++ b/src/Fallout.MSBuildTasks/TaskItemExtensions.cs
@@ -4,7 +4,7 @@
namespace Fallout.MSBuildTasks;
-public static class TaskItemExtensions
+internal static class TaskItemExtensions
{
public static string GetMetadataOrNull(this ITaskItem taskItem, string metdataName)
{
diff --git a/src/Fallout.Migrate/Migration.cs b/src/Fallout.Migrate/Migration.cs
index 939b849f8..26fd45b21 100644
--- a/src/Fallout.Migrate/Migration.cs
+++ b/src/Fallout.Migrate/Migration.cs
@@ -5,7 +5,7 @@
namespace Fallout.Migrate;
-public sealed class Migration
+internal sealed class Migration
{
private readonly string _rootDirectory;
private readonly bool _dryRun;
@@ -144,7 +144,7 @@ private string RelativePath(string absolute) =>
private void Log(string line) => _log.WriteLine(line);
- public sealed class Summary
+ internal sealed class Summary
{
public int FilesChanged { get; set; }
public int EditCount { get; set; }
diff --git a/src/Fallout.SourceGenerators/CodeAnalysisExtensions.cs b/src/Fallout.SourceGenerators/CodeAnalysisExtensions.cs
index a00c38fff..c96750a9c 100644
--- a/src/Fallout.SourceGenerators/CodeAnalysisExtensions.cs
+++ b/src/Fallout.SourceGenerators/CodeAnalysisExtensions.cs
@@ -6,7 +6,7 @@
namespace Fallout.SourceGenerators;
-public static class CodeAnalysisExtensions
+internal static class CodeAnalysisExtensions
{
public static IEnumerable GetAllNamespaces(this INamespaceSymbol namespaceSymbol)
{