docs(deferment): #554 (TagConfigParseGate — authoring consults the parse) + #555 (browse-commit parity guard) closed; residuals #556/#557/#558 filed

This commit is contained in:
Joseph Doherty
2026-08-10 02:02:10 -04:00
parent 7cfe7b4a24
commit ca3968cc31
+43
View File
@@ -1280,6 +1280,49 @@ drivers), 3 carried-open archreview findings led by 01/S-1 (`AddressSpaceApplier
---
### 2026-08-10 (third round) — #554 + #555 closed: authoring consults the parse; the cited guard now exists
The two residuals of the #552/#553 round, again two isolated-worktree Opus agents, merged `7cfe7b4a`
(#554) + `4f1c83a7` (#555). Consolidated verification on the merged tree: full build clean; 14
suites / 5,251 tests green (AdminUI 1430, ControlPlane 261, Modbus 373, S7 285, AbCip 390, AbLegacy
230, TwinCAT 205, FOCAS 341, Mqtt 673, Sql 363, MTConnect 534, OpcUaClient 143, Calculation 23).
- **#554 CLOSED** — every mapped `*TagConfigModel.Validate()` consults the driver's own runtime
parse on the AS-LOADED blob via the new `TagConfigParseGate` (AdminUI-side, no factory touched):
**verdict from the parse, wording from `Inspect` only after refusal**. The two design points are
pinned: gating on "Inspect said something" would be stricter than runtime (FOCAS/MQTT/Calculation
advisories ride ACCEPTED blobs), and judging typed fields instead of the source blob would accept
exactly what the lenient load hides. Survey closed real gaps in 5 of 11 drivers: Modbus (absent
`region`, address shapes, `stringLength<1`, `bitIndex>15`, and `{}` itself), S7 (`stringLength`
0–254), TwinCAT (`dataType:"Structure"` — valid enum NAME the reader refuses; no spelling gate
can see it), Sql (the recognition rule), Mqtt (`"qos":null`). Deliberately-stricter editor rules
KEPT and pinned by name, incl. AbLegacy's `arrayLength>256` (the runtime *clamps* but the
materialiser advertises the RAW number in `ArrayDimensions` — the authored value is silently not
honoured, so author-time refusal is the honest treatment). ⚠️ Behaviour change: **an untouched
`{}` Modbus config is now refused at save** — it was the only editor with no required field, and
a `{}` tag reads BadNodeIdUnknown forever under a green deployment. Anti-vacuity guards: the
parity corpus must exercise BOTH verdicts per driver; an exemption that stops being
deliberately-stricter FAILS instead of silently excusing.
- **#555 CLOSED** — `RawBrowseCommitMapperParityTests` now exists, holding the mapper to what its
comment merely claimed. The browsable set is DERIVED: the test runs the production `AddAdminUI()`
registration and reads back every `IDriverBrowser.DriverType` (the set `BrowserSessionService`
indexes). The universal `DiscoveryDriverBrowser` arm is NOT derivable from the AdminUI assembly
(needs runtime drivers + Host's `IDriverFactory`; the #526 cut is deliberate) — covered by
enumerating `DriverTypeNames.All` with a reasoned `GenericKeyExemptions` list (Modbus,
Calculation) plus a fact that mechanically refutes any exemption the derived arm contradicts.
Falsified three ways (disabled Sql branch → red naming Sql; disabled MTConnect branch → red via
the enumeration half that DI derivation cannot reach; bogus exemption → the contradiction fact
red quoting it). The mapper comment now states the two real claims and the residual trust.
- **Residuals filed, not folded in:** **#556** (Inspect polish — the `reference[0] != '{'`
pre-filter has no `TrimStart()` so `" {…}"` draws zero warnings in 7 factories; FOCAS/MQTT
advisories can swallow the rejection backstop via `warnings.Count == 0`), **#557** (reader
asymmetries — OpcUaClient's legacy PascalCase `NodeId` is readable but unsaveable untouched; Mqtt
Sparkplug parse accepts a `payloadFormat` the Plain parse rejects and the union admits it),
**#558** (test hygiene — the pre-existing `DriverDispatchMapParityTests` browse-commit fact
overlaps the new guard and its `NonBrowsableDriverTypes` list is hand-authored AND misnamed;
two browser classes return `DriverType` string literals instead of `DriverTypeNames` constants,
unguarded).
### 2026-08-10 (later) — #552 + #553 closed: the browse states, the merge preserves
The two residuals the #550/#551 round exposed, again two isolated-worktree Opus agents, merged