Phase 7 plan doc — scripting runtime + virtual tags + scripted alarms + historian alarm sink #175
Reference in New Issue
Block a user
Delete Branch "phase-7-plan-doc"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Output from the 2026-04-20 interactive planning session. Drafts the last phase before v2 release readiness.
What Phase 7 adds
IAlarmSourceroutes through a local SQLite store-and-forward queue to Galaxy.Host, which writes via its already-loadedaahClientManagedDLLs. Per-alarmHistorizeToAvevatoggle.Locked decisions (22)
Covered in §Design Decisions table. Highlights: C# via Roslyn; read-only sandbox; AST-inferred dependencies; DataValue-returning
ctx.GetTag; per-tag error isolation; dedicatedscripts-*.logsink; template alarm messages; ActiveState recomputed on startup while ack/confirm/shelve persist; SQLite store-and-forward on the node; shelving via OPC UA method calls only (no custom Admin UI); Monaco editor; serial cascade for v1.Eight streams, ~10-12 weeks
Follow-ups from this PR
plan.md§6 Migration Strategy — add Phase 7 row (part of Stream H)config-db-schema.md§§ for the four new tables (part of Stream E)driver-specs.md§Alarm semantics — clarify driver-native vs scripted shape (part of Stream C)Tasks filed
#230 plan draft (complete), #231-#238 stream placeholders pending review.
Locks in 22 design decisions from the planning conversation: C# via Roslyn scripting; virtual tags in the Equipment tree (not a separate /Virtual/ namespace); change-driven + timer-driven triggers operator-configurable per tag; Shape A one-script-per-tag-or-alarm (no predicate/action split); full OPC UA Part 9 alarm fidelity; read-only sandbox (scripts read any tag, write only to virtual tags, no File/HttpClient/Process/reflection); AST-inferred dependencies via CSharpSyntaxWalker (non-literal tag paths rejected at publish); config DB storage with generation-sealed cache; ctx.GetTag returns a full DataValue {Value, StatusCode, Timestamp}; per-tag Historize checkbox; per-tag error isolation (throwing script sets tag quality BadInternalError, engine unaffected); dedicated scripts-*.log Serilog sink bound to ctx.Logger; alarm message as template with {TagPath} substitution resolved at event emission; ActiveState recomputed from tags on startup while EnabledState/AckedState/ConfirmedState/ShelvingState + audit persist to config DB; historian sink scope = all IAlarmSource impls with per-alarm toggle; SQLite store-and-forward on the node so operators are never blocked by Historian downtime; IPC to Galaxy.Host for ingestion reusing the already-loaded aahClientManaged DLLs; Monaco editor for Admin code editing; serial cascade evaluation for v1 (parallel as follow-up); shelving UX via OPC UA method calls only with no custom Admin controls (operator drives state transitions from plant HMIs or Client.CLI); 30-day dead-letter retention with manual retry button; test harness accepts only declared-input paths so the harness enforces dependency declaration. Eight streams totaling ~10-12 weeks, scope-comparable to Phase 6: A - Core.Scripting (Roslyn engine + sandbox + AST inference + logger); B - virtual tag engine (dependency graph + change/timer schedulers + historize); C - scripted alarm engine (Part 9 state machine + template messages + startup recovery + OPC UA method binding); D - historian alarm sink (SQLite store-and-forward + Galaxy.Host IPC contract extension); E - config DB schema (four new tables under sp_PublishGeneration); F - Admin UI scripting tab (Monaco + test harness + dependency preview + script-log viewer + historian diagnostics); G - address-space integration (extend EquipmentNodeWalker for virtual source kind + extend DriverNodeManager dispatch); H - exit gate. Compliance-check surface covers sandbox escape (typeof/Assembly.Load/File/HttpClient attempts must fail at compile), dependency inference (literal-only paths), change cascade (topological ordering), cycle rejection at publish, startup recovery (ack/confirm/shelve survive restart but ActiveState recomputed), ack audit trail persistence, historian queue durability (Galaxy.Host offline → online drains in-order), per-alarm historian toggle gating, script timeout isolation, log sink isolation, ACL binding (virtual tags inherit Equipment scope grants). Follow-up artifacts tracked as tasks #231-#238 (stream placeholders). Supporting doc updates (plan.md §6 Migration Strategy, config-db-schema.md §§ for the four new tables, driver-specs.md §Alarm semantics clarification, new ADR-002 for driver-vs-virtual dispatch) will land alongside the streams that touch them, not in this doc. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>