feat(management): FlowDebug run-method / run-value-change / replay commands (Deployer, active-node gated, inline trace)
Flow Debugger (design 2026-09-05 §7.1): FlowDebugRunMethodCommand / FlowDebugRunValueChangeCommand / FlowDebugReplayCommand on the per-node ManagementActor (Deployer role; the two run commands are long-running), all delegating to FlowDebugRunner. RunMethod refuses on a standby with STANDBY_NODE (ManagementCommandException now carries an optional Code that replaces COMMAND_FAILED), validates parameters through the real ParameterValidator/SchemaRefResolver (made public), synthesizes the inbound row (actor = operator, Extra.source = flow-debugger) and runs the method through InboundScriptExecutor with a trace-sink RouteHelper so the reply carries the RouteCall row + the site's inline events. RunValueChange does a traced routed write via IInstanceRouter, then polls IPullTraceEventsClient (interface moved to Commons so ManagementService can consume it) until a ScriptRun parented to the root settles, else NO_TRIGGER_WITHIN_WINDOW. Replay reads IAuditLogRepository.GetTraceEventsAsync. Claude-Session: https://claude.ai/code/session_01GSLkkHKz9JrAtmJjmQK3cP
This commit is contained in:
@@ -183,7 +183,8 @@ public class ManagementActor : ReceiveActor
|
||||
var clientMessage = cause is ManagementCommandException
|
||||
? cause.Message
|
||||
: $"An internal error occurred (CorrelationId={correlationId}).";
|
||||
return new ManagementError(correlationId, clientMessage, "COMMAND_FAILED");
|
||||
var errorCode = cause is ManagementCommandException { Code: { Length: > 0 } code } ? code : "COMMAND_FAILED";
|
||||
return new ManagementError(correlationId, clientMessage, errorCode);
|
||||
}
|
||||
|
||||
// Static readonly role sets for the authorization gate. Single-role arms
|
||||
@@ -304,6 +305,10 @@ public class ManagementActor : ReceiveActor
|
||||
or RetryParkedMessageCommand or DiscardParkedMessageCommand
|
||||
or DebugSnapshotCommand => DeployerOnly,
|
||||
|
||||
// Flow Debugger (design 2026-09-05 §9): Live runs execute scripts and write attributes
|
||||
// on operator input, Replay reads the audit chain — Deployer, like the Debug View.
|
||||
FlowDebugRunMethodCommand or FlowDebugRunValueChangeCommand or FlowDebugReplayCommand => DeployerOnly,
|
||||
|
||||
// Two-person secured write. Submit is an Operator action;
|
||||
// approve/reject are Verifier actions. Separation of duties (a write may
|
||||
// not be verified by its submitter) is enforced inside the handler — the
|
||||
@@ -401,6 +406,11 @@ public class ManagementActor : ReceiveActor
|
||||
DeleteDataConnectionCommand cmd => await HandleDeleteDataConnection(sp, cmd, user.Username),
|
||||
MoveDataConnectionCommand cmd => await HandleMoveDataConnection(sp, cmd, user.Username),
|
||||
|
||||
// Flow Debugger (design 2026-09-05 §7.1) — one execution path for the UI and the CLI.
|
||||
FlowDebugRunMethodCommand cmd => await sp.GetRequiredService<FlowDebug.FlowDebugRunner>().RunMethodAsync(sp, cmd, user, CancellationToken.None),
|
||||
FlowDebugRunValueChangeCommand cmd => await sp.GetRequiredService<FlowDebug.FlowDebugRunner>().RunValueChangeAsync(sp, cmd, user, CancellationToken.None),
|
||||
FlowDebugReplayCommand cmd => await sp.GetRequiredService<FlowDebug.FlowDebugRunner>().ReplayAsync(sp, cmd, CancellationToken.None),
|
||||
|
||||
// External Systems
|
||||
ListExternalSystemsCommand => await HandleListExternalSystems(sp),
|
||||
GetExternalSystemCommand cmd => await HandleGetExternalSystem(sp, cmd),
|
||||
@@ -4207,4 +4217,16 @@ public class ManagementCommandException : Exception
|
||||
/// <summary>Initializes a new instance with the given caller-safe error message.</summary>
|
||||
/// <param name="message">The error message to surface verbatim to the HTTP/CLI caller.</param>
|
||||
public ManagementCommandException(string message) : base(message) { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance with a caller-safe message AND a machine-readable error code
|
||||
/// that replaces the generic <c>COMMAND_FAILED</c> on the <c>ManagementError</c> reply
|
||||
/// (Flow Debugger design 2026-09-05 §7.1: <c>STANDBY_NODE</c>, <c>NO_TRIGGER_WITHIN_WINDOW</c>).
|
||||
/// </summary>
|
||||
/// <param name="message">The error message to surface verbatim to the HTTP/CLI caller.</param>
|
||||
/// <param name="code">The error code to surface as <c>ManagementError.ErrorCode</c>.</param>
|
||||
public ManagementCommandException(string message, string code) : base(message) { Code = code; }
|
||||
|
||||
/// <summary>Optional machine-readable error code; null = <c>COMMAND_FAILED</c>.</summary>
|
||||
public string? Code { get; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user