MTConnect authoring accepts a dataType the runtime rejects (authoring weaker than runtime) #549

Closed
opened 2026-08-09 21:46:18 -04:00 by dohertj2 · 1 comment
Owner

Found by the G-7 parity tests falsifiability control (merge 0695f682). MTConnectTagConfigModel.FromJson reads dataType via TagConfigJson.GetEnum, which falls back to String on any unrecognised value — so a misspelled name like "Strng" is accepted at authoring, silently coerced, and rewritten clean on save. The strict runtime parse (MTConnectTagDefinitionFactory.TryParseDataType: Enum.TryParse ignore-case + IsDefined) rejects the same value, so the tag fails at the driver. This is the REVERSE direction from G-7: authoring weaker than runtime.

Fix shape: one authority — expose the factory predicate from MTConnect.Contracts and have Validate() (which already keeps _rawDataType for the digits-only trap) reject any raw value the runtime would reject. Also survey the other ten TagConfigJson.GetEnum call sites for the same asymmetry (lenient authoring is only correct where the runtime is equally lenient).

Documented inline in TagConfigAuthoringDeployParityTests and in deferment.md §9 (2026-08-09 entry).

Found by the G-7 parity tests falsifiability control (merge 0695f682). `MTConnectTagConfigModel.FromJson` reads `dataType` via `TagConfigJson.GetEnum`, which falls back to `String` on any unrecognised value — so a misspelled name like `"Strng"` is accepted at authoring, silently coerced, and rewritten clean on save. The strict runtime parse (`MTConnectTagDefinitionFactory.TryParseDataType`: `Enum.TryParse` ignore-case + `IsDefined`) rejects the same value, so the tag fails at the driver. This is the REVERSE direction from G-7: authoring weaker than runtime. Fix shape: one authority — expose the factory predicate from `MTConnect.Contracts` and have `Validate()` (which already keeps `_rawDataType` for the digits-only trap) reject any raw value the runtime would reject. Also survey the other ten `TagConfigJson.GetEnum` call sites for the same asymmetry (lenient authoring is only correct where the runtime is equally lenient). Documented inline in `TagConfigAuthoringDeployParityTests` and in deferment.md §9 (2026-08-09 entry).
Author
Owner

FIXED, merged 3a70a4e6 (work commit a3c0ec03) — and the survey the issue asked for found the defect was 6 models wide, not 1. R2-11 Phase C had made every runtime TagConfig enum read strict (TagConfigJson.TryReadEnumStrict rejects the tag), so every lenient GetEnum authoring model was asymmetric: MTConnect, Modbus (region/dataType/byteOrder), S7, AbCip, AbLegacy, TwinCAT, FOCAS dataType. Mqtt and Sql were already strict on both sides (untouched).

Fix is one-authority as proposed: MTConnect Validate consults the exposed MTConnectTagDefinitionFactory.IsAcceptedDataTypeName; the other five consult a new TagConfigJson.DescribeInvalidEnum that delegates to the runtimes own ClassifyEnumText, so verdict AND wording come from one implementation. MTConnect also now captures the raw JSON token (an unquoted "dataType": 8` throws in the runtime DTO deserialise, so authoring rejects it too). Deliberately NOT stricter than runtime: absent keys and present-but-non-string tokens stay accepted where the runtime accepts them, each pinned by its own test.

+48 AdminUI tests, 3 independent falsification reverts each red for the right reason. Follow-ups from the survey filed separately: the MTConnect driverDataType dual-spelling (authoring blind to the runtime-preferred key) and the residual gate-coverage gaps (CSV-import TagConfigJson column, S7 absent-key, AbCip member dataType, Modbus stringByteOrder, stale Inspect doc summaries).

FIXED, merged `3a70a4e6` (work commit `a3c0ec03`) — and the survey the issue asked for found the defect was **6 models wide, not 1**. R2-11 Phase C had made every runtime TagConfig enum read strict (`TagConfigJson.TryReadEnumStrict` rejects the tag), so every lenient `GetEnum` authoring model was asymmetric: MTConnect, Modbus (region/dataType/byteOrder), S7, AbCip, AbLegacy, TwinCAT, FOCAS dataType. Mqtt and Sql were already strict on both sides (untouched). Fix is one-authority as proposed: MTConnect Validate consults the exposed `MTConnectTagDefinitionFactory.IsAcceptedDataTypeName`; the other five consult a new `TagConfigJson.DescribeInvalidEnum` that delegates to the runtime`s own `ClassifyEnumText`, so verdict AND wording come from one implementation. MTConnect also now captures the raw JSON token (an unquoted `"dataType": 8` throws in the runtime DTO deserialise, so authoring rejects it too). Deliberately NOT stricter than runtime: absent keys and present-but-non-string tokens stay accepted where the runtime accepts them, each pinned by its own test. +48 AdminUI tests, 3 independent falsification reverts each red for the right reason. Follow-ups from the survey filed separately: the MTConnect `driverDataType` dual-spelling (authoring blind to the runtime-preferred key) and the residual gate-coverage gaps (CSV-import TagConfigJson column, S7 absent-key, AbCip member dataType, Modbus stringByteOrder, stale Inspect doc summaries).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: dohertj2/lmxopcua#549