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:
Joseph Doherty
2026-09-06 00:38:41 -04:00
parent 66d5a67e4f
commit 0a9ef87b54
9 changed files with 60 additions and 3 deletions
@@ -47,6 +47,7 @@ Both central and site clusters. Each side has communication actors that handle m
- Site reads values from the Instance Actor and responds.
- Central returns the response to the external system.
- **Implementation**: this brokered round-trip is served by the **Inbound API's routed-site-script path** — a central-side inbound API method script composes the typed `RouteTo*` verbs on `CommunicationService` (`RouteToCall`, `RouteToGetAttributes`, `RouteToSetAttributes`, `RouteToWaitForAttribute`), driven from `InboundAPI/CommunicationServiceInstanceRouter` and sharing `IntegrationTimeout`. An earlier generic `IntegrationCallRequest` primitive was scaffolded for this pattern but never wired to a producer or a site handler; it was removed as dead code (Gitea #32, 2026-07-23).
- **Trace flag + inline trace events (Flow Debugger, 2026-09-05; additive):** `RouteToCallRequestDto.trace` (field 7) and `RouteToSetAttributesRequestDto.trace` (field 6) carry the `Trace` flag beside the existing `parent_execution_id`; `RouteToCallResponseDto.child_execution_id` (field 6) and `repeated sitestream.AuditEventDto trace_events` (field 7) return the site run's id and its `ScriptTrace` rows in the same reply. `site_command.proto` now imports `sitestream.proto` for the shared `AuditEventDto`. Proto3 defaults are the negotiation: an old site ignores the flag and returns no events; an old central never sets it. `SiteCommandDtoMapper` maps an empty `trace_events` to `null`.
### 5. Recipe/Command Delivery (External System → Central → Site)
- **Pattern**: Fire-and-forget with acknowledgment.
@@ -113,6 +114,7 @@ The streaming protocol is defined in `sitestream.proto` (`src/ZB.MOM.WW.ScadaBri
- `IngestCachedTelemetry(CachedTelemetryBatch) returns (IngestAck)` — ingest receiving surface for the combined cached-call telemetry packet (audit row + `SiteCalls` operational upsert written in one transaction).
- `PullAuditEvents(PullAuditEventsRequest) returns (PullAuditEventsResponse)` — central→site **reconciliation pull** for the Audit Log self-heal feed; the site serves `Pending`/`Forwarded` rows from its `ISiteAuditQueue`. **At-least-once (WP2.3):** rows are NOT retired when served. The site retires (`Reconciled`) everything at or before the cursor of the **next** pull, because that cursor is central's only proof of receipt — a fault between the response leaving the site and central committing it re-serves the rows instead of losing them (central dedups on `EventId`). The request carries an additive composite-keyset `after_id` (field 3) mirroring `PullSiteCallsRequest`; with it the read is a strict `(OccurredAtUtc, EventId)` keyset and the retirement is exact, without it the legacy inclusive `>=` read applies and only rows strictly older than the cursor instant are provably received.
- `PullSiteCalls(PullSiteCallsRequest) returns (PullSiteCallsResponse)` — central→site reconciliation pull for the Site Call Audit (#22) self-heal feed; the site serves operation-tracking rows changed since a cursor from its `IOperationTrackingStore`. A separate RPC from `PullAuditEvents` because the tracking store is the operational source of truth, distinct from the site audit queue.
- `PullTraceEvents(PullTraceEventsRequest) returns (PullTraceEventsResponse)` — central→site **point read** of `ScriptTrace` rows for named execution ids (Flow Debugger value-change runs; see §8). `AttributeValueUpdate` also gained `source_execution_id` (field 7) and `trace` (field 8) so a traced change's provenance reaches central's stream consumers.
- **Messages**: `InstanceStreamRequest` (correlation_id, instance_unique_name, `batching_supported`), `SiteStreamRequest` (correlation_id + `batching_supported` — no instance name; drives the site-wide `SubscribeSite` stream), `SiteStreamEvent` (correlation_id, oneof event: `AttributeValueUpdate`, `AlarmStateUpdate`, `SiteStreamEventBatch`); `AuditEventDto`/`AuditEventBatch`/`IngestAck` for ingest; `CachedTelemetryPacket`/`CachedTelemetryBatch` (each packet pairing an `AuditEventDto` with a `SiteCallOperationalDto`); `PullAuditEventsRequest`/`PullAuditEventsResponse` and `PullSiteCallsRequest`/`PullSiteCallsResponse` (each request carries `since_utc` + `batch_size` + an optional composite-keyset `after_id`; each response carries `more_available` to signal a saturated batch).
- The `oneof event` pattern is extensible — future event types (health metrics, connection state changes) are added as new fields without breaking existing consumers.
- Proto field numbers are never reused; new RPCs and message fields are appended additively. Old clients ignore unknown `oneof` variants — **but "ignore" means the event vanishes silently**, which is why the batch frame below is gated behind an explicit negotiation flag rather than simply emitted.
@@ -275,6 +277,7 @@ Keepalive settings are configurable via `CommunicationOptions`:
- Parked messages (store-and-forward dead letters).
- Site event logs.
- Instance debug snapshots (attribute values and alarm states).
- **Trace events by execution id** — `PullTraceEvents(PullTraceEventsRequest{execution_ids[], since_utc, max_events}) returns (PullTraceEventsResponse{events[]})` on `SiteStreamService` (Flow Debugger, 2026-09-05): a bounded point read of the site audit queue (64 ids / 2000 events, `InvalidArgument` beyond) that the central `FlowDebugRunner` polls for the run a traced value change spawned. Not a reconciliation path — it moves no cursor and does not flip the NodeA→NodeB channel on error. Client: `IPullTraceEventsClient` (Commons) → `GrpcPullTraceEventsClient` (AuditLog, PSK-authenticated like `PullAuditEvents`).
- Central can also send management commands:
- Retry or discard parked messages and parked cached calls — central sends `RetryParkedOperation` / `DiscardParkedOperation` (keyed by `TrackedOperationId`) to the owning site, which applies the change to its S&F buffer and tracking table.