docs(centralui): 2026-10-21 review hardening (review 2026-10-21 07, 04/C4)

This commit is contained in:
Joseph Doherty
2026-10-22 08:45:51 -04:00
parent 614aade610
commit c55128d83d
+9
View File
@@ -32,6 +32,15 @@ Central cluster only. Sites have no user interface.
- `TemplateFolderTree` compares immutable value snapshots of folder/template hierarchy and extra children before rebuilding. In-place renames, moves, derived-state changes, and composition edits remain visible; filter and reveal changes are applied independently.
- Navigation grants Flow Debugger its own policy and hides Notifications unless the principal holds a role that admits a child. Route-policy coverage freezes every CentralUI route and the external Secrets route.
## Review hardening (2026-10-21)
- **Test Run bound to a deployed instance** (`BindInstanceUniqueName`, `SandboxBoundRunPolicy`) performs real site operations, so it requires the **Deployer** role (a Designer may still run an *unbound* Test Run), is confined to the caller's permitted sites (`SiteScopeService.Resolve` over the request principal; a scoped caller whose instance site cannot be resolved is refused), and writes one best-effort operator-attributed `ScriptTrace`/`RouteCall` audit row (`Extra.source = "test-run"`) via `ICentralAuditWriter`, mirroring the Flow Debugger. Denials return 403 before any worker is started.
- **Script-analysis endpoints** reject script text over 256 KB (and bodies over 1 MB) with 413 and cap concurrent requests per user at 6 (429 beyond that; `ScriptAnalysisRequestGuard`, map entries live only while a request is in flight). The `Diagnose` cache key now includes a hash of the editor context (declared parameters, sibling scripts, self attributes, children, parent), so identical code with different context never shares a cached answer. `BlockingWaitAnalyzer` advisories surface as Monaco **warning** markers (`SCADA_BLOCKING_WAIT`) on the offending line.
- **Template reads:** the Dashboard counts templates from `GetTemplateStubsAsync`; Instance Create, Template Create and Transport Export use the stub projection (adapted to childless `Template` shells); Templates and Template Edit use `GetAllTemplatesForAnalysisAsync` (no tracking, no script bodies, compositions retained). No page loads the full tracked template graph except where it edits one template (`GetTemplateWithChildrenAsync`).
- **Topology live tick** runs behind `PollGate` and a refresh never raises `_loading` (the tree stays mounted); the refreshed lists are swapped in atomically.
- **Pending-updates faults** are remembered for 10 s (`SingleFlightMemo` fault back-off) so the rail indicator's polling does not start a fleet flatten per tick against a sick database; an operator Re-check bypasses it.
- **Circuit hygiene:** `ConfigurationAuditLog` disposes its browser-time JS module; `SessionExpiry` skips the redirect after disposal; `AlarmSummary` and `TreeView` fire-and-forget calls swallow disposal/disconnect races; `FlowDebugService`'s per-circuit script cache is bounded (8 instances); the Site Event Log page retains at most 1000 rows (oldest dropped, with a note) and hints that keyword search covers at most the last 7 days unless a narrower From/To is set (server clamp `ScadaBridge:SiteEventLog:KeywordSearchMaxWindow`).
## Failover Behavior
- A **load balancer** sits in front of the central cluster and routes to the active node.