fix(galaxy): publish an unrepresentable value as BadTypeMismatch, not a good null
v2-ci / build (push) Successful in 6m23s
v2-ci / unit-tests (push) Failing after 20m2s

Reverses the conservative call from the previous commit at the user's direction,
and they were right: "surface it on a counter first" left the wire lying. An
MXAccess event can carry Good quality while its payload is a kind MxValueDecoder
has no mapping for, so the old behaviour published null-under-Good — which a
client cannot tell apart from a genuine null reading. A value the gateway DID
send would be consumed as a value it did not, with the only evidence in a log
nobody is tailing. Bad data is the honest wire representation of lost data.

BadTypeMismatch is an existing StatusCodeMap constant, deliberately reused rather
than written inline: StatusCodeParityTests finds status constants by reflecting
over Good/Uncertain/Bad-prefixed uint fields and checking them against the pinned
SDK, so an inline literal would be invisible to that guard (Gitea #497, where 16
wrong constants had accumulated across 6 drivers exactly this way).

Logging is now once per DISTINCT value kind rather than once per pump. The set is
bounded by the MxValue oneof enum so a broken producer still cannot flood, but a
second unrepresentable kind appearing later gets its own line — warn-once-per-pump
would have silently swallowed it, which is the same class of bug as the null this
commit fixes.

The test's fixture matters more than its assertion: the undecodable event carries
Quality = 192 (OPC DA Good), so a decoder that gave up silently would publish Good
and fail. Paired with a positive control — a decodable value at the same quality
must still publish Good — so it cannot be satisfied by a pump that marks
everything Bad. Falsified by reverting the status to Good: the test reds, and only
that test.

Verified: 331 Galaxy tests green, Core.Abstractions 298 (the parity guard),
solution builds 0 errors. Docs corrected in the two places that recorded the old
decision as deliberate.
This commit is contained in:
Joseph Doherty
2026-08-12 03:03:51 -04:00
parent 4769044f88
commit c51c59987b
4 changed files with 110 additions and 19 deletions
+4 -3
View File
@@ -63,9 +63,10 @@ observation.
`galaxy.events.undecodable` should likewise be flat at zero: every
`MxValue` kind the contract declares decodes today. Non-zero means the
gateway shipped a new wire type and those readings are being published as
**nulls under the event's own quality** — the status is deliberately not
downgraded, so this counter is the only signal that it is happening.
gateway shipped a new wire type, and those readings are being published
as **`BadTypeMismatch` with a null value** — visible to clients as bad
data rather than as a plausible null, and logged once per distinct kind.
The remedy is a mapping in `MxValueDecoder`, not a quality change.
### Bounded channel design