diff --git a/src/MeshWeaver.Approvals/GraphLegacySurface.cs b/src/MeshWeaver.Approvals/GraphLegacySurface.cs
new file mode 100644
index 0000000000..1b7198f169
--- /dev/null
+++ b/src/MeshWeaver.Approvals/GraphLegacySurface.cs
@@ -0,0 +1,38 @@
+using MeshWeaver.Messaging;
+
+// 🚨 Deliberately the GRAPH namespace. This file restores the EXACT public surface in-mesh
+// sources compiled against before the Approvals extraction (#1654): `MeshWeaver.Graph.
+// ApprovalExtensions` with `AddApprovals(this MessageHubConfiguration)`. The extraction moved
+// the class to the MeshWeaver.Approvals namespace and narrowed the public entry point to
+// MeshBuilder — deleting a public framework surface that the compiler cannot see the callers
+// of (AGENTS.md: in-mesh source is invisible to `dotnet build`). On the first image that
+// shipped the extraction, 11 NodeTypes across the SocialMedia and UWDeepfield partitions
+// regressed to CompileError (CS1061 AddApprovals / CS0103 ApprovalExtensions) and the bake
+// gate refused readiness mesh-wide — the same symbol that caused the #683-era outage.
+// Node content lives in OTHER repos and in production databases, so the platform keeps the
+// surface; content can migrate to the module registration at its own pace.
+namespace MeshWeaver.Graph;
+
+///
+/// Legacy Approvals surface for in-mesh sources written before the Approvals module extraction
+/// (#1654). The real registration lives in and is
+/// applied to every per-node hub when the module is installed — so this entry point only fills
+/// the gap on hubs the module has not configured, and is a no-op everywhere else.
+///
+public static class ApprovalExtensions
+{
+ /// The sub-partition name where approvals are stored.
+ public const string ApprovalPartition = Approvals.ApprovalExtensions.ApprovalPartition;
+
+ ///
+ /// Adds approval support to this hub configuration. Idempotent: when the Approvals module
+ /// (or an earlier call) already configured the hub — detected via the
+ /// marker (,
+ /// which remains the one HasApprovals surface) — the configuration is returned
+ /// unchanged.
+ ///
+ public static MessageHubConfiguration AddApprovals(this MessageHubConfiguration configuration)
+ => ApprovalsMarkerExtensions.HasApprovals(configuration)
+ ? configuration
+ : Approvals.ApprovalExtensions.ConfigureHub(configuration);
+}
diff --git a/src/MeshWeaver.Documentation/Data/WhatsNew/2026-08-16-approvals-legacy-surface.md b/src/MeshWeaver.Documentation/Data/WhatsNew/2026-08-16-approvals-legacy-surface.md
new file mode 100644
index 0000000000..ee2676c362
--- /dev/null
+++ b/src/MeshWeaver.Documentation/Data/WhatsNew/2026-08-16-approvals-legacy-surface.md
@@ -0,0 +1,15 @@
+---
+Name: Approvals keep working in existing content
+Category: Fix
+Description: Content that wires up approvals with the original AddApprovals call compiles again — the surface was restored after the Approvals module extraction removed it.
+Icon: Sparkle
+Order: -20260816
+---
+
+# Approvals keep working in existing content
+
+The Approvals feature recently moved into its own module. That move accidentally removed the
+original programming surface that existing content in several workspaces still uses, so those
+pages stopped compiling on the newest version and the update was held back by the platform's
+safety gate. The original surface is restored (and now covered by a test), so existing content
+keeps working unchanged while new content can use the module directly.
diff --git a/test/MeshWeaver.Graph.Test/ApprovalModuleTest.cs b/test/MeshWeaver.Graph.Test/ApprovalModuleTest.cs
index e1b9fd0076..95f5ee44ad 100644
--- a/test/MeshWeaver.Graph.Test/ApprovalModuleTest.cs
+++ b/test/MeshWeaver.Graph.Test/ApprovalModuleTest.cs
@@ -54,7 +54,10 @@ public void ConfigureHub_SetsTheApprovalsEnabledMarker_TheOverviewGuardReads()
// The markdown overview embeds its Approvals section only when HasApprovals() is true —
// the marker stays in Graph, the module sets it. One drifting apart of the two would
// silently blank the section, so pin the pair here.
- var configuration = ApprovalExtensions.ConfigureHub(
+ // Fully qualified: the legacy MeshWeaver.Graph.ApprovalExtensions (the restored in-mesh
+ // surface) shadows the module class from this namespace, and only the module class has
+ // the internal ConfigureHub.
+ var configuration = Approvals.ApprovalExtensions.ConfigureHub(
new MessageHubConfiguration(null, new Address("test", "approvals")));
configuration.HasApprovals().Should().BeTrue();
}
diff --git a/test/MeshWeaver.Hosting.Monolith.Test/ApprovalsLegacySurfaceCompileTest.cs b/test/MeshWeaver.Hosting.Monolith.Test/ApprovalsLegacySurfaceCompileTest.cs
new file mode 100644
index 0000000000..f12dc63c90
--- /dev/null
+++ b/test/MeshWeaver.Hosting.Monolith.Test/ApprovalsLegacySurfaceCompileTest.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Linq;
+using System.Reactive.Linq;
+using System.Threading.Tasks;
+using MeshWeaver.Graph;
+using MeshWeaver.Graph.Configuration;
+using MeshWeaver.Hosting.Monolith.TestBase;
+using MeshWeaver.Mesh;
+using MeshWeaver.Mesh.Services;
+using Microsoft.Extensions.DependencyInjection;
+using Xunit;
+
+namespace MeshWeaver.Hosting.Monolith.Test;
+
+///
+/// Pins the LEGACY Approvals surface for in-mesh sources: MeshWeaver.Graph.ApprovalExtensions
+/// with AddApprovals(this MessageHubConfiguration). The Approvals extraction (#1654) moved
+/// the class to the MeshWeaver.Approvals namespace and narrowed the public entry to MeshBuilder —
+/// and the first image shipping that regressed 11 NodeTypes across the SocialMedia and UWDeepfield
+/// partitions to CompileError (CS1061 AddApprovals / CS0103 ApprovalExtensions),
+/// which the bake gate answered by refusing readiness mesh-wide. In-mesh source is invisible to
+/// dotnet build, so THIS test is the compiler for those callers: it compiles a NodeType
+/// whose Source uses the exact legacy shape and must stay green for as long as any partition's
+/// content does.
+///
+public class ApprovalsLegacySurfaceCompileTest(ITestOutputHelper output) : MonolithMeshTestBase(output)
+{
+ private IMeshService MeshService => Mesh.ServiceProvider.GetRequiredService();
+
+ /// Same shape as CellSurfaceScriptingSeamTest.CreateAndCompile.
+ private async Task CreateAndCompile(
+ string nodeTypePath,
+ NodeTypeDefinition definition,
+ params (string Name, string Code)[] sources)
+ {
+ var typeNode = MeshNode.FromPath(nodeTypePath) with
+ {
+ Name = nodeTypePath.Split('/').Last(),
+ NodeType = MeshNode.NodeTypePath,
+ Content = definition,
+ State = MeshNodeState.Active
+ };
+
+ await MeshService.CreateNode(typeNode)
+ .SelectMany(_ => sources
+ .Select(source => MeshService.CreateNode(new MeshNode(source.Name, $"{nodeTypePath}/Source")
+ {
+ NodeType = "Code",
+ Name = source.Name,
+ Content = new CodeConfiguration { Code = source.Code, Language = "csharp" },
+ State = MeshNodeState.Active
+ }))
+ .Aggregate(Observable.Return(null), (chain, next) =>
+ chain.SelectMany(_ => next.Select(n => (MeshNode?)n))))
+ .Should().Within(30.Seconds()).Emit();
+
+ var node = await Mesh.GetMeshNodeStream(nodeTypePath)
+ .Should().Within(60.Seconds())
+ .Match(n => n?.Content is NodeTypeDefinition d
+ && d.CompilationStatus is CompilationStatus.Ok or CompilationStatus.Error);
+ return (NodeTypeDefinition)node.Content!;
+ }
+
+ [Fact(Timeout = 120_000)]
+ public async Task LegacyApprovalsSurface_StaysCompilableFromNodeSource()
+ {
+ // The EXACT caller shape live in the SocialMedia and UWDeepfield partitions:
+ // `using MeshWeaver.Graph;` + `configuration.AddApprovals()` + the class referenced
+ // by its short name (the partition-path const). Both failed on the extraction image.
+ var def = await CreateAndCompile(
+ "type/LegacyApprovals",
+ new NodeTypeDefinition
+ {
+ Configuration = "config => config"
+ },
+ ("wiring", """
+ using MeshWeaver.Graph;
+ using MeshWeaver.Messaging;
+
+ public static class LegacyApprovalsWiring
+ {
+ public const string Partition = ApprovalExtensions.ApprovalPartition;
+
+ public static MessageHubConfiguration Wire(MessageHubConfiguration configuration)
+ => configuration.AddApprovals();
+ }
+ """));
+
+ def.CompilationStatus.Should().Be(CompilationStatus.Ok,
+ "the legacy MeshWeaver.Graph Approvals surface has in-mesh callers the compiler "
+ + $"cannot see — it must never disappear again; error: {def.CompilationError}");
+ }
+}