Files
lmxopcua/code-reviews/Core.Scripting.Abstractions/findings.md
T
Joseph Doherty 145b06bec9 review(Core.Scripting.Abstractions): refresh stale Phase7 labels + document {{equip}}
First review at 7286d320. Five Low doc fixes (BadNodeIdUnknown comment parity, three stale
Phase7 labels -> design-doc cites, {{equip}} token doc on GetTag/SetVirtualTag). Deadband
NaN/negative-tolerance (004) + a stale docs path (007) left Open.
2026-06-19 11:06:56 -04:00

8.9 KiB
Raw Blame History

Code Review — Core.Scripting.Abstractions

Field Value
Module src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions
Reviewer Claude Code
Review date 2026-06-19
Commit reviewed 7286d320
Status Reviewed
Open findings 2

Checklist coverage

A comprehensive review completes every category, recording "No issues found" where a category produced nothing rather than leaving it blank.

# Category Result
1 Correctness & logic bugs 1 finding (Core.Scripting.Abstractions-004)
2 OtOpcUa conventions No issues found
3 Concurrency & thread safety No issues found
4 Error handling & resilience No issues found
5 Security No issues found
6 Performance & resource management No issues found
7 Design-document adherence 1 finding (Core.Scripting.Abstractions-007)
8 Code organization & conventions No issues found
9 Testing coverage No issues found
10 Documentation & comments 5 findings (001003, 005006)

Findings

Core.Scripting.Abstractions-001

Field Value
Severity Low
Category Documentation & comments
Location src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/AlarmPredicateContext.cs:43,46
Status Resolved

Description: AlarmPredicateContext.GetTag uses the magic constant 0x80340000u twice with no inline comment. The sibling VirtualTagContext.GetTag annotates both sites with /* BadNodeIdUnknown */, making the intent immediately clear. The inconsistency makes the alarm context harder to audit for correctness.

Recommendation: Add /* BadNodeIdUnknown */ inline comments matching the pattern in VirtualTagContext.cs:55,58.

Resolution: Applied inline — added /* BadNodeIdUnknown */ comments to both 0x80340000u literals in AlarmPredicateContext.GetTag. Verified by build (no test project for this module). 2026-06-19.


Core.Scripting.Abstractions-002

Field Value
Severity Low
Category Documentation & comments
Location src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/AlarmPredicateContext.cs:14
Status Resolved

Description: The <remarks> block opens with "Per Phase 7 plan Shape A decision...". The project-wide rename (master commit 40e8a23e) retired the "Phase 7" prefix for the address-space pipeline; comments referencing it by that name are stale and confuse new readers. The authoritative plan document is docs/v2/implementation/phase-7-scripting-and-alarming.md (decision row 4, Shape A), so the relevant fix is to cite the design doc rather than the internal plan-phase label.

Recommendation: Replace "Per Phase 7 plan Shape A decision" with "Per the scripting design (see docs/v2/implementation/phase-7-scripting-and-alarming.md, decision row 4)".

Resolution: Applied inline — updated the stale "Phase 7 plan Shape A decision" reference to cite the design doc directly. Verified by build (no test project for this module). 2026-06-19.


Core.Scripting.Abstractions-003

Field Value
Severity Low
Category Documentation & comments
Location src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/ScriptContext.cs:9,10
Status Resolved

Description: The ScriptContext summary comment reads "Phase 7 plan decision #6: scripts can read any tag, write only to virtual tags...". The "Phase 7 plan" label is stale after the global rename. Decision #6 in docs/v2/plan.md remains the correct reference, but the wording should match the current naming convention.

Recommendation: Replace "Phase 7 plan decision #6" with "plan decision #6 (see docs/v2/plan.md)".

Resolution: Applied inline — updated the stale "Phase 7 plan decision #6" reference to use the current naming convention. Verified by build (no test project for this module). 2026-06-19.


Core.Scripting.Abstractions-004

Field Value
Severity Low
Category Correctness & logic bugs
Location src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/ScriptContext.cs:84
Status Open

Description: ScriptContext.Deadband has no guard or documentation for invalid tolerance values. A negative tolerance makes Math.Abs(current - previous) > tolerance trivially true for all finite inputs (any absolute value exceeds a negative number), so Deadband(x, y, -1.0) always reports a change regardless of the actual difference — silently inverting the intended semantics. A NaN tolerance makes the comparison always false (no change ever detected). Neither case is caught by the compiler and there is no runtime warning, so script authors have no feedback when they supply an invalid threshold.

Recommendation: Document the behavior clearly in the <param name="tolerance"> XML doc. If a design decision allows it, add an ArgumentOutOfRangeException guard for tolerance < 0, but this changes the public API contract for authored scripts and needs a plan-level decision. Minimum fix (doc-only, zero-risk):

/// <param name="tolerance">The minimum change magnitude to detect (must be &gt;= 0).
///     Negative values cause the function to always return true; NaN always returns false.</param>

Resolution: (Open — the doc-only fix is zero-risk but the tolerance param is part of the locked script API surface; the decision on whether to also add a guard belongs at the plan level. Deferred until that call is made. No test project exists for this module.)


Core.Scripting.Abstractions-005

Field Value
Severity Low
Category Documentation & comments
Location src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/VirtualTagContext.cs:21
Status Resolved

Description: The <remarks> second paragraph ends with "Mutable state across runs is a future decision (e.g. a dedicated ctx.Memory dictionary); not in scope for Phase 7." The "Phase 7" label is stale (see findings 002 and 003). The forward-looking note itself is still valid.

Recommendation: Replace "not in scope for Phase 7" with "not currently in scope".

Resolution: Applied inline — removed the stale Phase 7 label. Verified by build (no test project for this module). 2026-06-19.


Core.Scripting.Abstractions-006

Field Value
Severity Low
Category Documentation & comments
Location src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/ScriptContext.cs:35-36,55-58
Status Resolved

Description: The <summary> for ScriptContext.GetTag describes the path syntax as "forward-slash delimited, matching the Equipment-namespace browse tree" but makes no mention of the {{equip}} equipment-relative token introduced in master commit 27c34a55. Operators reading the XML doc for IntelliSense will not know the token exists. The SetVirtualTag remarks similarly omit it.

Recommendation: Add a note to the GetTag (and SetVirtualTag) <remarks>: "The reserved {{equip}} token may appear in the path literal; it is substituted with the owning equipment's tag-base prefix at deployment time. See docs/ScriptEditor.md — Equipment-relative tag paths."

Resolution: Applied inline — added {{equip}} token mention to GetTag and SetVirtualTag remarks in ScriptContext.cs. Verified by build (no test project for this module). 2026-06-19.


Core.Scripting.Abstractions-007

Field Value
Severity Low
Category Design-document adherence
Location docs/ScriptedAlarms.md:298
Status Open

Description: docs/ScriptedAlarms.md line 298 lists the file path as src/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms/AlarmPredicateContext.cs. The file was moved to src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/AlarmPredicateContext.cs as part of the A0 memory-reduction plan (docs/plans/2026-06-07-virtualtag-script-memory.md, step 1 git mv list). The stale path sends readers to a non-existent location. The namespace was intentionally preserved (Core.ScriptedAlarms) so no using changes were needed — the file location is the only thing that changed.

Recommendation: Update docs/ScriptedAlarms.md line 298:

- `src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/AlarmPredicateContext.cs` — script-side `ScriptContext` (read-only, write rejected)

Resolution: (Open — out of scope for this module's src-only fix pass. Should be fixed in a docs-cleanup commit targeting docs/ScriptedAlarms.md.)