diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaNodeWriteGateway.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaNodeWriteGateway.cs
new file mode 100644
index 00000000..4469005f
--- /dev/null
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Commons/OpcUa/IOpcUaNodeWriteGateway.cs
@@ -0,0 +1,36 @@
+namespace ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
+
+///
+/// Reverse-path gateway for an inbound OPC UA operator write to a writable equipment-tag node.
+/// The node manager calls fire-and-forget from its OnWriteValue handler
+/// (which runs under the node-manager Lock, so the call MUST return promptly — it kicks off an
+/// asynchronous route and the Task completes later) and uses the resolved
+/// to self-correct the node on failure.
+///
+public interface IOpcUaNodeWriteGateway
+{
+ /// Route a write of to the driver backing node
+ /// ; the returned task resolves with the device-write outcome.
+ /// The folder-scoped equipment-variable node id being written.
+ /// The value the client wrote.
+ /// Cancellation token.
+ /// A task resolving to the device-write outcome.
+ Task WriteAsync(string nodeId, object? value, CancellationToken ct);
+}
+
+/// Outcome of routing an inbound node write to the backing driver.
+/// True when the driver accepted the write.
+/// Failure detail when is false; null on success.
+public readonly record struct NodeWriteOutcome(bool Success, string? Reason);
+
+/// No-op gateway: every write resolves to "writes unavailable" (matches the legacy
+/// no-router-wired BadNotWritable). The default before the host wires the real gateway.
+public sealed class NullOpcUaNodeWriteGateway : IOpcUaNodeWriteGateway
+{
+ /// The shared singleton instance.
+ public static readonly NullOpcUaNodeWriteGateway Instance = new();
+ private NullOpcUaNodeWriteGateway() { }
+ ///
+ public Task WriteAsync(string nodeId, object? value, CancellationToken ct) =>
+ Task.FromResult(new NodeWriteOutcome(false, "writes unavailable"));
+}
diff --git a/tests/Core/ZB.MOM.WW.OtOpcUa.Commons.Tests/OpcUa/NullOpcUaNodeWriteGatewayTests.cs b/tests/Core/ZB.MOM.WW.OtOpcUa.Commons.Tests/OpcUa/NullOpcUaNodeWriteGatewayTests.cs
new file mode 100644
index 00000000..dc7a2899
--- /dev/null
+++ b/tests/Core/ZB.MOM.WW.OtOpcUa.Commons.Tests/OpcUa/NullOpcUaNodeWriteGatewayTests.cs
@@ -0,0 +1,16 @@
+using Shouldly;
+using Xunit;
+using ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
+
+namespace ZB.MOM.WW.OtOpcUa.Commons.Tests.OpcUa;
+
+public class NullOpcUaNodeWriteGatewayTests
+{
+ [Fact]
+ public async Task NullGateway_returns_writes_unavailable()
+ {
+ var outcome = await NullOpcUaNodeWriteGateway.Instance.WriteAsync("ns=2;s=x", 1, TestContext.Current.CancellationToken);
+ outcome.Success.ShouldBeFalse();
+ outcome.Reason.ShouldBe("writes unavailable");
+ }
+}