feat(hosts): driver diagnostics channel on /hosts, S7 negotiated PDU size first (#640)

Claude-Session: https://claude.ai/code/session_01Ef2ozxS7QPanGT8uoATbTe
This commit is contained in:
Joseph Doherty
2026-10-08 16:57:38 -04:00
parent a8b07ae12d
commit c2bdb7d5de
23 changed files with 469 additions and 20 deletions
+17
View File
@@ -112,6 +112,23 @@ it — but it does mean the panel cannot answer "which node saw this?". Adding t
widening the wire record, not changing the page. The one sub-instance breakdown the channel *does*
carry is per-host connectivity, below.
### Driver diagnostics ride `driver-health` (Gitea #640)
A driver may implement the optional `IDriverDiagnostics` (Core.Abstractions): a pure in-memory
`IReadOnlyDictionary<string,string> GetDiagnostics()` of operator-facing facts that are not driver
*state* (S7's negotiated PDU size is the first; others opt in later). `DriverInstanceActor` pulls it on
every health publish (try/caught, unguarded by the invoker like `GetHostStatuses`), bounds it
(`DriverDiagnostics.Bound`: 16 entries, text truncated to 200 chars, ordinal key order), and carries it as
`DriverHealthChanged.Diagnostics` -> proto `DriverHealth.has_diagnostics = 13` / `map<string,string>
diagnostics = 14` (additive; old nodes never set them, old central ignores them) -> `HostsDriverRow.DiagnosticItems`,
rendered as a small key/value list under the driver name on `/hosts` (nothing when empty).
- **null ≠ empty**: null = driver lacks the capability; the presence flag preserves an empty bag.
- **The diagnostics digest is part of the publish fingerprint, and must stay there** - a diagnostic fact
(e.g. PDU size changing on a reconnect) moves no other component, so without it the dedup swallows the
publish. Pinned by `DriverInstanceActorDiagnosticsTests.A_diagnostics_change_republishes_despite_otherwise_unchanged_health`
(stable-health stub - the shared `StubDriver` returns `UtcNow` and would pass vacuously).
### Per-host connectivity rides `driver-health` (Gitea #521)
`DriverHealthChanged.HostStatuses` carries each driver's `IHostConnectivityProbe.GetHostStatuses()`