Add same-day addendum to OtOpcUa corrections doc noting four v2 design defects an adversarial review surfaced after the corrections doc was filed (one critical: cross-cluster namespace binding, three high: namespace state bypassing publish boundary, ZTag/SAPID rollback-reuse hazard, operator-supplied EquipmentId minting duplicate identities) — all four closed in lmxopcua v2 branch at commit a59ad2e (decisions #122–125). Two of the fixes refine claims this corrections doc made (C4 multi-identifier model: EquipmentId is now system-generated not operator-supplied; D3 ACL location: ExternalIdReservation precedent shows some cross-generation invariants need non-versioned tables) so plan-team awareness matters; the other two (same-cluster namespace invariant, Namespace generation-versioning) are purely internal correctness with no handoff relevance, included for audit trail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-04-17 11:09:58 -04:00
parent 68dbc014da
commit 8a6c227dbc

View File

@@ -373,3 +373,47 @@ This batch:
**Most urgent for plan integration:** B1 (missing ACL surface) and C5 (missing consumer cutover plan) — both are large work items the v2 implementation design discovered are needed but doesn't currently own. They should be assigned (to OtOpcUa team or another team) before Year 1 tier 1 cutover begins.
**Reference:** all v2 design decisions are in `lmxopcua/docs/v2/plan.md` (decision log §). Specific cross-references in this doc cite decision numbers (#XX) where applicable.
---
## Addendum — v2 design hardening, same day (2026-04-17)
After this corrections doc was filed, an adversarial review of the v2 db schema and Admin UI surfaced four internal design defects (one critical, three high) that the OtOpcUa team has now closed. None of these are corrections back to the handoff — they are internal design corrections within the v2 work — but two of them refine claims this corrections doc made and are worth flagging for plan-team awareness:
### Affects C4 (multi-identifier equipment model) — `EquipmentId` is now system-generated, not operator-supplied
C4 above describes a 5-identifier equipment model (UUID, EquipmentId, MachineCode, ZTag, SAPID) and implies `EquipmentId` is operator-set with the other operator-facing identifiers. The hardened design (lmxopcua decision #125) makes `EquipmentId` **system-generated** as `'EQ-' + first 12 hex chars of EquipmentUuid`, never operator-supplied, never editable, never present in CSV imports. The operator-facing identifiers are now MachineCode, ZTag, SAPID — three operator-set fields, two system-generated (EquipmentId, EquipmentUuid).
**Why the change**: operator-supplied EquipmentId was a corruption path — typos and bulk-import renames would mint duplicate equipment identities, each with a fresh UUID, permanently splitting downstream UUID-keyed lineage. Removing operator authoring eliminates the failure mode entirely. CSV imports now match by EquipmentUuid for updates; rows without UUID create new equipment with system-generated identifiers.
**For the plan team**: this doesn't change the audience-mapping story (operators say MachineCode in conversation, ERP queries by ZTag, etc.) — it just means there's one less operator field in the equipment-create form. If any plan-level documentation describes EquipmentId as operator-managed, update to "system-generated".
### Affects D3 (ACL location) and adds a new architectural concept — `ExternalIdReservation` table for rollback-safe identifier uniqueness
D3 above proposes ACL definitions live alongside topology in the central config DB, generation-versioned. The same review surfaced that **fleet-wide uniqueness for ZTag and SAPID cannot be expressed within generation-versioned tables** because old generations and disabled equipment can still hold the same external IDs — rollback or re-enable then silently reintroduces duplicates that corrupt downstream ERP/SAP joins.
The hardened design (lmxopcua decision #124) introduces a new `ExternalIdReservation` table that sits **outside generation versioning** specifically for this rollback-safety property. `sp_PublishGeneration` reserves IDs atomically at publish; FleetAdmin-only `sp_ReleaseExternalIdReservation` (audit-logged, requires reason) is the only path to free a value for reuse by a different EquipmentUuid; rollback respects the reservation table.
**For the plan team**: this is a precedent that some cross-generation invariants need their own non-versioned tables. When the missing ACL design is being scoped (per B1 / C5 above), consider whether *any* ACL grant has a similar rollback-reuse hazard. (Initial intuition: ACLs probably don't — granting a permission and then revoking it doesn't create downstream join corruption the way an ID does. But worth checking.)
### Two purely-internal fixes (no plan-team relevance)
For completeness and audit trail:
- **Same-cluster invariant on `DriverInstance.NamespaceId`** (lmxopcua decision #122) — closes a critical cross-cluster trust-boundary leak in the schema where a draft for cluster A could bind to cluster B's namespace and leak its URI. Three-layer enforcement (sp_ValidateDraft + API scoping + audit log).
- **`Namespace` table moves from cluster-level to generation-versioned** (lmxopcua decision #123) — earlier draft mistakenly treated namespaces as cluster-topology like ClusterNode rows. They are consumer-visible content (define what consumers see at the OPC UA endpoint) and must travel through draft → diff → publish like every other consumer-visible config.
Neither of these affects the handoff or this corrections doc directly.
### Updated summary
| Category | Count | Notes |
|----------|------:|-------|
| A. Inaccuracies | 2 | Both wording/framing issues; no architectural conflict |
| B. Missing constraints | 3 | ACLs, schemas-repo dependencies, certificate trust pre-cutover |
| C. Architectural decisions to revisit | 6 | Driver list pre-survey, stability tiers, Polly resilience, multi-identifier model (now refined per addendum), missing cutover plan, per-building cluster interactions |
| D. Resolved TBDs | 4 | Pilot class, schemas repo format, ACL location, enterprise shortname (unresolved) |
| E. New TBDs | 4 | UUID-gen authority, Aveva validation, multi-cluster site addressing, cluster-endpoint mental model |
| **Addendum hardening fixes** | **4** | EquipmentId system-generated; ExternalIdReservation table; same-cluster namespace binding; Namespace generation-versioned |
The hardening fixes are committed in `lmxopcua` branch `v2` at commit `a59ad2e` (2026-04-17). Decisions #122125 in `lmxopcua/docs/v2/plan.md` carry the rationale.