Commit Graph

5 Commits

Author SHA1 Message Date
Joseph Doherty b8208b3312 test+docs(v3-batch4-wp5): 2-node dual-namespace harness tests + address-space docs
Tests:
- OpcUaServer.IntegrationTests/DualNamespaceAddressSpaceTests.cs (NEW, over-the-wire,
  offline-safe): both namespace URIs registered + distinct; Raw + UNS subtrees browse
  and read; UNS variable Organizes-references its raw node; single-source fan-out parity
  (identical value/quality/timestamp on both NodeIds); HistoryRead via either NodeId ->
  GoodNoData under the shared tagname; WriteOperate gate symmetric across both NodeIds.
- Host.IntegrationTests/EquipmentNamespaceMaterializationTests.cs (extended): full deploy
  -> persisted-artifact -> ParseComposition round-trip carrying both realms, sealing across
  the redundant 2-node cluster (redundancy non-interference). In-memory harness, offline.

Docs (dual-namespace reality):
- CLAUDE.md: new "v3 OPC UA Address Space (Batch 4)" section + Batch-4 testing paragraph.
- docs/Uns.md: address-space projection (two namespaces, Organizes edge, effective-name leaf).
- docs/Historian.md: dual-registration (both NodeIds -> one tagname); updated CLI examples.
- docs/ScriptedAlarms.md + docs/AlarmTracking.md: multi-notifier fan-out, ConditionId=RawPath.
- docs/ScriptEditor.md: dual-namespace clarification (script tag-path semantics unchanged).

Claude-Session: https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox
2026-07-16 13:11:34 -04:00
Joseph Doherty dc0d7653b9 feat(v3-batch3): B3-WP4 — {{equip}}/<RefName> reference-relative resolution
Replace the deleted equipment-base-prefix {{equip}} mechanism (impossible now
that equipment is reference-only) with per-reference resolution:
{{equip}}/<RefName> resolves through the owning equipment's UnsTagReference rows
(by effective name) to the backing raw tag's RawPath. Every unresolved <RefName>
is a clear deploy error + authoring rejection + Monaco diagnostic — preserving
"editor accepts <=> publish accepts".

Commons:
- EquipmentScriptPaths: delete DeriveEquipmentBase; SubstituteEquipmentToken now
  takes the equipment's reference map (effectiveName -> RawPath) and substitutes
  {{equip}}/<RefName> inside path literals (unresolved left intact, never throws);
  add ExtractEquipReferenceNames (path-literal scoped) +
  ExtractEquipReferenceNamesFromText (message templates). Slash syntax replaces
  the v2 dot joint.
- New EquipmentReferenceMap: shared, input-shape-agnostic builder (entity + JSON
  sides) over RawPathResolver — the single authority both compose seams + the
  validator use, so resolved RawPaths agree byte-for-byte.

Compose seams (byte-parity kept):
- AddressSpaceComposer.Compose + DeploymentArtifact.ParseComposition both build
  the per-equipment reference map from UnsTagReferences + Tags + raw topology and
  substitute VirtualTag AND ScriptedAlarm-predicate sources before dependency
  extraction (runtime dep refs = resolved RawPaths).

Deploy gate + authoring + editor:
- DraftValidator.ValidateEquipReferenceResolution: EquipReferenceUnresolved error
  for unresolved {{equip}}/<RefName> in VirtualTag/ScriptedAlarm scripts + alarm
  message-template tokens (naming script, equipment, missing ref).
- UnsTreeService.ValidateEquipTokenAsync (Wave-A M1): reference-relative authoring
  rejection, replacing the stale DeriveEquipmentBase(empty)->reject-all logic.
- ScriptAnalysisService: {{equip}}/ completion offers the equipment's reference
  effective names; DiagnoseAsync flags unresolved refs (OTSCRIPT_EQUIPREF) same as
  the deploy gate. Requests carry optional EquipmentId (threaded MonacoEditor ->
  monaco-init.js -> fetch bodies). IScriptTagCatalog.GetEquipmentRelativeLeavesAsync
  repurposed to GetEquipmentReferenceNamesAsync(equipmentId, filter).

Tests: EquipmentScriptPaths substitution/extraction (slash pinned); composer<->
artifact reference-resolution byte-parity; DraftValidator unresolved-ref;
ScriptAnalysis completion+diagnostic; M1 authoring gate. Build clean (0/0); all
five affected suites green.

Claude-Session: https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox
2026-07-16 06:58:17 -04:00
Joseph Doherty 6f9e9c5c1b docs(scripteditor): ctx-receiver scoping + SetVirtualTag single-tag-drop note 2026-06-18 02:42:29 -04:00
Joseph Doherty 27c34a556a docs(scripting): document {{equip}} equipment-relative tag paths 2026-06-10 08:14:25 -04:00
Joseph Doherty 4d12088fa2 docs(scripting): Monaco script-editor guide + refresh Scripts page banner 2026-06-09 15:50:49 -04:00