Joseph Doherty
9110a4eb01
fix(auditlog,health): harden hosted-service shutdown against disposed CTS
...
The host does not guarantee IHostedService.StopAsync is driven before the DI
container is disposed — WebApplicationFactory's teardown reaches Dispose first
— so cancelling the internal CTS from StopAsync threw ObjectDisposedException
and aborted the host's whole shutdown sequence. Four services shared the same
copy-pasted lifecycle and the same two races: StopAsync cancelling an already-
disposed CTS, and StartAsync reading _cts.Token lazily inside the Task.Run
lambda, which faults the loop task the host awaits when Dispose wins that race.
Each service now captures the token on the caller's thread, tolerates a
disposed CTS, and cancels-before-disposing so the loop is always signalled and
its pending Task.Delay sees a cancelled token rather than a dead source.
SiteAuditBacklogReporter also gains the outer OperationCanceledException guard
its sibling SiteAuditRetentionService already carried (arch-review 04 R2, R7),
without which a shutdown landing mid-probe threw TaskCanceledException out of
Host.StopAsync.
Surfaced while verifying the Gitea #15 test-harness fix: in Host.Tests the
aborted teardown skipped the fixture's env-var restore, contaminating every
later test in the run.
Refs: Gitea #15
2026-07-16 23:31:19 -04:00
Joseph Doherty
128f159692
feat(secrets): resolve MxGateway ApiKey secret: refs at connect time (ScadaBridge G-3 T9)
2026-07-16 15:37:01 -04:00
Joseph Doherty
56b428d2ef
docs(secrets): clustered master-key posture runbook + Central pointer (ScadaBridge G-5 T8)
2026-07-16 15:21:54 -04:00
Joseph Doherty
41e17d2ff8
feat(secrets): mount /admin/secrets + register secrets authz in CentralUI (ScadaBridge G-6 T7)
2026-07-16 15:09:34 -04:00
Joseph Doherty
cf715b813b
feat(secrets): switch Central config secrets to ${secret:} tokens (ScadaBridge G-4 T4)
...
Switch the three literal ${SCADABRIDGE_*} placeholders in appsettings.Central.json
to ${secret:} references resolved by the pre-host secrets expander, and update the
_secrets doc note. Fix Host.Tests fixtures that boot the real Program pipeline against
Central config: CentralDbTestEnvironment now also supplies the LDAP service-account
password and JWT signing key as whole-key env overrides (rollback path) so the expander
skips the tokens without a seeded store; the three fixtures that managed env vars
inline now use CentralDbTestEnvironment.
2026-07-16 14:42:28 -04:00
Joseph Doherty
abc9c96af0
feat(secrets): register runtime AddZbSecrets on Central + Site roles (ScadaBridge T3)
2026-07-16 14:26:16 -04:00
Joseph Doherty
ae62e650e9
feat(secrets): pre-host ${secret:} config expander (ScadaBridge G-4 T2)
2026-07-16 14:13:53 -04:00
Joseph Doherty
481d6d7265
build(secrets): add ZB.MOM.WW.Secrets 0.1.2 package refs (ScadaBridge G-3/4/5/6 T1)
2026-07-16 14:09:44 -04:00
Joseph Doherty
ccee558ca7
merge(r2): r2-plan08
...
# Conflicts:
# src/ZB.MOM.WW.ScadaBridge.Communication/CommunicationOptionsValidator.cs
2026-07-13 11:10:15 -04:00
Joseph Doherty
ca4b0dd849
merge(r2): r2-plan04
2026-07-13 11:09:36 -04:00
Joseph Doherty
699af8fc16
merge(r2): r2-plan06
...
# Conflicts:
# CLAUDE.md
2026-07-13 11:09:24 -04:00
Joseph Doherty
84fdea60cf
merge(r2): r2-plan05
2026-07-13 11:08:27 -04:00
Joseph Doherty
3ad5ad0d7e
merge(r2): r2-plan03
2026-07-13 11:08:27 -04:00
Joseph Doherty
774e3918db
merge(r2): PLAN-R2-07 UI/Management/Security
2026-07-13 11:08:10 -04:00
Joseph Doherty
2751a6dba9
test(management): freeze scrubber fragment coverage over DataConnection config types + document array-merge limit (plan R2-07 T12)
2026-07-13 11:05:19 -04:00
Joseph Doherty
1b88ca1296
fix(security): amortize LoginThrottle.Prune off the failed-bind hot path (plan R2-07 T11)
2026-07-13 11:03:26 -04:00
Joseph Doherty
5b16429635
fix(sitestream): deathwatch resets live-cache liveness on aggregator termination (plan R2-07 T10)
2026-07-13 11:01:54 -04:00
Joseph Doherty
56d39b5fce
fix(host): site singletons (deployment-manager, event-log-handler) via SingletonRegistrar — PhaseClusterLeave drains for site SQLite writes (plan R2-01 T11)
2026-07-13 11:01:44 -04:00
Joseph Doherty
80b967681e
chore(hygiene): fix stale area-export comment in EntitySerializer.FromBundleContent — areas travel by name since PLAN-05 (plan R2-08 T12, arch-review 08r2 NF6)
2026-07-13 10:58:52 -04:00
Joseph Doherty
76ef97f729
fix(ui): disposal guard on Alarm Summary live callback, matching the DebugView pattern (plan R2-07 T9)
2026-07-13 10:58:50 -04:00
Joseph Doherty
7943d73e71
fix(options): canonicalize Communication/DataConnection config sections to ScadaBridge:*; drop the duplicate Host bindings that were masking the drift (plan R2-08 T9, arch-review 08r2 NF8)
2026-07-13 10:58:28 -04:00
Joseph Doherty
925c869826
fix(ui): Alarm Summary poll defers row rebuilds to the live path while IsLive (plan R2-07 T8)
2026-07-13 10:57:09 -04:00
Joseph Doherty
d33337a834
fix(ui): drop stale-site poll results on Alarm Summary site switch (plan R2-07 T7)
2026-07-13 10:55:25 -04:00
Joseph Doherty
973e59de84
fix(options): bind + validate OperationTrackingOptions; register the site IOperationTrackingStore that two comments claimed AddSiteRuntime provides (plan R2-08 T8, arch-review 08r2 NF4)
...
VERIFY-THEN-FIX: the plan-authoring discovery is CONFIRMED. No code anywhere in
src/ registered IOperationTrackingStore in DI, yet AkkaHostedService and
AuditLog SCE both comment that AddSiteRuntime provides it. Every consumer
resolved it via GetService (null-tolerant) and silently ran degraded:
cached-drain scheduler never armed, PullSiteCalls reconciliation seam never
wired, Tracking.Status degraded to audit-only. This is a FUNCTIONAL FIX riding
the hygiene plan: AddSiteRuntime now registers the store (site-only), so
site-local cached-call tracking runs in its intended mode. OperationTrackingOptions
is now bound + eagerly validated in the Host site-options block.
2026-07-13 10:53:27 -04:00
Joseph Doherty
1fcfa4fb16
fix(security): scope-filter secured-write listing + align spec with enforced site scoping (plan R2-07 T6)
2026-07-13 10:53:16 -04:00
Joseph Doherty
80e5b36852
refactor(host): CentralSingletonRegistrar -> SingletonRegistrar with optional role scope — unblocks site-singleton drains (plan R2-01 T10)
2026-07-13 10:49:49 -04:00
Joseph Doherty
4a0462e4d0
fix(options): validate Host Node/Database/Logging options at startup — empty NodeName fails fast instead of NULLing SourceNode (plan R2-08 T7, arch-review 08r2 NF4)
2026-07-13 10:49:42 -04:00
Joseph Doherty
92936747b7
fix(security): additive permitted-sites filter on secured-write query/count (plan R2-07 T5)
2026-07-13 10:48:45 -04:00
Joseph Doherty
c2707fdcf8
docs(health): CentralHealthReportLoop comments say oldest-member, not cluster leader — stop re-teaching the S2 conflation (plan R2-01 T9)
2026-07-13 10:46:18 -04:00
Joseph Doherty
9b9222d223
fix(security): enforce LDAP-mapping site scope on secured-write submit/approve/reject (plan R2-07 T4)
2026-07-13 10:46:08 -04:00
Joseph Doherty
11efe4be05
fix(health): flag metrics-stale for never-reported sites via FirstSeenAt anchor — null LastReportReceivedAt no longer skips the check (plan R2-01 T8)
2026-07-13 10:45:22 -04:00
Joseph Doherty
f85f036b09
fix(options): eager startup validation for AuditLog central sub-options — PartitionMaintenance, Purge, Reconciliation (plan R2-08 T6, arch-review 08r2 NF4)
2026-07-13 10:39:03 -04:00
Joseph Doherty
b532a1e30e
fix(security): trusted-proxy ForwardedHeaders so LoginThrottle keys on the real client IP (plan R2-07 T2)
2026-07-13 10:38:41 -04:00
Joseph Doherty
e0dddac0be
fix(options): eager startup validation for AuditLog site sub-options — SiteWriter, SiteTelemetry, SiteRetention (plan R2-08 T5, arch-review 08r2 NF4)
2026-07-13 10:36:46 -04:00
Joseph Doherty
e1a692016e
fix(security): throttle DebugStreamHub LDAP bind via ManagementAuthenticator + correct coverage doc (plan R2-07 T1)
2026-07-13 10:36:32 -04:00
Joseph Doherty
c573d8cac6
fix(audit-log): retention loop absorbs shutdown cancellation instead of faulting host StopAsync (plan R2-04 T12)
2026-07-13 10:28:03 -04:00
Joseph Doherty
c83b51fe9c
fix(comm): single-gRPC-endpoint sites can go live (flip degenerates to same-node reconnect) (plan R2-02 T15)
2026-07-13 10:26:43 -04:00
Joseph Doherty
8f46b6cec2
fix(sitecallaudit): time-sliced terminal purge replaces the single year-scale DELETE (plan R2-04 T11)
2026-07-13 10:26:33 -04:00
Joseph Doherty
41ffe42de3
docs(comm): accept + document standby aggregators and deleted-site viewer behavior; fix aggregator e2e ctor call for new params (plan R2-02 T14)
2026-07-13 10:25:10 -04:00
Joseph Doherty
3d6973cc89
perf(sitecallaudit): filtered IX_SiteCalls_Terminal index backs the retention purge predicate (plan R2-04 T10)
2026-07-13 10:23:19 -04:00
Joseph Doherty
4e228110ec
fix(comm): site delete disposes the site's cached gRPC channels via RemoveSiteAsync (plan R2-02 T13)
2026-07-13 10:22:56 -04:00
Joseph Doherty
439dee52d3
fix(kpi): classify the failover fold-race pass loss as a self-healing Information event (plan R2-04 T9)
2026-07-13 10:21:02 -04:00
Joseph Doherty
b7f8632db8
chore(comm): ctor-inject aggregator reconnect/stability tuning, remove process-global statics (plan R2-02 T12)
2026-07-13 10:19:51 -04:00
Joseph Doherty
c29e588905
fix(comm): queue failover re-seed behind in-flight fan-out; stamp stream generation on gRPC errors (plan R2-02 T11)
2026-07-13 10:18:16 -04:00
Joseph Doherty
cd93ad3976
fix(kpi): promote catalog metric literals to shared KpiMetrics constants — drift becomes a compile error (plan R2-04 T8)
2026-07-13 10:15:40 -04:00
Joseph Doherty
bb8be55382
perf(comm): coalesce live-alarm delta publishes (250ms window, 0 = legacy) (plan R2-02 T10)
2026-07-13 10:14:54 -04:00
Joseph Doherty
1c8b2bc745
docs(kpi): trend charts state per-bucket-total semantics for rate metrics (plan R2-04 T7)
2026-07-13 10:12:58 -04:00
Joseph Doherty
cc4ff7029d
chore(saf): eagerly validate SweepBatchLimit/SweepTargetParallelism (plan R2-02 T9)
2026-07-13 10:10:34 -04:00
Joseph Doherty
9a1b160e79
fix(kpi): query service applies catalog aggregation at the bucketer — rate charts keep one unit across the raw/rollup boundary (plan R2-04 T6)
2026-07-13 10:10:30 -04:00
Joseph Doherty
61442b5f81
fix(saf): publish _sweepTask only on CAS win so StopAsync drains the real in-flight sweep (plan R2-02 T8)
2026-07-13 10:09:40 -04:00