From c284e4d68da169cc2bc5b109c0c173fa8cded920 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Mon, 1 Jun 2026 07:38:20 -0400 Subject: [PATCH] docs(audit): register component in indexes + GAPS cross-check --- CLAUDE.md | 19 +++++++++++++++++++ components/README.md | 1 + upcoming.md | 10 ++++++++-- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index d729eae..267e3c5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -119,6 +119,7 @@ each project's **code-verified current state**, and the **gaps** between. See |---|---|---|---|---| | Auth (login / identity / authz) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Auth` lib | [`components/auth/`](components/auth/) | [`ZB.MOM.WW.Auth/`](ZB.MOM.WW.Auth/) | | UI Theme (layout / tokens / components) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Theme` RCL | [`components/ui-theme/`](components/ui-theme/) | [`ZB.MOM.WW.Theme/`](ZB.MOM.WW.Theme/) | +| Audit (event model + writer seam) | Built (lib `0.1.0`) | Shared `ZB.MOM.WW.Audit` lib | [`components/audit/`](components/audit/) | [`ZB.MOM.WW.Audit/`](ZB.MOM.WW.Audit/) | The auth component is fully populated: a normalized [`spec`](components/auth/spec/SPEC.md), a proposed [`shared-contract`](components/auth/shared-contract/ZB.MOM.WW.Auth.md), three @@ -149,6 +150,24 @@ The implementation plan is at Build/test from `ZB.MOM.WW.Theme/`: `dotnet test`. Consumer matrix: all three apps consume the single `ZB.MOM.WW.Theme` package (OtOpcUa AdminUI, MxGateway Server, ScadaBridge Host + CentralUI). +The audit component is fully populated: a normalized [`spec`](components/audit/spec/SPEC.md), an +[`event-model`](components/audit/spec/EVENT-MODEL.md) reference, a +[`shared-contract`](components/audit/shared-contract/ZB.MOM.WW.Audit.md), three +[`current-state`](components/audit/current-state/) docs, and an adoption [`GAPS`](components/audit/GAPS.md) +backlog. Common ground = canonical `AuditEvent` record + `AuditOutcome` enum + `IAuditWriter` / +`IAuditRedactor` seams + helpers (`NullAuditRedactor`, `TruncatingAuditRedactor`, `NoOpAuditWriter`, +`CompositeAuditWriter`, `RedactingAuditWriter`) + `AddZbAudit` DI registration; left per-project = +transport/storage and domain vocabulary. Closes the loop on Auth — audit's `Actor` field = the Auth +principal. `IAuditRedactor` is aligned with Telemetry's `ILogRedactor` seam convention. + +The shared library is **built and lives in this repo** at [`ZB.MOM.WW.Audit/`](ZB.MOM.WW.Audit/) +(.NET 10; 1 package — `ZB.MOM.WW.Audit`; only non-BCL dependency `Microsoft.Extensions.DependencyInjection.Abstractions`; +19 tests; `dotnet pack` → 1 nupkg @ 0.1.0). Repo: `https://gitea.dohertylan.com/dohertj2/zb-mom-ww-audit`. +**Not yet adopted** by the three apps — that's the follow-on tracked in [`components/audit/GAPS.md`](components/audit/GAPS.md). +Build/test from `ZB.MOM.WW.Audit/`: `dotnet test`. Consumer matrix: all three apps consume the single +`ZB.MOM.WW.Audit` package (OtOpcUa, MxAccessGateway, ScadaBridge each map their own audit record/seam +onto the canonical type at the emit boundary). + ## Per-project primary commands Run these from inside each project directory (not from `scadaproj`). diff --git a/components/README.md b/components/README.md index 5dfd0ef..c4aac67 100644 --- a/components/README.md +++ b/components/README.md @@ -19,6 +19,7 @@ specs and analyses that *drive* changes made in the individual repos. |---|---|---|---|---| | Auth (login / identity / authz) | Draft | OtOpcUa, MxAccessGateway, ScadaBridge | Path to shared code (`ZB.MOM.WW.Auth`) | [`auth/`](auth/) | | UI Theme (layout / tokens / components) | Draft | OtOpcUa, MxAccessGateway, ScadaBridge | Path to shared code (`ZB.MOM.WW.Theme`) | [`ui-theme/`](ui-theme/) | +| Audit (event model + writer seam) | Draft | OtOpcUa, MxAccessGateway, ScadaBridge | Path to shared code (`ZB.MOM.WW.Audit`) | [`audit/`](audit/) | > Add a row when you start normalizing a new component. Status: `Draft` → `Reviewed` → `Adopting` → `Converged`. diff --git a/upcoming.md b/upcoming.md index b7aac1e..bef454c 100644 --- a/upcoming.md +++ b/upcoming.md @@ -49,7 +49,7 @@ Three different, incompatible approaches mean you can't scrape or dashboard the (+ `Commons` `OtOpcUaTelemetry`); MxGateway `src/ZB.MOM.WW.MxGateway.Server/Metrics/GatewayMetrics.cs` (~470 LOC, no exporter); ScadaBridge `OpenTelemetry.Api` dep only (no instrumentation). -### 3. Audit — shared event *model* + writer seam +### 3. Audit — shared event *model* + writer seam ✅ DONE All three audit; the who-did-what record (actor / action / target / time / correlationId / detailsJson) is genuinely common, and it **closes the loop on the Auth component** (audit's "who" = identity). Transport differs (Akka cluster vs SQLite vs none), so extract only the @@ -58,6 +58,9 @@ ScadaBridge's pipeline is ~3k LOC. - Evidence: OtOpcUa `Commons/Messages/Audit/AuditEvent.cs` + `ControlPlane/Audit/AuditWriterActor.cs` + `Configuration/Entities/ConfigAuditLog.cs`; ScadaBridge `src/ZB.MOM.WW.ScadaBridge.AuditLog/` (site + central) + `Commons/Entities/Audit/`; MxGateway `Security/Authentication/SqliteApiKeyAuditStore.cs`. +- **Delivered:** shared library built at [`ZB.MOM.WW.Audit/`](ZB.MOM.WW.Audit/) (1 nupkg @ 0.1.0); + design at [`components/audit/`](components/audit/); adoption backlog in + [`components/audit/GAPS.md`](components/audit/GAPS.md). ### Strategic — the gRPC `.proto` break surface [`CLAUDE.md`](CLAUDE.md) names these as *the* cross-repo break surface ("a green build in one @@ -70,7 +73,10 @@ cross-repo interop checks, distinct from the others. ### Tier 2 (good, with caveats) - **Logging — `ZB.MOM.WW.Logging`:** strong overlap (Serilog bootstrap + enrichers SiteId/NodeRole/Host + correlation scope), but MxGateway uses MS.Extensions.Logging — step 1 is converging on Serilog. - Natural to bundle with Telemetry as "observability". + Natural to bundle with Telemetry as "observability". **Note:** the logging-family work for this + family is being delivered as `ZB.MOM.WW.Telemetry.Serilog` by the health/observability normalization + pass ([`components/health/`](components/health/)), not as a standalone `ZB.MOM.WW.Logging` lib — + a separate Logging candidate is not expected. - **Config validation conventions:** all three use IOptions + `IValidateOptions` + `ValidateOnStart`; a shared validation base + startup-validation helper is reusable and pairs with the Auth options pattern.