feat(cli): flow-debug run-method|run-value-change|replay

New top-level command group for the Flow Debugger (design 2026-09-05 §7.1). run-method /
run-value-change post the FlowDebugRun* management commands with a 2-minute client wait;
replay posts FlowDebugReplayCommand. A table projection unwraps the FlowDebugRunResult
envelope to one row per step (occurred | kind | lane | target | durationMs | status |
error) using the Commons FlowStepProjector's kind/lane resolution, with a trailing note
row for an incomplete run (error code verbatim, e.g. STANDBY_NODE) or a truncated event
list. --params must be a JSON object (INVALID_PARAMS otherwise). README section added;
command-tree test bumped to 18 groups.

Claude-Session: https://claude.ai/code/session_01GSLkkHKz9JrAtmJjmQK3cP
This commit is contained in:
Joseph Doherty
2026-09-06 00:11:42 -04:00
parent f783d4efc4
commit 0fb7e16ced
6 changed files with 534 additions and 3 deletions
+79
View File
@@ -2270,6 +2270,85 @@ scadabridge --url <url> cached-call discard --site-id <string> --tracked-operati
---
### `flow-debug` — Trace an inbound API or value-change flow end to end
The CLI face of the **Flow Debugger** (design `docs/plans/2026-09-05-flow-debugger-design.md`).
A Live run executes the real thing — the method script on the active central node, or a
real attribute write at the site — with tracing switched on for the whole chain, so every
routed site script run, attribute write and attribute wait it causes is recorded as a
`ScriptTrace` audit row and returned inline. Replay reads those rows back for any past
execution. All three sub-commands require the **Deployer** role.
The two run commands are answered by the node the CLI is pointed at. Through the Traefik
load balancer that is the active node; pointed at a standby node directly they refuse with
error code `STANDBY_NODE` rather than run the script somewhere it would not run in
production. `replay` is served from any node.
Trace steps are ordinary audit rows: a run leaves them in the central `AuditLog`
(channel `ScriptTrace`), so `audit tree --execution-id <rootExecutionId>` shows the same
chain after the fact.
Table output prints one row per step in chronological order —
`occurred | kind | lane | target | durationMs | status | error` — with a trailing `note`
row when the run did not complete (the error code verbatim) or the inline event list was
truncated. `--format json` returns the raw `FlowDebugRunResult` (`rootExecutionId`,
`completed`, `error`, `errorCode`, `events`, `truncated`, `startedAtUtc`, `finishedAtUtc`).
#### `flow-debug run-method`
Run an inbound API method with the given parameters, exactly as an external caller would,
and print the traced flow.
```sh
scadabridge --url <url> flow-debug run-method --method-id <int> [--params <json>]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--method-id` | yes | Inbound API method ID (`api-method list`) |
| `--params` | no | Flat JSON object of parameters, validated against the method's parameter schema. Omit for a parameterless method. |
The client waits up to 2 minutes. Parameters that fail schema validation are reported as
`VALIDATION_FAILED` without running the script.
#### `flow-debug run-value-change`
Write an attribute on a deployed instance through the traced routed-write path, then wait
for the script run(s) the change triggers at the site and print them.
```sh
scadabridge --url <url> flow-debug run-value-change --instance-id <int> --attribute <name> --value <string> [--wait-seconds 45]
```
| Option | Required | Description |
|--------|----------|-------------|
| `--instance-id` | yes | Instance ID |
| `--attribute` | yes | Canonical attribute name to write |
| `--value` | yes | Value to write, in canonical string form |
| `--wait-seconds` | no | How long to wait for a triggered run before reporting `NO_TRIGGER_WITHIN_WINDOW` (default 45) |
The write itself is real — the attribute changes — and is the root step of the flow.
A static attribute triggers directly; a data-sourced attribute triggers when the device
echoes the write back, which the site's trace arm (`SiteRuntime:TraceArmWindowSeconds`,
default 30) correlates back to this run.
#### `flow-debug replay`
Rebuild a past flow from the central audit store.
```sh
scadabridge --url <url> flow-debug replay --execution-id <guid>
```
| Option | Required | Description |
|--------|----------|-------------|
| `--execution-id` | yes | Any execution ID in the chain — the root is resolved server-side |
Only flows whose site legs were traced (a Live run, or a method with `--trace-all-calls`
set) have site steps to replay; an untraced call shows its central `RouteCall` step alone.
---
## Architecture Notes
The CLI connects to the Central cluster over **HTTP** (`ManagementHttpClient`), posting to the `/management` endpoints at the configured `managementUrl` — normally the Traefik load balancer, which routes to the active central node. It carries HTTP **Basic** credentials from `--username`/`--password`. Central's endpoint handler asks the `ManagementActor` in-process via `ManagementActorHolder`.