docs(deferment): #549 (6-model authoring strictness) + NamespaceMap split recorded; residuals #550/#551 filed
This commit is contained in:
+36
-1
@@ -55,7 +55,7 @@ So everything below is **untracked work**. Nothing in it is a data-loss or outag
|
||||
|---|---|---|
|
||||
| **4 live gates blocked on hardware/licence** — ~~archreview R2-03 (VT Good→Bad on a data-fed rig)~~ ✅ *PASSED 2026-08-07*, ~~R2-10 (force breaker-OPEN)~~ ✅ *PASSED 2026-08-08 by fixing the structural gap (`DriverCapability.Initialize`)*, Galaxy `ScanStateProbeParityTests` (licence-gated), v2 GA exit criteria (~~FOCAS live-CNC smoke #54~~ *closed — live-validated on a real 31i-B 2026-06-25, see `docs/plans/2026-06-25-focas-pdu-v3-30i-b-support.md`*, OPC UA CTT pass, Ignition 8.3 cutover) | Cannot be closed from this box. Not decisions — inputs. *(The two archreview gates turned out to be closable from this box after all — §5.)* | §5 |
|
||||
| ~~**1 deferred live-verify task** — `2026-06-14-driver-reconfigure-while-faulted` Task 3~~ ✅ **PASSED 2026-08-07.** A faulted driver ("initialize failed: Connection refused") adopted a corrected config and connected while faulted, with the node's `startedAt` byte-identical before and after and `RestartCount=0` — no restart. | §5 |
|
||||
| ~~**G-7 residual** — Sql / MTConnect / Calculation / OpcUaClient have no Contracts-side `Inspect`~~ ✅ **CLOSED 2026-08-09** (`2947a2b9` + `1469fbb4`, merge `0695f682`). All four now ship a Contracts-side `*TagDefinitionFactory.Inspect` **wrapping the runtime parse, never mirroring the AdminUI model** — Sql wraps the pre-existing `SqlEquipmentTagParser`; the MTConnect / OpcUaClient / Calculation blob readers were **moved** into their Contracts assemblies (the drivers now call them), so never-stricter-than-runtime is structural. `Driver.Calculation.Contracts` was created (no Contracts assembly existed). The reflection coverage guard was falsified (map entry removed → red naming `SqlTagDefinitionFactory`), and `TagConfigAuthoringDeployParityTests` pins authoring-accepts ⇒ deploy-accepts. **Galaxy is now the sole unmapped type, deliberately + symmetrically** (no typed authoring editor either). Found en route, left open: `MTConnectTagConfigModel` reads `dataType` leniently (misspelled name → silently `String`) while the runtime rejects it — authoring weaker than runtime, the *opposite* direction from G-7; documented inline in the parity tests. | ~~The deploy gate is weaker than the authoring gate.~~ Config arriving by CSV import or API now meets the same checks the modal applies. | §1.2 |
|
||||
| ~~**G-7 residual** — Sql / MTConnect / Calculation / OpcUaClient have no Contracts-side `Inspect`~~ ✅ **CLOSED 2026-08-09** (`2947a2b9` + `1469fbb4`, merge `0695f682`). All four now ship a Contracts-side `*TagDefinitionFactory.Inspect` **wrapping the runtime parse, never mirroring the AdminUI model** — Sql wraps the pre-existing `SqlEquipmentTagParser`; the MTConnect / OpcUaClient / Calculation blob readers were **moved** into their Contracts assemblies (the drivers now call them), so never-stricter-than-runtime is structural. `Driver.Calculation.Contracts` was created (no Contracts assembly existed). The reflection coverage guard was falsified (map entry removed → red naming `SqlTagDefinitionFactory`), and `TagConfigAuthoringDeployParityTests` pins authoring-accepts ⇒ deploy-accepts. **Galaxy is now the sole unmapped type, deliberately + symmetrically** (no typed authoring editor either). ~~Found en route, left open: `MTConnectTagConfigModel` reads `dataType` leniently (misspelled name → silently `String`) while the runtime rejects it — authoring weaker than runtime, the *opposite* direction from G-7; documented inline in the parity tests.~~ ✅ Filed and FIXED same day as **#549** — and it was 6 models wide, not 1 (see the "2026-08-09 (later)" §9 entry); residuals are **#550**/**#551**. | ~~The deploy gate is weaker than the authoring gate.~~ Config arriving by CSV import or API now meets the same checks the modal applies. | §1.2 |
|
||||
| ~~**3 carried-open archreview findings** — the failure-visibility trio~~ **Update 2026-08-07 (truth sweep): mostly CLOSED.** 01/S-1 **FIXED** — `AddressSpaceApplier.cs:95-97` tallies swallowed removal-pass failures into `AddressSpaceApplyOutcome.FailedNodes` (comment cites 01/S-1). 03/S4 **FIXED** — `PrimaryGatePolicy.cs` default-denies on unknown role when a driver peer exists (doc-comment "Fixes archreview 03/S4"), live-proven R2-04 T15. 06/S-1 **PARTIAL** — fail-closed advise path + `galaxy.writes.unconfirmed` meter shipped in `GatewayGalaxyDataWriter.cs`; residual = gateway-side WriteComplete correlation (cross-repo, mxaccessgw). **Update 2026-08-09: the gateway half SHIPPED** — mxaccessgw main `b948e69` correlates the worker's `OnWriteComplete` onto the unary `WriteSecured` reply (`statuses[0]`; bounded wait default **1.5 s** — deliberately under OtOpcUa's 2 s Tier A Write budget, configurable via `MxGateway:Worker:WriteCompletionWaitMilliseconds`; timeout falls back to today's empty-statuses shape, still metered unconfirmed). **Update 2026-08-09 (later): 06/S-1 CLOSED — live-gated end to end, and the gate found + fixed three defects.** The user-authorized redeploy exposed (1) the correlation covered `WriteSecured` only while OtOpcUa's dominant no-login path emits plain `Write` — fixed gateway-side (worker `53f69cd`, all four unary write kinds, redeployed both hosts); (2) OtOpcUa's `StatusCodeMap.FromMxStatus` truncated the correlated failure row's MxStatus detail code to a byte (`1007 & 0xFF = 239` → OPC DA Good band), mapping a REFUSED write to Good — fixed with the not-IsSuccess-never-Good invariant + category routing (`SECURITY_ERROR → BadUserAccessDenied`); (3) the writer's borrow-from-subscription-registry optimization could never commit (a subscription handle is plain-advised; MXAccess refuses the no-login write `SECURITY_ERROR 1008` AND the advise upgrade `E_INVALIDARG` — one advise per HANDLE, not per attribute) — borrow path REMOVED, writer always owns a supervisory-advised handle. Live legs all PASSED on windev: happy write Good off confirmed `statuses[0]` + both meters flat; read-only refusal surfaces Bad-family + node-revert input; `WriteCompletionWaitMilliseconds=0` control → provisional Good + metered unconfirmed (override removed after). Pinned by `Live_correlated_write_statuses_confirm_commit_and_surface_refusal`, `Live_write_to_subscribed_tag_commits_via_own_handle`, `GatewayGalaxyWriteMeterLiveTests`, and the new `StatusCodeMapTests` rows. | ~~Residual is only the 06/S-1 live leg~~ **CLOSED 2026-08-09** — nothing remains. | §6.3 |
|
||||
| ~~**1 genuinely unexecuted plan** — `2026-05-29-adminui-followups`, **19 pending / 0 completed**~~ ✅ **CLOSED 2026-08-07 by the overlap audit it asked for — it was bookkeeping drift, not backlog.** All 19 tasks are shipped, superseded by v3, or moot; **no code was needed.** The warning was right and then some: WS1's whole *premise* died with v3 (driver-embedded tag lists in `DriverConfig` are no longer the runtime source of truth — the artifact populates `RawTags`), and its capability was delivered in the v3 shape (`TagConfigEditorMap` + `DeviceFormMap`, both verified **reachable**, not merely present). WS2/WS3 shipped; WS4's target files were deleted by v3 Batch 2 + #542. Per-task evidence in the `.tasks.json`. | §6.2 |
|
||||
| **11 other open plan tasks** — ~~5 akka-hosting partials (likely v3-superseded)~~ *(verified superseded 2026-08-07 — F8/F9/F10/F13/F14 marked completed; `Phase7Composer`/`ScriptedAlarmActor` deleted, evaluators/SDK sinks/security policies all production-wired)*, 4+1 followups-batch (open *by choice*), fixedtree Task 11, 1 manual smoke checklist | Small, and two of the groups are decisions already taken. | §6.2 |
|
||||
@@ -1280,6 +1280,41 @@ drivers), 3 carried-open archreview findings led by 01/S-1 (`AddressSpaceApplier
|
||||
|
||||
---
|
||||
|
||||
### 2026-08-09 (later) — #549 authoring strictness (6 models); NamespaceMap out of Contracts
|
||||
|
||||
Follow-ups from the round below, again two isolated-worktree agents, merged `3a70a4e6` + `10c7a0e8`.
|
||||
Consolidated verification on the merged tree: full build clean; 12 suites / 4,119 tests green
|
||||
(AdminUI 1175, ControlPlane 261, Core.Abstractions 284, MTConnect 534, AbLegacy 219, TwinCAT 192,
|
||||
FOCAS 327, OpcUaClient 143 + Browser 10, Modbus 346, S7 264, AbCip 364).
|
||||
|
||||
- **#549 CLOSED — and the survey it demanded found the defect was 6 models wide, not 1.** The G-7
|
||||
round's "MTConnect authoring accepts a dataType the runtime rejects" generalised: **R2-11 Phase C
|
||||
made every runtime TagConfig enum read strict** (`TagConfigJson.TryReadEnumStrict` rejects the
|
||||
tag), so every lenient `GetEnum` authoring model was authoring-weaker-than-runtime — MTConnect,
|
||||
Modbus (region/dataType/byteOrder), S7, AbCip, AbLegacy, TwinCAT, FOCAS. Mqtt and Sql were already
|
||||
strict on both sides. Fixed one-authority: MTConnect's `Validate` consults the factory's exposed
|
||||
`IsAcceptedDataTypeName`; the other five consult `TagConfigJson.DescribeInvalidEnum`, which
|
||||
delegates to the runtime's own `ClassifyEnumText` (verdict AND wording from one implementation).
|
||||
Deliberately not stricter than runtime: absent keys / non-string tokens stay accepted where the
|
||||
runtime accepts them, each pinned. MTConnect also captures the raw JSON token — an unquoted
|
||||
`"dataType": 8` throws in the runtime DTO deserialise, so authoring now rejects it too.
|
||||
- **Survey residuals filed, not folded in:** **#550** (MTConnect `driverDataType` is a second,
|
||||
runtime-preferred spelling the editor neither reads nor writes — a valid one silently overrides
|
||||
what the editor displays; fixing needs both read-both-spellings AND normalise-on-save together) and
|
||||
**#551** (4 gate-coverage gaps: `RawCsvImportModal`'s free-form TagConfigJson column meets only the
|
||||
deploy gate; S7's unique absent-`dataType` hard-requirement warns nowhere; AbCip member `dataType`
|
||||
+ Modbus `stringByteOrder` checked by neither gate; the seven pre-#549 `Inspect` doc summaries
|
||||
still claim "silently defaulted by the lenient runtime" — stale since R2-11).
|
||||
- **NamespaceMap moved out of `OpcUaClient.Contracts`** into a new `Driver.OpcUaClient.Session` leaf
|
||||
(merge `10c7a0e8`), so ControlPlane's G-7 reference no longer drags the OPC UA client SDK into its
|
||||
dependency graph (before: five `OPCFoundation.*` packages transitively; after: none). The
|
||||
alternative — Browser referencing the driver, the Mqtt #512 shape — lost on a measurement: AdminUI
|
||||
references `.Browser`, so it would have pulled the driver runtime into the AdminUI graph, exactly
|
||||
what #512 spent two extractions removing. The G-7 one-authority seam survives (`BuildRawPathTable`
|
||||
still calls `OpcUaClientTagDefinitionFactory.TryReadNodeId`, now `.Session → .Contracts`).
|
||||
`ContractsIsDependencyLightTests` pins it from both directions (Contracts manifest names no
|
||||
`Opc.Ua*`; `.Session`'s must — so "none anywhere" cannot read as a pass), falsified red before trust.
|
||||
|
||||
### 2026-08-09 — G-7 closed; RawBrowseModal race ported
|
||||
|
||||
The two items §0.1 flagged as "highest-leverage runnable from here", executed in parallel by two
|
||||
|
||||
Reference in New Issue
Block a user