Commit Graph

286 Commits

Author SHA1 Message Date
Joseph Doherty 130e9c918f feat(localdb): snapshot resync (LWW-merging, tombstone-carrying, delta resume)
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 23:35:50 -04:00
Joseph Doherty e92cdc6d3a fix(localdb): adapter review fixes — deterministic pump teardown, always-hosted initiator, backoff clamp
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 23:13:02 -04:00
Joseph Doherty a64fc26391 feat(localdb): gRPC sync adapters, background service, replication DI
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 23:01:29 -04:00
Joseph Doherty 183901e8ac test(localdb): pin drift-watermark branch; guard writer loop against completed-lane spin 2026-07-17 22:50:33 -04:00
Joseph Doherty 92ccbac8db fix(localdb): sync session concurrency fixes — two-lane writer, teardown fault fidelity, per-entry drift, gated snapshot seam 2026-07-17 22:44:42 -04:00
Joseph Doherty 925623b878 feat(localdb): SyncSession protocol state machine (handshake fail-closed, bidirectional delta pump) 2026-07-17 22:26:03 -04:00
Joseph Doherty b223507070 fix(localdb): applier review fixes — null-row_json guard, clock recovery via last_seen_hlc, fidelity + guard tests
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 22:15:51 -04:00
Joseph Doherty d7cbdce65c feat(localdb): LWW applier (hlc+node_id tie-break, applying guard, dead-letter, atomic watermark)
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 22:03:24 -04:00
Joseph Doherty 3cf8cabaf9 fix(localdb): oplog store review fixes — ack clamping, age-based pruning, monotonicity tests
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 21:55:25 -04:00
Joseph Doherty 4f9982c53f fix(localdb): DI review fixes — onReady leak guard, BusyTimeoutMs ctor guard, shared allow-list 2026-07-17 21:47:28 -04:00
Joseph Doherty 529585163c feat(localdb): oplog store (batch read, ack watermark, pruning caps, tombstone retention)
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 21:45:20 -04:00
Joseph Doherty c061ba733f feat(localdb): options validation + AddZbLocalDb DI; fail-fast on unsupported parameter collections 2026-07-17 21:40:23 -04:00
Joseph Doherty 3d72d2ee4b test(localdb): pin the S2 stale-rowid guard (in-txn + mixed multi-row PK-change regression tests) 2026-07-17 21:37:11 -04:00
Joseph Doherty df2518611f fix(localdb): capture-layer review fixes — BLOB fail-closed, identifier escaping, master lock, PK-change tombstone, digest canon 2026-07-17 21:30:45 -04:00
Joseph Doherty f4063f811f feat(localdb): opt-in table registration + capture triggers (oplog + row_version, applying guard) 2026-07-17 21:18:08 -04:00
Joseph Doherty 8b921e3106 feat(localdb): localdb_sync.v1 wire contract 2026-07-17 21:12:25 -04:00
Joseph Doherty 12b8839f33 fix(localdb): Task 4 review fixes — synchronous allow-list, dictionary params, async conn setup, dispose guard 2026-07-17 21:11:07 -04:00
Joseph Doherty 827bf44684 test(localdb): review fixes — index assertion, AUTOINCREMENT rationale, ReadMeta guard, concurrent HLC test 2026-07-17 21:05:10 -04:00
Joseph Doherty 83f384247c feat(localdb): SqliteLocalDb host (WAL, UDF-registered connections, HLC recovery, consumer SQL API) 2026-07-17 21:03:39 -04:00
Joseph Doherty fb8f751fac feat(localdb): lib-owned schema (meta/oplog/peer_state/row_version/applying/dead_letter) 2026-07-17 21:00:04 -04:00
Joseph Doherty cf58077398 feat(localdb): hybrid logical clock (UTC-ms<<16 | counter) 2026-07-17 20:58:02 -04:00
Joseph Doherty 61e5564c26 feat(localdb): scaffold ZB.MOM.WW.LocalDb (core/contracts/replication + tests)
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 20:55:56 -04:00
Joseph Doherty 9cef3c5d45 docs(localdb): implementation plan (15 TDD tasks) + task tracking
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 20:31:45 -04:00
Joseph Doherty bf4c5dccbd docs(localdb): approved design for ZB.MOM.WW.LocalDb (embedded SQLite cache + optional 2-node bidirectional async gRPC replication)
Claude-Session: https://claude.ai/code/session_01BL2Vu1ESDQ9SCN4gVKkdts
2026-07-17 20:25:22 -04:00
Joseph Doherty d82d3451e7 feat(secrets): build G-8 KEK rotation (RewrapAll); design+plan G-7 clustered replication
G-8 (KEK rotation) — built in ZB.MOM.WW.Secrets, lib 0.1.2->0.1.3:
- ISecretCipher.Rewrap(row, oldKek, newKek): re-wraps the per-secret DEK only
  (bodies never re-encrypted; revision/timestamps preserved -> invisible to
  cluster LWW). Fail-closed on wrong old-KEK id, wrong key bytes, and malformed
  wraps; DEK zeroed on all paths.
- ISecretStore.ApplyRewrapAsync(rewrappedRow, expectedCurrentWrappedDek):
  updates only the 4 wrap columns + kek_id, compare-and-swap on the current
  wrapped DEK so a concurrent set/rotate cannot corrupt a row (closes a
  review-caught TOCTOU).
- KekRotationService.RewrapAllAsync + RewrapReport: enumerate all rows incl.
  tombstones, idempotent/resumable skip-already-current, bounded CAS-retry,
  fail-closed on unknown/identical KEK.
- `secret rewrap-all` CLI verb: key material only via env-var name / file path,
  JSON counts report; README section + operator runbook.

Verified: full offline suite green (82 core + 15 UI, 0 regressions) + end-to-end
CLI smoke + adversarial crypto review (all 7 categories PASS; TOCTOU fixed).

G-7 (clustered replication) — designed + planned, no code:
- Fork resolved to build Option A (shared SQL-Server ISecretStore); Akka
  replicator ZB.MOM.WW.Secrets.Akka is a deferred phase-2. Design doc +
  executable plan + .tasks.json under docs/plans/2026-07-17-secrets-g7-*.

Tracking: components/secrets/GAPS.md + CLAUDE.md secrets row updated.
2026-07-17 02:55:43 -04:00
Joseph Doherty b009507e10 docs(secrets): OtOpcUa G-2 live-proven vs prod MxGateway (wonder-app-vd03:5120)
Record the OtOpcUa live wonder gate (item 2). A throwaway harness drove OtOpcUa's
real GalaxyDriverBrowser (secret: ApiKeySecretRef resolved via ISecretResolver) against
the real production MxGateway: dummy secret: ref -> MxGatewayAuthenticationException,
real metadata:read key -> CONNECTED + browsed the real Galaxy root (10 nodes). Temp key
minted via the dashboard, then revoked (functionally proven) + deleted; no prod key
touched; harness + scratch stores destroyed. All four apps now G-2..G-6 done + live-proven.
2026-07-16 23:15:00 -04:00
Joseph Doherty 1d05ecdf1e docs(secrets): OtOpcUa adoption executed + merged (lmxopcua @872cf7e3) — all 4 apps done
Record the OtOpcUa secrets adoption (G-2/G-4/G-5/G-6, the last app): FF-merged +
pushed to lmxopcua origin/master @872cf7e3. Update the components/secrets/GAPS.md
OtOpcUa bullet (execution record + the three verified plan deviations + the regression
the gate caught) and the CLAUDE.md secrets-component-table row. All four apps
(HistorianGateway, mxaccessgw, ScadaBridge, OtOpcUa) now adopt ZB.MOM.WW.Secrets.
2026-07-16 22:52:21 -04:00
Joseph Doherty c6b782e635 docs(secrets): re-verify OtOpcUa adoption plan vs v3.0 master (ec6598ce)
The v3.0 dual-namespace rewrite (PR #472) moved anchors and reshaped the
build, so the plan is refreshed to stay executable: CPM correction (OtOpcUa
is on Central Package Management, not inline versions), OpcUaClient options
in .Contracts + GalaxyDriverBrowser in .Browser, DriverHostActor line
shifts, and appsettings/owner precision. Driver-secret flow itself was
untouched by v3.0, so the two-layer approach holds.
2026-07-16 16:50:14 -04:00
Joseph Doherty 5eea386ebf docs(secrets): ScadaBridge G-3/G-4/G-5/G-6 adopted + merged + live-proven (ScadaBridge @ 128f1596) 2026-07-16 16:15:28 -04:00
Joseph Doherty fbb79ef83a docs(index): OtOpcUa v3.0 — dual-namespace address space (PR #472 merged)
Update the OtOpcUa umbrella entry for v3.0: the single .../ns namespace is
replaced by .../raw (s=<RawPath>) + .../uns (s=<Area>/<Line>/<Equipment>/<Eff>),
single-source fan-out to both NodeIds, Organizes UNS->Raw, writes/HistoryRead via
either NodeId, multi-notifier alarms, EquipmentNodeIds retired. Flags the wire-
contract change as a pending ScadaBridge Data-Connection-Layer cutover.

Claude-Session: https://claude.ai/code/session_01LVneM3eh1UtJxEisFXgmox
2026-07-16 14:39:33 -04:00
Joseph Doherty d95328efb3 docs(secrets): mxaccessgw G-4/G-5/G-6 adopted + merged (mxaccessgw @ e088dfa) 2026-07-16 13:49:43 -04:00
Joseph Doherty 6be5f746d5 docs(secrets): G-2..G-6 adoption design + 3 per-repo plans
Shared design (two resolution layers, wiring template, master-key/clustering
fork) + per-repo executable plans with code-verified anchors and co-located
.tasks.json:
  - mxaccessgw (G-4/G-5/G-6, 8 tasks)
  - otopcua    (G-2/G-4/G-5/G-6, 10 tasks, 2 slices)
  - scadabridge (G-3/G-4/G-5/G-6, 10 tasks, 2 slices)
Linked from components/secrets/GAPS.md.
2026-07-16 09:19:33 -04:00
Joseph Doherty e347286f28 docs(components): normalize Secrets component + index the shared lib
Add components/secrets/ (SPEC, realized shared-contract, code-verified
current-state for OtOpcUa/mxaccessgw/ScadaBridge, GAPS adoption backlog) and
register the Secrets row in CLAUDE.md + components/README.md. The
ZB.MOM.WW.Secrets lib is built + published 0.1.2 + reference-consumer-proven
(HistorianGateway, live vs the wonder historian); per-app adoption is the
tracked follow-on.
2026-07-16 04:49:57 -04:00
Joseph Doherty de77bc30e3 merge: ZB.MOM.WW.Secrets envelope-encrypted secrets manager (lib + Blazor UI + CLI)
7th shared ZB.MOM.WW.* library: AES-256-GCM envelope-encrypted secret store
(ISecretStore/SQLite), pluggable IMasterKeyProvider, ${secret:name} config
resolution, ISecretResolver runtime cache, Blazor /admin/secrets management UI
on the Theme kit, and a headless 'secret' CLI. Published 0.1.2 to the Gitea feed;
HistorianGateway adopted as reference consumer (live-proven end-to-end against
the real wonder historian). 80 tests pass.
2026-07-16 04:44:01 -04:00
Joseph Doherty 9bd3c76d96 fix(secrets): ${secret:} expander skips comment keys (_-prefixed leaf) — 0.1.2
Live HistorianGateway boot caught that the expander scanned a '_secretsComment' appsettings
value documenting the ${secret:...} syntax, tried to resolve the literal example token, and
crashed boot. The family uses _*Comment keys pervasively, so skip any config key whose leaf
segment starts with '_' (the _comment convention). Functional keys never lead with '_'.
2026-07-16 04:16:25 -04:00
Joseph Doherty 76124590f0 fix(secrets-ui): admin role must be canonical 'Administrator' (case-sensitive) — 0.1.1
Reference-consumer (HistorianGateway) caught that SecretsAuthorization.AdminRole was
'administrator' (lowercase) while the family canonical role is CanonicalRole.Administrator.
ASP.NET role claims compare case-sensitively (Ordinal), so a real admin got 403 on the
secrets UI. Now nameof(CanonicalRole.Administrator).
2026-07-16 04:11:20 -04:00
Joseph Doherty 2c64683303 docs(secrets): package README + embed in nupkgs 2026-07-16 04:00:32 -04:00
Joseph Doherty e23cd317b0 docs(index): HistorianGateway AHC-002 string reads merged (historiangw @ 56a70df, PR #17) + 8 follow-up issues #18-#25 2026-07-16 03:51:49 -04:00
Joseph Doherty e20812cbae chore(secrets): wire cache invalidation on rotate/delete, drop dead RevealEnabled, remove scaffold leftovers 2026-07-15 17:39:55 -04:00
Joseph Doherty 294f53b49a fix(secrets-ui): preserve metadata on rotate + audit unexpected mutation/reveal failures 2026-07-15 17:31:34 -04:00
Joseph Doherty 0ab276dac0 feat(secrets-cli): set/get/list/rm/rotate commands 2026-07-15 17:26:14 -04:00
Joseph Doherty 21556cc1a7 feat(secrets-ui): add/rotate/delete modal + audited gated reveal 2026-07-15 17:20:01 -04:00
Joseph Doherty d7f8ca455b feat(secrets-ui): RCL + authz policies + metadata-only secrets list 2026-07-15 17:10:40 -04:00
Joseph Doherty 7f1db1b214 feat(secrets): SecretsOptions + AddZbSecrets DI + migration hosted service 2026-07-15 17:05:30 -04:00
Joseph Doherty 8c4175d8ce fix(secrets): audit decryption failures in resolver (fail-loud, no plaintext) 2026-07-15 17:01:10 -04:00
Joseph Doherty 0bb553212a feat(secrets): ${secret:} config expander (fail-closed) 2026-07-15 16:58:34 -04:00
Joseph Doherty 79ebd14baa feat(secrets): default resolver with TTL cache + audit (never logs plaintext) 2026-07-15 16:55:24 -04:00
Joseph Doherty 10455ec53b feat(secrets): sqlite secret store (overwrite-in-place, tombstone, manifest, LWW) 2026-07-15 16:50:59 -04:00
Joseph Doherty e99a8731e9 feat(secrets): sqlite connection factory + schema v1 + migrator 2026-07-15 16:46:15 -04:00
Joseph Doherty 1c13b4af99 feat(secrets): pluggable master-key providers (env/file/dpapi) + factory 2026-07-15 16:43:10 -04:00