fix(audit): populate ParentExecutionId on alarm-triggered script runs
M5.4 T4 threaded a `parentExecutionId` parameter through
AlarmActor.SpawnAlarmExecution → AlarmExecutionActor → ScriptRuntimeContext,
but every call site passed null — so alarm on-trigger runs were silently always
execution-tree roots, contradicting the "tag-cascade coverage is complete"
claim in CLAUDE.md and Component-AuditLog.md.
Source the id where a spawner genuinely exists: a static attribute write issued
by a site script (`Instance.SetAttribute`) or by an inbound API request
(`Route.To(...).SetAttributes(...)`, whose ParentExecutionId was already carried
to the site and then dropped). The id rides site-locally through three additive,
nullable fields — no wire, proto or central schema change:
ScriptRuntimeContext.SetAttribute / RouteToSetAttributesRequest.ParentExecutionId
→ SetStaticAttributeCommand.SourceExecutionId
→ AttributeValueChanged.SourceExecutionId (InstanceActor static-write path)
→ AlarmActor.SpawnAlarmExecution → AlarmExecutionActor → ScriptRuntimeContext
All four computed trigger types participate. Expression triggers evaluate off
the dispatcher, so the writer of the newest value folded into the snapshot is
captured *with* the snapshot and echoed home on ExpressionEvalResult /
ExpressionEvalFailed — a change arriving mid-flight cannot mis-attribute the
raise.
Deliberately still roots (documented, not deferred): alarms fired by Data
Connection Layer values (external device data has no spawning execution — this
includes the device echo of a script write to a *data-sourced* attribute, so
only static writes cascade), and ScriptActor value-change/conditional/
expression/timer trigger runs (a timer tick has no spawner; a WhileTrue/interval
run has no single identifiable write).
Tests: new SiteRuntime.Tests/Actors/AlarmCascadeParentExecutionTests pins all
three hops — SetAttribute stamps the run's ExecutionId, InstanceActor publishes
it on the change (and publishes null when absent), and ValueMatch/HiLo/
Expression alarms parent the on-trigger run to the writer while a DCL-originated
change leaves it a root.
Docs: CLAUDE.md and Component-AuditLog.md corrected from "complete" to the true
behaviour; Component-SiteRuntime.md gains an "Audit correlation of an on-trigger
run" section with the hop table and the by-design root cases.
This commit is contained in:
@@ -4,12 +4,28 @@ namespace ZB.MOM.WW.ScadaBridge.Commons.Messages.Instance;
|
||||
/// Command to set a static attribute value on an Instance Actor.
|
||||
/// Updates in-memory state and persists the override to SQLite.
|
||||
/// </summary>
|
||||
/// <param name="CorrelationId">Per-operation correlation id.</param>
|
||||
/// <param name="InstanceUniqueName">Unique name of the target instance.</param>
|
||||
/// <param name="AttributeName">Canonical name of the attribute to write.</param>
|
||||
/// <param name="Value">Canonical string form of the new value.</param>
|
||||
/// <param name="Timestamp">UTC timestamp of the command.</param>
|
||||
/// <param name="SourceExecutionId">
|
||||
/// Audit Log #23 (ParentExecutionId tag-cascade): the <c>ExecutionId</c> of the
|
||||
/// execution issuing this write — a site script run
|
||||
/// (<c>ScriptRuntimeContext.SetAttribute</c>) or the inbound API request behind a
|
||||
/// <c>Route.To(...).SetAttributes(...)</c>. Additive and nullable; <c>null</c>
|
||||
/// when the write has no audited originating execution (central Test Run,
|
||||
/// deployment tooling, tests). The Instance Actor stamps it onto the resulting
|
||||
/// <c>AttributeValueChanged</c> so an alarm the write trips can record it as the
|
||||
/// on-trigger script run's <c>ParentExecutionId</c>.
|
||||
/// </param>
|
||||
public record SetStaticAttributeCommand(
|
||||
string CorrelationId,
|
||||
string InstanceUniqueName,
|
||||
string AttributeName,
|
||||
string Value,
|
||||
DateTimeOffset Timestamp);
|
||||
DateTimeOffset Timestamp,
|
||||
Guid? SourceExecutionId = null);
|
||||
|
||||
/// <summary>
|
||||
/// Response confirming that a static attribute was set.
|
||||
|
||||
Reference in New Issue
Block a user