diff --git a/docs/reviews/2026-08-18-r3-test-truth-ledger.md b/docs/reviews/2026-08-18-r3-test-truth-ledger.md
index 5a9eefd0..76e7c722 100644
--- a/docs/reviews/2026-08-18-r3-test-truth-ledger.md
+++ b/docs/reviews/2026-08-18-r3-test-truth-ledger.md
@@ -1498,3 +1498,43 @@ Verification follows the proportionate R3 policy:
- a targeted scan finds source reads only in the two explicitly retained
whole-tree policy methods. The final inventory and twelve-assembly Release
gate remain deferred to closeout.
+
+## Batch AF create-authority drift-model contract replacement
+
+Batch AF converts the final approved test-model/source correspondence check.
+`CreateAuthorityDriftModelSourcePinTests` is renamed to
+`CreateAuthorityDriftModelContractTests`; its descriptive test method
+`HandCalledDriftProbe_StillModelsTheExecutorDrainAdvance` is retained. No
+product source changes and no test is removed.
+
+The replacement no longer regexes two Runtime files. It inspects compiled
+Runtime metadata and proves:
+
+- `ApplyWeenieDescriptionAction` applies the accepted description, refreshes
+ the canonical snapshot, advances create authority exactly once, and then
+ advances the executor baseline in semantic execution order;
+- `RegisterEntityCore` still has the named Boolean initial-residence input,
+ refreshes the ordinary existing-generation snapshot, and places the one
+ registration-time authority advance behind a conditional branch that skips
+ over the call; and
+- the Runtime assembly contains exactly those two call sites targeting
+ `RuntimeEntityDirectory.AdvanceCreateAuthority`: the modeled executor drain
+ and the gated ordinary registration route.
+
+This is the stale-model alarm the source regex intended, but it now survives
+comments, whitespace, local renames, and equivalent expression refactors.
+The expectation-item 6/8 probe comments in the hydration and supersession
+suites now say `metadata-pinned` and name the new contract class, preserving
+the rationale without leaving misleading source-pin references.
+
+Verification follows the proportionate R3 policy:
+
+- the contract plus its hydration and supersession behavior suites pass 90/90;
+- the complete `AcDream.App.Tests` hermetic lane passes 5,381/5,381 with zero
+ skips or failures;
+- the complete locked Release build covers all 44 projects with zero warnings
+ and zero errors; and
+- targeted scans find no source reader in the renamed contract and no stale
+ source-pin comment in the affected tests. With this batch, all 85 approved
+ replacements are implemented; final inventory reconciliation and the one
+ complete Release gate follow next.
diff --git a/tests/AcDream.App.Tests/Rendering/LiveEntityCreateSupersessionRecoveryTests.cs b/tests/AcDream.App.Tests/Rendering/LiveEntityCreateSupersessionRecoveryTests.cs
index 36b3e5e6..81d423be 100644
--- a/tests/AcDream.App.Tests/Rendering/LiveEntityCreateSupersessionRecoveryTests.cs
+++ b/tests/AcDream.App.Tests/Rendering/LiveEntityCreateSupersessionRecoveryTests.cs
@@ -83,7 +83,7 @@ public sealed class LiveEntityCreateSupersessionRecoveryTests
// covered.
// C3c-R1 F3: honest MODEL of the executor drain's advance
// (ApplyWeenieDescriptionAction — the sole production site,
- // source-pinned by CreateAuthorityDriftModelSourcePinTests); a
+ // metadata-pinned by CreateAuthorityDriftModelContractTests); a
// nested production OnCreate can no longer reach it —
// post-residence registration is description-only
// (RuntimeEntityObjectLifetime :660-665,
diff --git a/tests/AcDream.App.Tests/World/CreateAuthorityDriftModelContractTests.cs b/tests/AcDream.App.Tests/World/CreateAuthorityDriftModelContractTests.cs
new file mode 100644
index 00000000..381d12ac
--- /dev/null
+++ b/tests/AcDream.App.Tests/World/CreateAuthorityDriftModelContractTests.cs
@@ -0,0 +1,113 @@
+using System.Reflection;
+using System.Reflection.Emit;
+using AcDream.App.Tests.Architecture;
+using AcDream.Runtime.Entities;
+
+namespace AcDream.App.Tests.World;
+
+///
+/// The create-authority drift probes in the expectation-item 6/8 tests
+/// (`LiveEntityHydrationControllerTests` and
+/// `LiveEntityCreateSupersessionRecoveryTests`) hand-call
+/// as an honest model
+/// of the executor drain's advance: the sole production drain site that
+/// advances create authority for an existing incarnation. A nested production
+/// OnCreate cannot produce that drift because the initial-residence
+/// registration route branches around the ordinary registration-time advance.
+/// This compiled contract flags the model as stale if either route changes, so
+/// those probes can be re-derived from the new production boundary.
+///
+public sealed class CreateAuthorityDriftModelContractTests
+{
+ private const BindingFlags Declared = BindingFlags.Instance
+ | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic
+ | BindingFlags.DeclaredOnly;
+
+ [Fact]
+ public void HandCalledDriftProbe_StillModelsTheExecutorDrainAdvance()
+ {
+ MethodInfo drain = RequiredMethod(
+ typeof(RuntimeInitialCreateContinuationExecutor),
+ "ApplyWeenieDescriptionAction");
+ AssertCallOrder(
+ drain,
+ (typeof(RuntimeEntityDirectory),
+ nameof(RuntimeEntityDirectory.ApplyAcceptedWeenieDescriptionSnapshot)),
+ (typeof(RuntimeEntityDirectory), nameof(RuntimeEntityDirectory.RefreshSnapshot)),
+ (typeof(RuntimeEntityDirectory),
+ nameof(RuntimeEntityDirectory.AdvanceCreateAuthority)),
+ (typeof(RuntimeInitialCreateResidenceState), "AdvanceExecutorBaseline"));
+ Assert.Single(
+ CompiledCallGraph.Read(drain),
+ call => IsAuthorityAdvance(call.Target));
+
+ MethodInfo registration = RequiredMethod(
+ typeof(RuntimeEntityObjectLifetime),
+ "RegisterEntityCore");
+ ParameterInfo residenceFlag = Assert.Single(
+ registration.GetParameters(),
+ parameter => parameter.Name == "beginInitialResidence"
+ && parameter.ParameterType == typeof(bool));
+ Assert.NotNull(residenceFlag);
+
+ IReadOnlyList registrationCalls =
+ CompiledCallGraph.Read(registration);
+ CompiledCall refresh = Assert.Single(
+ registrationCalls,
+ call => call.Target.DeclaringType == typeof(RuntimeEntityDirectory)
+ && call.Target.Name == nameof(RuntimeEntityDirectory.RefreshSnapshot));
+ CompiledCall ordinaryAdvance = Assert.Single(
+ registrationCalls,
+ call => IsAuthorityAdvance(call.Target));
+ Assert.True(refresh.Offset < ordinaryAdvance.Offset);
+ Assert.Contains(
+ CompiledCallGraph.ReadBranches(registration),
+ branch => branch.OpCode.FlowControl == FlowControl.Cond_Branch
+ && branch.Offset > refresh.Offset
+ && branch.Offset < ordinaryAdvance.Offset
+ && branch.TargetOffset > ordinaryAdvance.Offset);
+
+ MethodBase[] productionCallSites =
+ MethodsCallingRuntimeAuthorityAdvance().ToArray();
+ Assert.Equal(2, productionCallSites.Length);
+ Assert.Contains(drain, productionCallSites);
+ Assert.Contains(registration, productionCallSites);
+ }
+
+ private static IEnumerable MethodsCallingRuntimeAuthorityAdvance() =>
+ typeof(RuntimeEntityObjectLifetime).Assembly.GetTypes()
+ .SelectMany(type => type.GetMethods(Declared)
+ .Cast()
+ .Concat(type.GetConstructors(Declared)))
+ .Where(method => method.GetMethodBody() is not null)
+ .Where(method => CompiledCallGraph.Read(method).Any(call =>
+ IsAuthorityAdvance(call.Target)));
+
+ private static bool IsAuthorityAdvance(MethodBase method) =>
+ method.DeclaringType == typeof(RuntimeEntityDirectory)
+ && method.Name == nameof(RuntimeEntityDirectory.AdvanceCreateAuthority);
+
+ private static MethodInfo RequiredMethod(Type owner, string name) =>
+ owner.GetMethod(
+ name,
+ BindingFlags.Instance | BindingFlags.Static
+ | BindingFlags.Public | BindingFlags.NonPublic)
+ ?? throw new MissingMethodException(owner.FullName, name);
+
+ private static void AssertCallOrder(
+ MethodBase method,
+ params (Type Type, string Method)[] expected)
+ {
+ IReadOnlyList calls = CompiledCallGraph.Read(method);
+ int cursor = -1;
+ foreach ((Type type, string name) in expected)
+ {
+ int found = Enumerable.Range(cursor + 1, calls.Count - cursor - 1)
+ .FirstOrDefault(index => calls[index].Target.DeclaringType == type
+ && calls[index].Target.Name == name, -1);
+ Assert.True(found > cursor,
+ $"Missing compiled edge after {cursor}: {type.FullName}.{name}.");
+ cursor = found;
+ }
+ }
+}
diff --git a/tests/AcDream.App.Tests/World/CreateAuthorityDriftModelSourcePinTests.cs b/tests/AcDream.App.Tests/World/CreateAuthorityDriftModelSourcePinTests.cs
deleted file mode 100644
index 68659a9a..00000000
--- a/tests/AcDream.App.Tests/World/CreateAuthorityDriftModelSourcePinTests.cs
+++ /dev/null
@@ -1,73 +0,0 @@
-using System.Text.RegularExpressions;
-
-namespace AcDream.App.Tests.World;
-
-///
-/// The create-authority drift probes in the expectation-item 6/8 tests
-/// (LiveEntityHydrationControllerTests + LiveEntityCreateSupersessionRecoveryTests)
-/// hand-call record.Canonical.AdvanceCreateAuthority() as an HONEST
-/// MODEL of the executor drain's advance — the SOLE remaining production
-/// site that advances create authority for an existing incarnation. A
-/// nested production OnCreate can no longer produce that drift:
-/// post-residence ExistingGeneration registration is description-only
-/// (RuntimeEntityObjectLifetime gates the advance on
-/// !beginInitialResidence) and ConsumeExecuted removes the
-/// completed residence entry at Released, closing the FIFO-adoption path
-/// (empirically confirmed: the restored nested-OnCreate probe produced no
-/// drift and no CreateSupersessionRecovery). This pin flags the model as
-/// STALE if the production site ever moves or loses the advance — the
-/// item 6/8 probes must be re-derived from wherever it goes.
-///
-public sealed class CreateAuthorityDriftModelSourcePinTests
-{
- [Fact]
- public void HandCalledDriftProbe_StillModelsTheExecutorDrainAdvance()
- {
- string executor = ReadRuntimeSource(
- "Entities",
- "RuntimeInitialCreateContinuationExecutor.cs");
-
- // Exactly one production advance, and it lives inside the
- // WeenieDescription drain stage the probes model.
- Assert.Single(
- Regex.Matches(executor, @"_entities\.AdvanceCreateAuthority\(")
- .Cast());
- Assert.Matches(
- new Regex(
- @"private bool ApplyWeenieDescriptionAction[\s\S]{0,6000}?"
- + @"_entities\.AdvanceCreateAuthority\(canonical\);"),
- executor);
-
- // The registration-time advance stays gated OFF the residence
- // route — the reason a nested production OnCreate cannot reach the
- // modeled drift.
- string lifetime = ReadRuntimeSource(
- "Entities",
- "RuntimeEntityObjectLifetime.cs");
- Assert.Matches(
- new Regex(
- @"if \(!beginInitialResidence\)\s*"
- + @"Entities\.AdvanceCreateAuthority\(retained\);"),
- lifetime);
- }
-
- private static string ReadRuntimeSource(params string[] relativePath)
- {
- DirectoryInfo? directory = new(AppContext.BaseDirectory);
- while (directory is not null)
- {
- if (File.Exists(Path.Combine(directory.FullName, "AcDream.slnx")))
- {
- return File.ReadAllText(Path.Combine(
- directory.FullName,
- "src",
- "AcDream.Runtime",
- Path.Combine(relativePath)));
- }
-
- directory = directory.Parent;
- }
-
- throw new DirectoryNotFoundException("Could not find AcDream.slnx.");
- }
-}
diff --git a/tests/AcDream.App.Tests/World/LiveEntityHydrationControllerTests.cs b/tests/AcDream.App.Tests/World/LiveEntityHydrationControllerTests.cs
index 8fcdceaf..56569778 100644
--- a/tests/AcDream.App.Tests/World/LiveEntityHydrationControllerTests.cs
+++ b/tests/AcDream.App.Tests/World/LiveEntityHydrationControllerTests.cs
@@ -1371,7 +1371,7 @@ public sealed class LiveEntityHydrationControllerTests
// honest MODEL of the executor drain's advance
// (RuntimeInitialCreateContinuationExecutor
// .ApplyWeenieDescriptionAction — the sole production site,
- // source-pinned by CreateAuthorityDriftModelSourcePinTests). A nested
+ // metadata-pinned by CreateAuthorityDriftModelContractTests). A nested
// production OnCreate can no longer reach it here:
// post-residence ExistingGeneration registration is
// description-only (RuntimeEntityObjectLifetime gates the
@@ -1509,7 +1509,7 @@ public sealed class LiveEntityHydrationControllerTests
// honest MODEL of the executor drain's advance
// (RuntimeInitialCreateContinuationExecutor
// .ApplyWeenieDescriptionAction — the sole production site,
- // source-pinned by CreateAuthorityDriftModelSourcePinTests). A nested
+ // metadata-pinned by CreateAuthorityDriftModelContractTests). A nested
// production OnCreate can no longer reach it here:
// post-residence ExistingGeneration registration is
// description-only (RuntimeEntityObjectLifetime gates the
@@ -1864,7 +1864,7 @@ public sealed class LiveEntityHydrationControllerTests
// revalidation guard stays covered.
// C3c-R1 F3: honest MODEL of the executor drain's advance
// (ApplyWeenieDescriptionAction — the sole production site,
- // source-pinned by CreateAuthorityDriftModelSourcePinTests); a
+ // metadata-pinned by CreateAuthorityDriftModelContractTests); a
// nested production OnCreate can no longer reach it —
// post-residence registration is description-only
// (RuntimeEntityObjectLifetime :660-665,
@@ -1983,7 +1983,7 @@ public sealed class LiveEntityHydrationControllerTests
// WeenieDescription stage; model that advance directly.
// C3c-R1 F3: honest MODEL of the executor drain's advance
// (ApplyWeenieDescriptionAction — the sole production site,
- // source-pinned by CreateAuthorityDriftModelSourcePinTests); a
+ // metadata-pinned by CreateAuthorityDriftModelContractTests); a
// nested production OnCreate can no longer reach it —
// post-residence registration is description-only
// (RuntimeEntityObjectLifetime :660-665,
@@ -2019,7 +2019,7 @@ public sealed class LiveEntityHydrationControllerTests
// (AdvanceCreateAuthority), not at registration; model it directly.
// C3c-R1 F3: honest MODEL of the executor drain's advance
// (ApplyWeenieDescriptionAction — the sole production site,
- // source-pinned by CreateAuthorityDriftModelSourcePinTests); a nested
+ // metadata-pinned by CreateAuthorityDriftModelContractTests); a nested
// production OnCreate can no longer reach it — post-residence
// registration is description-only (RuntimeEntityObjectLifetime
// :660-665, !beginInitialResidence gate) and ConsumeExecuted