diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/IScriptLogPublisher.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/IScriptLogPublisher.cs
index 010316cf..fb261769 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/IScriptLogPublisher.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/IScriptLogPublisher.cs
@@ -4,9 +4,9 @@ namespace ZB.MOM.WW.OtOpcUa.Core.Scripting;
///
/// Abstraction over the mechanism that publishes records
-/// to a downstream consumer (e.g. an Akka DPS script-logs topic). Implemented by
-/// the concrete DPS publisher in a later task; the sink depends only on this interface
-/// so the Core.Scripting layer has no Akka dependency.
+/// to a downstream consumer (e.g. an Akka DPS script-logs topic). The concrete
+/// implementation is DpsScriptLogPublisher (Runtime project), wired via DI; the
+/// sink depends only on this interface so the Core.Scripting layer has no Akka dependency.
///
public interface IScriptLogPublisher
{
diff --git a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/ScriptLogTopicSink.cs b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/ScriptLogTopicSink.cs
index 026d5d33..fe9e7f3e 100644
--- a/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/ScriptLogTopicSink.cs
+++ b/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/ScriptLogTopicSink.cs
@@ -7,7 +7,7 @@ namespace ZB.MOM.WW.OtOpcUa.Core.Scripting;
///
/// Serilog sink that converts each script into a
/// and forwards it to an .
-/// The publisher implementation (supplied by a later task) routes the entry onto the
+/// The production publisher (DpsScriptLogPublisher) routes the entry onto the
/// Akka DPS script-logs topic so the live Script-log Admin UI page can display it.
///
///
diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/Browse/GalaxyDiscoverer.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/Browse/GalaxyDiscoverer.cs
index d07c79e3..7874c46a 100644
--- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/Browse/GalaxyDiscoverer.cs
+++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/Browse/GalaxyDiscoverer.cs
@@ -17,9 +17,9 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browse;
/// - Folder per gobject; variables placed inside their owner folder.
/// - Variable's full reference = tag_name.attribute_name — the format MXAccess
/// expects for read/write addressing (translated from the contained-name browse path).
-/// - Hierarchy is rendered flat (one folder per gobject under the driver root) for
-/// this PR. PR 4.W's address-space wiring revisits whether to nest under
-/// parent_gobject_id for a true tree shape.
+/// - Hierarchy is rendered flat (one folder per gobject under the driver root).
+/// Nesting under parent_gobject_id for a true tree shape is not implemented;
+/// the flat layout is the current shipping behaviour.
///
///
public sealed class GalaxyDiscoverer
diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriver.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriver.cs
index c8847278..a3f098da 100644
--- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriver.cs
+++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriver.cs
@@ -863,12 +863,12 @@ public sealed class GalaxyDriver
if (_dataWriter is null)
{
// Mirror the IReadable fallback: production write path runs on top of
- // GalaxyMxSession (PR 4.2 skeleton; PR 4.4 wires the live session). Until
- // that lands, deployments selecting Galaxy:Backend=mxgateway can't write.
+ // GatewayGalaxyDataWriter, which is wired by InitializeAsync when the gRPC session
+ // connects. This guard fires only if the driver is called before initialization completes.
throw new NotSupportedException(
"GalaxyDriver.WriteAsync requires GatewayGalaxyDataWriter wired against a connected " +
- "GalaxyMxSession (PR 4.4). Until that lands, route writes through the legacy-host " +
- "backend (Galaxy:Backend=legacy-host).");
+ "GalaxyMxSession. Call InitializeAsync and wait for a successful connection before " +
+ "issuing writes.");
}
return _dataWriter.WriteAsync(writes, ResolveSecurity, cancellationToken);
@@ -887,7 +887,7 @@ public sealed class GalaxyDriver
{
throw new NotSupportedException(
"GalaxyDriver.SubscribeAsync requires a connected GalaxyMxSession + GatewayGalaxySubscriber. " +
- "PR 4.W wires the production session; until then route subscriptions through the legacy-host backend.");
+ "Call InitializeAsync and wait for a successful connection before subscribing.");
}
var pump = EnsureEventPumpStarted();
@@ -1103,7 +1103,7 @@ public sealed class GalaxyDriver
{
throw new NotSupportedException(
"GalaxyDriver.AcknowledgeAsync requires GatewayGalaxyAlarmAcknowledger wired against a connected " +
- "GalaxyMxSession (PR B.2). InitializeAsync must run before alarm acknowledgements can flow.");
+ "GalaxyMxSession. InitializeAsync must complete successfully before alarm acknowledgements can flow.");
}
// Acks are issued one-by-one — the gateway RPC accepts a single alarm
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/ScriptAnalysis/ScriptAnalysisService.cs b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/ScriptAnalysis/ScriptAnalysisService.cs
index 35fa8ebf..97acb700 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/ScriptAnalysis/ScriptAnalysisService.cs
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/ScriptAnalysis/ScriptAnalysisService.cs
@@ -18,9 +18,10 @@ namespace ZB.MOM.WW.OtOpcUa.AdminUI.ScriptAnalysis;
/// context.
///
///
-/// Public methods are placeholders returning empty results — later tasks fill in each
-/// capability via TDD. The shared seam + the offset helpers are
-/// the load-bearing part every later capability reuses; keep them even while unused.
+/// All capabilities are fully implemented: Diagnose, Complete, Hover, SignatureHelp, and Format
+/// are wired and backed by the real Roslyn document/analysis pipeline. Only InlayHints is
+/// intentionally a no-op (empty list) — the endpoint exists for future use but the feature is
+/// not implemented.
///
public sealed class ScriptAnalysisService
{
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs
index f272c3cb..462e7b65 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Drivers/DriverHostActor.cs
@@ -41,8 +41,10 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Drivers;
/// - Stale — ConfigDb unreachable on bootstrap. Background reconnect loop tries to advance.
///
///
-/// Children (DriverInstance/VirtualTag/etc.) are spawned in Phase 6 follow-up tasks (41-44).
-/// For now the dispatch handler treats the apply as a no-op and writes the ACK back.
+/// Children (DriverInstance/VirtualTag/etc.) are fully wired: DispatchDeployment drives
+/// which runs the spawn-plan via ,
+/// maintains the FullName→NodeId live-value routing map, and forwards results to the
+/// OPC UA publish actor via ForwardToMux.
///
public sealed class DriverHostActor : ReceiveActor, IWithTimers
{
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/OpcUa/OpcUaPublishActor.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/OpcUa/OpcUaPublishActor.cs
index abde4509..e5c5f227 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/OpcUa/OpcUaPublishActor.cs
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/OpcUa/OpcUaPublishActor.cs
@@ -243,13 +243,14 @@ public sealed class OpcUaPublishActor : ReceiveActor
_applier.MaterialiseScriptedAlarms(composition);
// Equipment-namespace tags get their own pass: ensures each signal's Variable (and any
// FolderPath sub-folder) exists under its already-materialised equipment folder so
- // clients can browse them. Live values arrive in a later milestone; until then the
- // variables show BadWaitingForInitialData.
+ // clients can browse them. Live values are pushed by DriverHostActor.ForwardToMux after
+ // each subscription cycle; variables show BadWaitingForInitialData only until the first
+ // publish interval fires.
_applier.MaterialiseEquipmentTags(composition);
// Equipment-namespace VirtualTags get their own pass right after the equipment tags:
// ensures each computed signal's Variable (and any FolderPath sub-folder) exists under its
- // equipment folder with a folder-scoped NodeId. The VirtualTagActor fills live values in a
- // later milestone; until then the variables show BadWaitingForInitialData (same as tags).
+ // equipment folder with a folder-scoped NodeId. VirtualTagHostActor.OnResult pushes live
+ // values once the first dependency update arrives; until then variables show BadWaitingForInitialData.
_applier.MaterialiseEquipmentVirtualTags(composition);
OtOpcUaTelemetry.OpcUaSinkWrite.Add(1, new KeyValuePair("kind", "rebuild"));
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Security/ServiceCollectionExtensions.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Security/ServiceCollectionExtensions.cs
index 2eba6ddd..c64e518f 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.Security/ServiceCollectionExtensions.cs
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.Security/ServiceCollectionExtensions.cs
@@ -62,10 +62,11 @@ public static class ServiceCollectionExtensions
// driver path) ends up with exactly one descriptor regardless of registration order.
services.TryAddSingleton();
- // Shared ZB.MOM.WW.Auth group→role mapper seam (Task 1.1, additive). Wraps the existing
- // RoleMapper.Map + RoleMapper.Merge logic; the login flow is rewired to consume it in a
- // later task. Scoped to match ILdapGroupRoleMappingService (DbContext-backed, registered
- // Scoped) — a singleton here would capture the scoped DB service.
+ // Shared ZB.MOM.WW.Auth group→role mapper seam. Wraps the existing RoleMapper.Map +
+ // RoleMapper.Merge logic; consumed by AuthEndpoints.cs (/auth/login) and by
+ // LdapOpcUaUserAuthenticator (OPC UA UserName session auth). Scoped to match
+ // ILdapGroupRoleMappingService (DbContext-backed, registered Scoped) — a singleton here
+ // would capture the scoped DB service.
services.TryAddScoped, OtOpcUaGroupRoleMapper>();
services.AddDataProtection()