docs: Flow Debugger — component specs, CLAUDE.md, CLI README, register row 110
Component-CentralUI (new Flow Debugger page section), Component-InboundAPI (TraceAllCalls property, always-on RouteCall row + Trace flag under Routing Behavior, new 'Flow Debugger runs' section), Component-SiteRuntime (Instance Actor trace arm; Script Actor traced runs; CallScript flag inheritance), Component-AuditLog (ScriptTrace channel in Scope, the PullTraceEvents point-read note + mixed-version caveat under Reconciliation, per-channel retention example), Component-Communication (§4 trace flag + inline events with proto field numbers; §8 PullTraceEvents; RPC list), Component-ScriptAnalysis (REQ-SA-7 FlowShapePredictor), CLAUDE.md UI bullet, deferred-work register row 110 (vertical-trace list toggle + console capture), design doc status → implemented. CLI README sections landed in Tasks 3/16. Umbrella index (../scadaproj/CLAUDE.md) checked: its ScadaBridge row records stack/wire relationships only, unchanged by a new page — no edit. Claude-Session: https://claude.ai/code/session_01GSLkkHKz9JrAtmJjmQK3cP
This commit is contained in:
@@ -55,6 +55,10 @@ boundary:
|
||||
| `Database.CachedWrite(...)` | Script | Outbound | Yes — `SiteCalls` (Site Call Audit) |
|
||||
| `Notify.To(list).Send(...)` | Script | Outbound | Yes — `Notifications` (Notification Outbox) |
|
||||
| `POST /api/{method}` (Inbound API) | External | Inbound (invokes a script) | No (gap) |
|
||||
| `Route.To(x).Call(y)` (Inbound API → site) | Script | Central → site | Yes — `ScriptTrace.RouteCall`, **always-on** (2026-09-05) |
|
||||
| Site script run / attribute write / attribute wait under a **traced** run | Script | Site-local | Yes — `ScriptTrace.ScriptRun` / `AttributeWrite` / `AttributeWait`, **gated** by the `Trace` flag (Flow Debugger Live runs, `ApiMethod.TraceAllCalls`) |
|
||||
|
||||
**`AuditChannel.ScriptTrace` (Flow Debugger, design `docs/plans/2026-09-05-flow-debugger-design.md` §5.1).** Trace steps ARE audit events — no parallel store. One kind is always-on (`RouteCall`, a central direct write per `Route.To().Call`, carrying the child run's id in `Extra.childExecutionId`); the three site kinds are emitted only when the run's `Trace` flag is set, ride the ordinary site `IAuditWriter` → SQLite → telemetry → central path, share the run's `ExecutionId` / `ParentExecutionId`, and are additionally returned inline on the routed reply so a Live run does not wait on the 5 s telemetry cadence. The Flow Debugger's graph (`FlowStep` / `FlowGraphBuilder`, Commons) is a central-side projection of these rows.
|
||||
|
||||
Out of scope — framework traffic is not audited:
|
||||
|
||||
@@ -348,6 +352,17 @@ non-draining (e.g., telemetry actor wedged), central issues a
|
||||
`PullAuditEvents(sinceUtc, batchSize[, afterId])` and inserts-if-not-exists.
|
||||
Same self-healing pattern as Site Call Audit's reconciliation of `SiteCalls`.
|
||||
|
||||
**`PullTraceEvents` is a point read, not a reconciliation path (2026-09-05).** The
|
||||
Flow Debugger's value-change run cannot get its steps inline (the device echo
|
||||
triggers the run after the write reply has returned), so central polls the site
|
||||
with `PullTraceEvents(execution_ids[], since_utc, max_events)` — `ISiteAuditQueue.
|
||||
ReadByExecutionIdsAsync`, capped at 64 ids / 2000 events, served whatever the row's
|
||||
`ForwardState` — until the spawned `ScriptRun` settles. It moves no cursor and
|
||||
retires nothing; the telemetry push and the reconciliation pull are unchanged.
|
||||
**Mixed-version caveat:** a pre-2026-09-05 site ignores the `Trace` flag and has no
|
||||
`PullTraceEvents`, so a run against it shows the central `RouteCall` row with no
|
||||
child id and an empty Site lane — the page labels this *site not traced*.
|
||||
|
||||
**The pull is at-least-once (WP2.3).** Serving a row is not proof that central
|
||||
received it, so rows are **not** flipped when they are served. The site flips
|
||||
`ForwardState = 'Reconciled'` for everything at or before the cursor carried by
|
||||
@@ -612,8 +627,10 @@ MS SQL for direct-write events). Unredacted secrets never persist.
|
||||
index did not exist at all. See migration `AlignAuditLogEventIdUniqueness`.
|
||||
- **Per-channel retention overrides (M5.5 T3):** `AuditLog:PerChannelRetentionDays`
|
||||
is a dictionary keyed by canonical channel name (`ApiOutbound`, `DbOutbound`,
|
||||
`Notification`, `ApiInbound`, `SecuredWrite` — all five `AuditChannel` values are
|
||||
accepted by the validator) whose value is a retention window in days that
|
||||
`Notification`, `ApiInbound`, `SecuredWrite`, `Cluster`, `ScriptTrace` — every
|
||||
`AuditChannel` value is accepted by the validator; the docker rig's central nodes
|
||||
set `"ScriptTrace": 30`, the validator floor, because traced runs are a debugging
|
||||
aid, not a compliance record) whose value is a retention window in days that
|
||||
MUST be strictly shorter than the global `RetentionDays`. After the daily
|
||||
partition switch-out, the purge actor runs a bounded, batched row DELETE
|
||||
(`PurgeChannelOlderThanAsync`) for each channel whose override is shorter than
|
||||
|
||||
Reference in New Issue
Block a user