diff --git a/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Tests/AbLegacyArrayWriteSupportParityTests.cs b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Tests/AbLegacyArrayWriteSupportParityTests.cs
new file mode 100644
index 00000000..acae0cdd
--- /dev/null
+++ b/tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Tests/AbLegacyArrayWriteSupportParityTests.cs
@@ -0,0 +1,58 @@
+using Shouldly;
+using Xunit;
+using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
+
+namespace ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Tests;
+
+///
+/// Pins 's AbLegacy row against the REAL array encoder
+/// (), the same way the Modbus and S7 parity tests do: for every element
+/// type the server must advertise an array node writable exactly when the driver encodes it.
+///
+///
+/// ⚠️ SKIPPED until follow-up F1 lands: the driver gained an array encoder in this lane (review 07 U10), but
+/// (Core.Abstractions, not owned by the AbLegacy lane) still lists AbLegacy as
+/// scalar-only, so every AbLegacy array node stays read-only and the encoder is unreachable from OPC UA. When F1
+/// adds the row, delete the Skip; this test then holds the table and the encoder together.
+///
+[Trait("Category", "Unit")]
+public sealed class AbLegacyArrayWriteSupportParityTests
+{
+ public static TheoryData AllTypes() => new(Enum.GetValues());
+
+ private static string AddressFor(AbLegacyDataType t) => t switch
+ {
+ AbLegacyDataType.Float => "F8:0",
+ AbLegacyDataType.Long => "L9:0",
+ AbLegacyDataType.Bit => "B3:0",
+ AbLegacyDataType.String => "ST9:0",
+ AbLegacyDataType.TimerElement => "T4:0",
+ AbLegacyDataType.CounterElement => "C5:0",
+ AbLegacyDataType.ControlElement => "R6:0",
+ _ => "N7:0",
+ };
+
+ [Theory(Skip = "F1: DriverArrayWriteSupport has no AbLegacy row yet (Core.Abstractions is outside this lane)")]
+ [MemberData(nameof(AllTypes))]
+ public void Table_agrees_with_the_array_encoder(AbLegacyDataType dataType)
+ {
+ var json = $$"""{"address":"{{AddressFor(dataType)}}","dataType":"{{dataType}}","isArray":true,"arrayLength":2}""";
+ var encoderAccepts = AbLegacyTagDefinitionFactory.FromTagConfig(json, "p", out _)
+ && AbLegacyArrayWriteEncoder.TryConvert(dataType, new object[] { 1, 1 }, 2, out _) == AbLegacyStatusMapper.Good;
+
+ DriverArrayWriteSupport.Supports(DriverTypeNames.AbLegacy, "Int16", json).ShouldBe(encoderAccepts, dataType.ToString());
+ }
+
+ /// What the encoder accepts today — the row F1 must add (Int, AnalogInt, Long, Float).
+ [Theory]
+ [InlineData(AbLegacyDataType.Int, true)]
+ [InlineData(AbLegacyDataType.AnalogInt, true)]
+ [InlineData(AbLegacyDataType.Long, true)]
+ [InlineData(AbLegacyDataType.Float, true)]
+ [InlineData(AbLegacyDataType.Bit, false)]
+ [InlineData(AbLegacyDataType.String, false)]
+ [InlineData(AbLegacyDataType.TimerElement, false)]
+ public void Encoder_accepts_exactly_the_flat_numeric_element_types(AbLegacyDataType dataType, bool accepts) =>
+ (AbLegacyArrayWriteEncoder.TryConvert(dataType, new object[] { 1, 1 }, 2, out _) == AbLegacyStatusMapper.Good)
+ .ShouldBe(accepts);
+}