diff --git a/archreview/remediation/60-testing-docs-gaps.md b/archreview/remediation/60-testing-docs-gaps.md index f376539..6ebf9cd 100644 --- a/archreview/remediation/60-testing-docs-gaps.md +++ b/archreview/remediation/60-testing-docs-gaps.md @@ -355,6 +355,8 @@ If TST-02's interim mitigation (flip retention off) is chosen instead of impleme **Verification.** `dotnet build src/ZB.MOM.WW.MxGateway.Server`; test toggling the flag suppresses/shows values; docs match. +**Closed 2026-08-18 — implemented (the Design's recommended path).** The flag is no longer dead: it now gates value display on all three seams that carry a tag value. `Dashboard/DashboardLiveDataService.cs` substitutes `[redacted]` at the service boundary for each successfully read `/browse` tag (a failed read keeps its `-` placeholder, so the error row and the redaction cannot contradict each other); `Dashboard/Hubs/AlarmsHubPublisher.cs` clears `current_value`/`limit_value` from a **deep-cloned** `AlarmFeedMessage` before broadcasting to `/hubs/alarms`, and `DashboardEventBroadcaster` does the same for the events-hub mirror — clones, because the sources fan out to gRPC `StreamAlarms`/`StreamEvents` and the replay ring, so no gRPC client is affected by this dashboard-display flag. The flag is **kept**, default still `false`. The stale prose the Finding flagged is gone: `docs/GatewayConfiguration.md` and `docs/GatewayDashboardDesign.md` now describe the real behaviour. Status tracked in `00-tracking.md` (already **Done**). + --- ## TST-17 — Vendor-gated alarm parity residuals silently lossy `Medium` · `—` diff --git a/clients/go/internal/generated/mxaccess_gateway.pb.go b/clients/go/internal/generated/mxaccess_gateway.pb.go index 4ef7d3a..99596e8 100644 --- a/clients/go/internal/generated/mxaccess_gateway.pb.go +++ b/clients/go/internal/generated/mxaccess_gateway.pb.go @@ -7342,9 +7342,13 @@ func (x *StreamAlarmsRequest) GetAlarmFilterPrefix() string { return "" } -// One message on the StreamAlarms feed. The stream opens with one -// `active_alarm` per currently-active alarm, then a single -// `snapshot_complete`, then a `transition` for every subsequent change. +// One message on the StreamAlarms feed. The stream opens with a +// `provider_status` (the current provider mode), then a `snapshot_status` +// (whether the cached active set may be incomplete), then one `active_alarm` +// per currently-active alarm, then a single `snapshot_complete`. After that +// come the live frames: a `transition` for every subsequent alarm change, +// interleaved with a further `provider_status` on each failover/failback and a +// further `snapshot_status` on each change of the truncation verdict. type AlarmFeedMessage struct { state protoimpl.MessageState `protogen:"open.v1"` // Types that are valid to be assigned to Payload: diff --git a/clients/java/src/main/generated/main/java/mxaccess_gateway/v1/MxaccessGateway.java b/clients/java/src/main/generated/main/java/mxaccess_gateway/v1/MxaccessGateway.java index b49bf8b..153aea4 100644 --- a/clients/java/src/main/generated/main/java/mxaccess_gateway/v1/MxaccessGateway.java +++ b/clients/java/src/main/generated/main/java/mxaccess_gateway/v1/MxaccessGateway.java @@ -89203,9 +89203,13 @@ public final class MxaccessGateway extends com.google.protobuf.GeneratedFile { } /** *
- * One message on the StreamAlarms feed. The stream opens with one
- * `active_alarm` per currently-active alarm, then a single
- * `snapshot_complete`, then a `transition` for every subsequent change.
+ * One message on the StreamAlarms feed. The stream opens with a
+ * `provider_status` (the current provider mode), then a `snapshot_status`
+ * (whether the cached active set may be incomplete), then one `active_alarm`
+ * per currently-active alarm, then a single `snapshot_complete`. After that
+ * come the live frames: a `transition` for every subsequent alarm change,
+ * interleaved with a further `provider_status` on each failover/failback and a
+ * further `snapshot_status` on each change of the truncation verdict.
*
*
* Protobuf type {@code mxaccess_gateway.v1.AlarmFeedMessage}
@@ -89739,9 +89743,13 @@ public final class MxaccessGateway extends com.google.protobuf.GeneratedFile {
}
/**
*
- * One message on the StreamAlarms feed. The stream opens with one
- * `active_alarm` per currently-active alarm, then a single
- * `snapshot_complete`, then a `transition` for every subsequent change.
+ * One message on the StreamAlarms feed. The stream opens with a
+ * `provider_status` (the current provider mode), then a `snapshot_status`
+ * (whether the cached active set may be incomplete), then one `active_alarm`
+ * per currently-active alarm, then a single `snapshot_complete`. After that
+ * come the live frames: a `transition` for every subsequent alarm change,
+ * interleaved with a further `provider_status` on each failover/failback and a
+ * further `snapshot_status` on each change of the truncation verdict.
*
*
* Protobuf type {@code mxaccess_gateway.v1.AlarmFeedMessage}
diff --git a/clients/proto/descriptors/mxaccessgw-client-v1.protoset b/clients/proto/descriptors/mxaccessgw-client-v1.protoset
index 30a8c97..c92518c 100644
Binary files a/clients/proto/descriptors/mxaccessgw-client-v1.protoset and b/clients/proto/descriptors/mxaccessgw-client-v1.protoset differ
diff --git a/clients/rust/protos/mxaccess_gateway.proto b/clients/rust/protos/mxaccess_gateway.proto
index b5e2a6b..daa3e8d 100644
--- a/clients/rust/protos/mxaccess_gateway.proto
+++ b/clients/rust/protos/mxaccess_gateway.proto
@@ -1003,9 +1003,13 @@ message StreamAlarmsRequest {
string alarm_filter_prefix = 2;
}
-// One message on the StreamAlarms feed. The stream opens with one
-// `active_alarm` per currently-active alarm, then a single
-// `snapshot_complete`, then a `transition` for every subsequent change.
+// One message on the StreamAlarms feed. The stream opens with a
+// `provider_status` (the current provider mode), then a `snapshot_status`
+// (whether the cached active set may be incomplete), then one `active_alarm`
+// per currently-active alarm, then a single `snapshot_complete`. After that
+// come the live frames: a `transition` for every subsequent alarm change,
+// interleaved with a further `provider_status` on each failover/failback and a
+// further `snapshot_status` on each change of the truncation verdict.
message AlarmFeedMessage {
oneof payload {
// Part of the initial active-alarm snapshot (ConditionRefresh).
diff --git a/docs/GatewayDashboardDesign.md b/docs/GatewayDashboardDesign.md
index bfc7fdb..f69b8c0 100644
--- a/docs/GatewayDashboardDesign.md
+++ b/docs/GatewayDashboardDesign.md
@@ -520,7 +520,9 @@ panel. The panel shows each subscribed tag's live value, MXAccess data type,
quality and source timestamp, refreshed every two seconds — but the value column
obeys `Dashboard:ShowTagValues` like every other dashboard value surface. With
the flag false (the default) `DashboardLiveDataService` hands the page
-`[redacted]` in place of the formatted value; data type, quality, source
+`[redacted]` in place of the formatted value of each **successfully read** tag —
+a failed read keeps its `-` placeholder, since there was no value to suppress —
+while data type, quality, source
timestamp and any read error are untouched, so the panel still answers "is this
tag advising and healthy" without disclosing the value. The substitution happens
at the service, not in the page: one decision point, and the value never enters
diff --git a/docs/Grpc.md b/docs/Grpc.md
index 15bd1c8..6d7794e 100644
--- a/docs/Grpc.md
+++ b/docs/Grpc.md
@@ -114,10 +114,11 @@ message AlarmProviderStatus {
}
```
-The gateway emits `provider_status` once when a client first subscribes
-(immediately after the initial snapshot and before the first live transition)
-and again on every failover or failback. A late-joining client therefore
-always learns the current provider mode without waiting for the next switch.
+The gateway emits `provider_status` once when a client first subscribes — as
+the **first** frame on the stream, before the `snapshot_status` frame and
+before any cached `active_alarm` — and again on every failover or failback. A
+late-joining client therefore learns the current provider mode before it sees a
+single alarm, without waiting for the next switch.
#### Snapshot completeness on the alarm feed
diff --git a/src/ZB.MOM.WW.MxGateway.Contracts/Generated/MxaccessGateway.cs b/src/ZB.MOM.WW.MxGateway.Contracts/Generated/MxaccessGateway.cs
index d171283..b5d06b2 100644
--- a/src/ZB.MOM.WW.MxGateway.Contracts/Generated/MxaccessGateway.cs
+++ b/src/ZB.MOM.WW.MxGateway.Contracts/Generated/MxaccessGateway.cs
@@ -28513,9 +28513,13 @@ namespace ZB.MOM.WW.MxGateway.Contracts.Proto {
}
///