fix(commons): Flow graph orders executions by emission sequence, timestamps only within one clock (arch-review F5)
Central rows carry central's clock, site rows the site's, so the global OccurredAtUtc sort let a 1-2 s skew float a whole site execution ahead of the inbound row / RouteCall that started it, and pushed the trigger-cascade spawner search onto its parentChain[0] fallback. FlowGraphBuilder.Build now orders executions by the input index of their earliest-given row and orders steps by timestamp only INSIDE one execution (one clock), breaking ties by kind rank then input index. A folded outbound node keeps its earliest-by-time row's identity, which need not be the row given first, so its index is the minimum over the rows folded into it. The spawner search uses position in the ordered list rather than a raw timestamp compare. FlowDebugRunner.RunMethodAsync keeps the collector's emission order instead of re-sorting; the value-change path keeps its OrderBy (all rows share one site clock). Replay input arrives timestamp-sorted from the repository, so its order is unchanged. The DelmiaShaped test fixture is still shuffled within each execution (the inside-one-execution timestamp rule is unchanged) but now lists the executions in emission order, since that is what fixes their relative order. Claude-Session: https://claude.ai/code/session_01NcMG6xXdsJbmD2wYAgkK29
This commit is contained in:
@@ -173,8 +173,12 @@ public sealed class FlowDebugRunner
|
||||
result.ErrorMessage ?? "Access denied: routed call outside your site scope.");
|
||||
}
|
||||
|
||||
// Arch-review F5: the collector's emission order is authoritative — central rows carry central's
|
||||
// clock and site rows the site's, so re-sorting by OccurredAtUtc lets a skewed site clock float
|
||||
// its steps ahead of the RouteCall that started them. (The value-change path below keeps its
|
||||
// OrderBy: every row it merges was stamped by the same site.)
|
||||
var ordered = new List<AuditEvent>(events.Count + 1) { inboundRow };
|
||||
ordered.AddRange(events.OrderBy(e => e.OccurredAtUtc).ThenBy(e => e.EventId));
|
||||
ordered.AddRange(events);
|
||||
|
||||
return new FlowDebugRunResult(
|
||||
root, result.Success, result.ErrorMessage, result.Success ? null : result.ErrorCode,
|
||||
|
||||
Reference in New Issue
Block a user