diff --git a/archreview/plans/R2-06-serverhistorian-failfast-plan.md.tasks.json b/archreview/plans/R2-06-serverhistorian-failfast-plan.md.tasks.json
index 19e36248..a4cdd1fa 100644
--- a/archreview/plans/R2-06-serverhistorian-failfast-plan.md.tasks.json
+++ b/archreview/plans/R2-06-serverhistorian-failfast-plan.md.tasks.json
@@ -73,7 +73,7 @@
{
"id": "T10",
"subject": "C-7: keep-populating decision + dead-Quality doc comments at GatewayHistorianValueWriter.cs:63, ContinuousHistorizationRecorder.GoodQuality, docs/Historian.md (cites 0.2.0 Contracts C-002); commit 3 (C-7)",
- "status": "pending",
+ "status": "completed",
"blockedBy": []
},
{
diff --git a/docs/Historian.md b/docs/Historian.md
index 183ef1b7..3549760b 100644
--- a/docs/Historian.md
+++ b/docs/Historian.md
@@ -102,6 +102,12 @@ write path) and the `ContinuousHistorization` section (driver-value capture). Al
**same** gateway — but only `ServerHistorian` carries the connection (endpoint/key/TLS); the other two
source it from there.
+> **Continuous-historization value quality is server-stamped.** The gateway's `WriteLiveValues` SQL path
+> **discards** the quality the recorder sends (a server-managed column; 0.2.0 Contracts C-002), so persisted
+> quality is stamped gateway-side regardless of what the `ContinuousHistorizationRecorder` provides (it
+> hardcodes OPC-DA Good, `192`). Capturing real per-node quality will not persist until the gateway honors
+> the field — see `GatewayHistorianValueWriter`'s remarks (archreview 06/C-7).
+
---
## Tag auto-provisioning (EnsureTags)
diff --git a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/Recorder/GatewayHistorianValueWriter.cs b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/Recorder/GatewayHistorianValueWriter.cs
index ac3ccacb..c862c4a3 100644
--- a/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/Recorder/GatewayHistorianValueWriter.cs
+++ b/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/Recorder/GatewayHistorianValueWriter.cs
@@ -24,6 +24,17 @@ namespace ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.Recorder;
/// A success ack OR a store-forward-queued ack maps to true: a value the gateway
/// durably queued must not be re-drained.
///
+///
+/// Quality is a documented-dead input on the WriteLiveValues SQL path
+/// (HistorianGateway 0.2.0 Contracts C-002): HistorianLiveValue.Quality /
+/// QualityDetail are server-managed columns — any value sent is accepted on the wire and
+/// then silently discarded. We populate Quality anyway (see the mapping below): proto3
+/// transmits 0 when a field is left unset, and 0 is "Bad" in OPC-DA terms, so
+/// not setting it would send a wrong quality to any future gateway version that
+/// starts honoring the field — whereas the recorder's 192 ("Good") is the correct value.
+/// Do NOT extend the recorder to capture real node quality expecting it to persist — it
+/// will not, until the gateway honors the field.
+///
///
public sealed class GatewayHistorianValueWriter : IHistorianValueWriter, IAsyncDisposable
{
@@ -60,6 +71,8 @@ public sealed class GatewayHistorianValueWriter : IHistorianValueWriter, IAsyncD
var live = new HistorianLiveValue
{
NumericValue = value.Value,
+ // Documented-dead input on the WriteLiveValues SQL path (0.2.0 Contracts C-002 —
+ // server-managed, silently discarded). Populated deliberately; see the class .
Quality = value.Quality,
};
diff --git a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Historian/ContinuousHistorizationRecorder.cs b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Historian/ContinuousHistorizationRecorder.cs
index 8c589e6f..bbb4122a 100644
--- a/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Historian/ContinuousHistorizationRecorder.cs
+++ b/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/Historian/ContinuousHistorizationRecorder.cs
@@ -41,7 +41,14 @@ namespace ZB.MOM.WW.OtOpcUa.Runtime.Historian;
public sealed class ContinuousHistorizationRecorder : ReceiveActor, IWithTimers
{
/// OPC-DA quality byte recorded for mux-fanned values (the mux drops quality; driver-published
- /// values are Good by the same convention the scripted-alarm host applies).
+ /// values are Good by the same convention the scripted-alarm host applies).
+ ///
+ /// Note (archreview 06/C-7): the historian gateway's WriteLiveValues SQL path discards
+ /// quality (server-managed column, 0.2.0 Contracts C-002 — see
+ /// GatewayHistorianValueWriter's remarks). This constant is therefore what a future
+ /// quality-honoring gateway path would receive; capturing real per-node quality here will
+ /// NOT persist until the gateway honors the field.
+ ///
public const ushort GoodQuality = 192;
private const string DrainTimerKey = "drain";