diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/VirtualTags/VirtualTagActor.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/VirtualTags/VirtualTagActor.cs
new file mode 100644
index 0000000..ffa5adb
--- /dev/null
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/VirtualTags/VirtualTagActor.cs
@@ -0,0 +1,41 @@
+using Akka.Actor;
+using Akka.Event;
+using ZB.MOM.WW.OtOpcUa.Commons.Types;
+
+namespace ZB.MOM.WW.OtOpcUa.Runtime.VirtualTags;
+
+///
+/// Wraps a single virtual-tag expression. Receives dependency-tag updates, recomputes the
+/// expression, and publishes the result to OpcUaPublishActor.
+///
+/// Engine wiring (compile expression via VirtualTagEngine, manage subscriptions,
+/// emit AttributeValueUpdate) is staged for follow-up F8. This skeleton compiles + has
+/// a basic message contract so DriverHostActor can spawn it as a child.
+///
+public sealed class VirtualTagActor : ReceiveActor
+{
+ public sealed record DependencyValueChanged(string TagId, object? Value, DateTime TimestampUtc);
+ public sealed record EvaluationResult(string VirtualTagId, object? Value, DateTime TimestampUtc, CorrelationId Correlation);
+
+ private readonly string _virtualTagId;
+ private readonly string _expression;
+ private readonly ILoggingAdapter _log = Context.GetLogger();
+ private readonly Dictionary _dependencies = new(StringComparer.Ordinal);
+
+ public static Props Props(string virtualTagId, string expression) =>
+ Akka.Actor.Props.Create(() => new VirtualTagActor(virtualTagId, expression));
+
+ public VirtualTagActor(string virtualTagId, string expression)
+ {
+ _virtualTagId = virtualTagId;
+ _expression = expression;
+
+ Receive(msg =>
+ {
+ _dependencies[msg.TagId] = msg.Value;
+ // Engine wiring (F8): VirtualTagEngine.Evaluate(_expression, _dependencies) → publish.
+ _log.Debug("VirtualTag {Id}: dependency {Tag}={Value} buffered (eval staged for F8)",
+ _virtualTagId, msg.TagId, msg.Value);
+ });
+ }
+}
diff --git a/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/VirtualTags/VirtualTagActorTests.cs b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/VirtualTags/VirtualTagActorTests.cs
new file mode 100644
index 0000000..d75e760
--- /dev/null
+++ b/tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests/VirtualTags/VirtualTagActorTests.cs
@@ -0,0 +1,22 @@
+using Akka.Actor;
+using Shouldly;
+using Xunit;
+using ZB.MOM.WW.OtOpcUa.Runtime.Tests.Harness;
+using ZB.MOM.WW.OtOpcUa.Runtime.VirtualTags;
+
+namespace ZB.MOM.WW.OtOpcUa.Runtime.Tests.VirtualTags;
+
+public sealed class VirtualTagActorTests : RuntimeActorTestBase
+{
+ [Fact]
+ public void DependencyValueChanged_is_accepted_and_actor_stays_alive()
+ {
+ var actor = Sys.ActorOf(VirtualTagActor.Props("vt-1", "a + b"));
+ Watch(actor);
+ actor.Tell(new VirtualTagActor.DependencyValueChanged("tag-a", 10, DateTime.UtcNow));
+ actor.Tell(new VirtualTagActor.DependencyValueChanged("tag-b", 20, DateTime.UtcNow));
+
+ // No crash, no termination.
+ ExpectNoMsg(TimeSpan.FromMilliseconds(200));
+ }
+}