Joseph Doherty
ccdc649641
feat(kpihistory): classify KPI metrics gauge-vs-rate for hourly rollups (plan #22 T2)
...
Add KpiRollupAggregation { Gauge, Rate } enum + KpiMetricAggregationCatalog.Resolve(source, metric)
that the hourly rollup fold (T3) consults. Rate = sum-per-hour for per-interval delta counters;
Gauge = last-value-per-hour default (also the safe fallback for unknown/new metrics, never throws).
totalEventsLastHour/errorEventsLastHour classified Gauge (rolling trailing-hour counts, not
per-interval deltas) per authoritative source semantics.
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 11:45:54 -04:00
Joseph Doherty
22136d36d9
feat(testrun): route WaitForAttribute in the Test-Run sandbox (deferred #14 )
...
Closes deferred-work register item #14 with full fidelity. The Central UI Test-Run
sandbox previously threw ScriptSandboxException for Attributes.WaitAsync/WaitForAsync;
now the value-equality forms route to the bound deployed instance over the same
cross-site path inbound Route.To().WaitForAttribute() uses.
- Commons: additive trailing RouteToWaitForAttributeRequest.RequireGoodQuality
(default false; message-evolution safe) so quality-gated waits route too.
- SiteRuntime: DeploymentManagerActor's routed-wait handler now threads
request.RequireGoodQuality into the InstanceActor WaitForAttributeRequest
(previously hard-coded to default).
- CentralUI sandbox: ISandboxInstanceGateway.WaitForAttributeAsync +
SandboxInstanceGateway impl (via CommunicationService.RouteToWaitForAttributeAsync);
SandboxAttributeAccessor value-equality WaitAsync/WaitForAsync route through it
(codec-encoded target, scope-resolved name). Predicate overloads stay unsupported
(an in-process lambda can't be routed) and throw a clearer, dedicated message.
- Tests: sandbox accessor routing + predicate/unbound rejection (CentralUI);
site-handler RequireGoodQuality threading (SiteRuntime). Register + the historical
waitfor-deferred plan doc updated.
Full slnx build 0/0; CentralUI 59, SiteRuntime routed-wait 4, InboundAPI wait 32 green.
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 09:29:38 -04:00
Joseph Doherty
4cd21b342b
feat(auditlog): make SiteAuditBacklogReporter cadence configurable (deferred #21 )
...
Consolidates the reporter's poll cadence onto SqliteAuditWriterOptions instead of
the hard-coded 30 s constant, closing deferred-work register item #21 (the config-
shape cleanup its own XML doc flagged as a follow-up).
- SqliteAuditWriterOptions.BacklogPollIntervalSeconds (default 30).
- Reporter reads it via IOptions; precedence explicit-override (tests) > configured
> 30 s default; a non-positive value falls back to the default. Corrected the
stale "hard-code / tunable in a follow-up" class-doc.
- Cadence tests + register updated (row 21 -> Resolved).
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 08:56:32 -04:00
Joseph Doherty
f480a56737
feat(instance): native-alarm-source-override CSV bulk import (deferred #12 ) + doc fixes
...
Closes the operator parity gap the deferred-work register tracked as #12 : native
alarm source overrides could only be set one-at-a-time, while attribute overrides
had a CSV bulk path. Adds an all-or-nothing CSV import for native sources.
- Commons: extract the RFC-4180 line splitter into a shared CsvLineSplitter
(refactor OverrideCsvParser onto it — no behavior change, pinned by its tests);
new NativeAlarmSourceOverrideCsvParser (header SourceName,Connection,
SourceReference,Filter; blank = inherited).
- Commons: NativeAlarmSourceOverrideEntry + bulk SetInstanceNativeAlarmSource-
OverridesCommand (auto-registered via the reflection command registry).
- ManagementService: Deployer-gated handler — flattens once, validates every
source resolves + is unlocked + no duplicates up front, then upserts the whole
batch under a single SaveChanges (true all-or-nothing txn). Added to the frozen
authorization matrix; dispatch-coverage guard passes.
- CLI: `instance native-alarm-source import --instance-id --file` (parity with
`instance import-overrides`) + README.
- Tests: native parser (Commons), CLI parse/entry mapping, 3 bulk-handler tests
(happy path single-commit, locked-source reject, unresolved-source reject).
Also corrects a stale XML-doc line in ScriptRuntimeContext (WaitForAttribute
quality-gated mode is shipped, not "planned") and updates the deferred-work
register: marks #7/#13/#15/#16/#20 verified-resolved, #12 as CLI/API-shipped with
only the Central UI upload affordance still pending.
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 08:52:12 -04:00
Joseph Doherty
d61881ffaf
refactor(site-runtime): excise vestigial site-side notification-list surface — repo, DI registration, dead write paths (arch-review 08 §1.3/#23)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 07:00:09 -04:00
Joseph Doherty
e156c7fa8a
test(commons): contract-lock tests for top ClusterClient records — enforce additive-only evolution under version skew (arch-review 08 §1.8)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:53:30 -04:00
Joseph Doherty
fcc9c7bf8e
test(perf): failover-timing harness placeholder documenting the 25s envelope protocol, pending PLAN-01 two-node rig (arch-review 08 §2.3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:53:30 -04:00
Joseph Doherty
b879e51541
test(perf): site-wide stream throughput measurement — first real perf-envelope test (arch-review 08 §2.3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:53:30 -04:00
Joseph Doherty
6bf9dfb3c5
feat(options): eager startup validation for central-component options (Transport, SiteCallAudit, DeploymentManager) (arch-review 08 §1.5)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:53:30 -04:00
Joseph Doherty
fc918d4679
feat(options): eager startup validation for edge/management options (InboundAPI, ESG, Notification, ManagementService) (arch-review 08 §1.5)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:53:30 -04:00
Joseph Doherty
8b775f4ae1
feat(options): eager startup validation for site-pipeline options (SiteRuntime, S&F, SiteEventLog) (arch-review 08 §1.5)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:53:30 -04:00
Joseph Doherty
af2cfde484
feat(options): eager startup validation for Communication + DataConnectionLayer options (arch-review 08 §1.5)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:53:30 -04:00
Joseph Doherty
884f9127b2
test(commons): update AuditKind lock-in test to 16 members (SecuredWriteExpire from T15)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:16:07 -04:00
Joseph Doherty
d6bad1738e
fix(management): single-flight transport bundle commands + drop redundant export copy (arch-review S4)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 06:04:22 -04:00
Joseph Doherty
433c6db4ec
feat(cli): browse/search/verify-endpoint/cert-trust commands — actor parity (arch-review C4)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:57:58 -04:00
Joseph Doherty
d8a39f3c35
feat(ui): secured-write history paging + submission age in approve dialog (arch-review S2/P3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:57:58 -04:00
Joseph Doherty
655834f0b8
feat(management): additive Skip/Take paging on template/instance lists (arch-review P2)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:57:14 -04:00
Joseph Doherty
8221ee797e
fix(management): canonicalize role-mapping casing at write path, closing UI/actor case split (arch-review C5)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:52:45 -04:00
Joseph Doherty
83e09fc210
fix(management): honor MgmtDeployArtifactsCommand.SiteId + enforce site scope (arch-review C2)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:51:03 -04:00
Joseph Doherty
5b00c049f8
test(management): dispatch-coverage test — every registered command has a handler (arch-review UA2)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:43:27 -04:00
Joseph Doherty
61df8a28fe
test(management): frozen GetRequiredRoles matrix over every registered command (arch-review UA2)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:43:27 -04:00
Joseph Doherty
8d4ffa7ef1
feat(management): secured-write list paging with TotalCount (arch-review P3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:42:35 -04:00
Joseph Doherty
03295e91bb
feat(management): opportunistic expiry sweep on secured-write list (arch-review S2)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:39:29 -04:00
Joseph Doherty
064a7d9415
feat(management): server-side secured-write TTL — stale pending writes expire, never execute (arch-review S2)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:38:19 -04:00
Joseph Doherty
5415e6566f
feat(management): Admin-gated actor dispatch for cert-trust commands (arch-review C4)
...
Made CommunicationService.TrustServerCertAsync/RemoveServerCertAsync/ListServerCertsAsync virtual to support the test seam (mirrors existing virtual WriteTagAsync).
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:29:57 -04:00
Joseph Doherty
722063638b
feat(management): actor dispatch for BrowseNode/SearchAddressSpace/VerifyEndpoint — CLI parity (arch-review C4)
...
Made CommunicationService.BrowseNodeAsync/SearchAddressSpaceAsync/VerifyEndpointAsync virtual to support the test seam (mirrors existing virtual WriteTagAsync).
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:27:48 -04:00
Joseph Doherty
51cff07753
fix(management): reconcile area role gate to Designer|Deployer across actor and all three docs (arch-review C6)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:23:57 -04:00
Joseph Doherty
75bf14a35a
chore(ui): memoize AlarmSummary rows + keyboard/aria-sort on sortable headers (arch-review P4/UA6)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:16:40 -04:00
Joseph Doherty
7af36fd5dc
feat(security): wire LoginThrottle into management Basic-Auth and /auth/login|token — password-spray guard (arch-review P1/UA5)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:16:40 -04:00
Joseph Doherty
d4d1732a9e
fix(management): elide DatabaseConnection ConnectionString from List/Get (arch-review C3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:15:55 -04:00
Joseph Doherty
ecf8ac1b7d
fix(management): elide ExternalSystem AuthConfiguration from responses and audit (arch-review C3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:14:04 -04:00
Joseph Doherty
3a1980cb4c
fix(management): elide DataConnection config secrets from responses and audit (arch-review C3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:12:29 -04:00
Joseph Doherty
adc488a9f9
fix(ui): reentrancy guard on Health/AlarmSummary poll timers (arch-review S3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:04:18 -04:00
Joseph Doherty
bd6c310825
feat(security): LoginThrottle — per-username+IP LDAP-bind failure lockout (arch-review P1)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:04:18 -04:00
Joseph Doherty
fb491a5342
feat(commons): additive SiteIdentifier on browse/verify/cert-trust commands for management-API routing (arch-review C4)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:04:18 -04:00
Joseph Doherty
7206761cb4
fix(management): 5-min Ask timeout for transport/deploy commands (arch-review S1)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:04:18 -04:00
Joseph Doherty
0fad6817c2
feat(config-db): secured-write TryMarkExpiredAsync CAS + CountAsync (arch-review S2/P3)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:04:18 -04:00
Joseph Doherty
5cfa85ea91
feat(management): ConfigSecretScrubber for connection-config secret elision
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:04:18 -04:00
Joseph Doherty
efa6ac223c
feat(deployment): DeployToSiteAsync for single-site artifact deployment
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:04:18 -04:00
Joseph Doherty
6c9de9f7ab
feat(management): any-of role gates; restrict ListSecuredWrites to Operator/Verifier/Admin (arch-review UA1)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 05:03:51 -04:00
Joseph Doherty
40088a2123
fix(notifications): validate Twilio AccountSid format at save — closes the un-escaped URI interpolation door
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:36:47 -04:00
Joseph Doherty
37cf7c1a44
fix(esg): cancellation-aware ErrorClassifier.IsTransient overload — caller-cancelled work can never classify transient
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:36:47 -04:00
Joseph Doherty
0ee9975111
feat(notifications): OAuth2 authority/scope management + CLI + UI surfaces
...
Additive UpdateSmtpConfigCommand params (OAuth2Authority/OAuth2Scope),
preserve-on-null handler application, CLI --oauth2-authority/--oauth2-scope
on smtp update, Central UI text inputs shown only for the OAuth2 auth type,
and the Component-NotificationService doc paragraph with M365 defaults.
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:30:28 -04:00
Joseph Doherty
2e7be1e852
fix(esg): structured JSON AuthConfiguration (matches entity doc + UI placeholders) with legacy colon fallback — keys containing ':' no longer misparse
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:30:28 -04:00
Joseph Doherty
b5e80d4c00
feat(inbound-api): machine-readable error codes per spec (incl. SITE_UNREACHABLE) + 415 for non-JSON bodies
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:30:28 -04:00
Joseph Doherty
761729b5d0
perf(esg): bound outbound response bodies (ResponseHeadersRead + MaxResponseBodyBytes cap; oversize = permanent failure)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:20:28 -04:00
Joseph Doherty
eabd2820eb
feat(esg): --timeout-seconds on external-system create/update (management command + CLI, additive contract)
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:20:28 -04:00
Joseph Doherty
0b916ff0c5
fix(inbound-api): defer DI-scope disposal to handler completion and count abandoned executions — closes the timeout use-after-dispose
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:20:28 -04:00
Joseph Doherty
39e1ca3eae
fix(notifications): deterministic lowest-Id SMTP config selection (+ multi-row warning); atomic OAuth2 token cache entry
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:14:36 -04:00
Joseph Doherty
eb7a913d22
feat(esg): {param} path-template substitution with consumed-param removal — implements the spec'd /recipes/{id} form
...
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-10 04:14:36 -04:00