docs: truth sweep — index + component GAPS reconciled with shipped state (Health 0.3.0 merged both apps, OtOpcUa LocalDb Phase 2 executed, Auth 0.1.5, Secrets 0.2.3/0.3.0)

Claude-Session: https://claude.ai/code/session_014WNM4vjoVksyyBraTXSZE1
This commit is contained in:
Joseph Doherty
2026-08-07 02:00:58 -04:00
parent 1a7bff6a19
commit 537a4f524d
23 changed files with 304 additions and 261 deletions
+8 -9
View File
File diff suppressed because one or more lines are too long
@@ -3,8 +3,10 @@
**Audience:** operators rotating the key-encryption key (KEK) that protects a secrets store.
**Primitive:** `secret rewrap-all` (CLI) → `KekRotationService.RewrapAllAsync` → per-row
`ISecretCipher.Rewrap` + `ISecretStore.ApplyRewrapAsync`.
**Status:** G-8 (KEK-rotation `RewrapAll` + runbook). Companion to the deferred G-7 clustered
replication (`ZB.MOM.WW.Secrets.Akka`).
**Status:** G-8 (KEK-rotation `RewrapAll` + runbook). Companion to the G-7 clustered replication,
which was **BUILT 2026-07-18** (lib `0.2.0`, both options: `ZB.MOM.WW.Secrets.Replicator.SqlServer`
and `ZB.MOM.WW.Secrets.Replicator.AkkaDotNet`; see `clustered-secrets.md`) — the earlier "deferred"
wording here predated that build.
---
+7 -7
View File
@@ -17,13 +17,13 @@ specs and analyses that *drive* changes made in the individual repos.
| Component | Status | Applies to | Goal | Folder |
|---|---|---|---|---|
| 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/) |
| Health (readiness / liveness / active-node) | Draft | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Health` lib (3 packages) | [`health/`](health/) |
| Observability (metrics / traces / logs) | Draft | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Telemetry` lib (2 packages) | [`observability/`](observability/) |
| Config + validation (options / startup validation) | Draft | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Configuration` lib (1 package) | [`configuration/`](configuration/) |
| Audit (event model + writer seam) | Draft | OtOpcUa, MxAccessGateway, ScadaBridge | Path to shared code (`ZB.MOM.WW.Audit`) | [`audit/`](audit/) |
| Secrets (encrypted store + `${secret:}` resolution) | Built + reference-consumer adopted | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Secrets` lib (3 packages + CLI) | [`secrets/`](secrets/) |
| Auth (login / identity / authz) | Adopted | OtOpcUa, MxAccessGateway, ScadaBridge | Path to shared code (`ZB.MOM.WW.Auth`) | [`auth/`](auth/) |
| UI Theme (layout / tokens / components) | Adopted | OtOpcUa, MxAccessGateway, ScadaBridge | Path to shared code (`ZB.MOM.WW.Theme`) | [`ui-theme/`](ui-theme/) |
| Health (readiness / liveness / active-node) | Adopted | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Health` lib (3 packages) | [`health/`](health/) |
| Observability (metrics / traces / logs) | Adopted | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Telemetry` lib (2 packages) | [`observability/`](observability/) |
| Config + validation (options / startup validation) | Adopted | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Configuration` lib (1 package) | [`configuration/`](configuration/) |
| Audit (event model + writer seam) | Adopted | OtOpcUa, MxAccessGateway, ScadaBridge | Path to shared code (`ZB.MOM.WW.Audit`) | [`audit/`](audit/) |
| Secrets (encrypted store + `${secret:}` resolution) | Adopted (all four apps pin `0.2.3`) | OtOpcUa, MxAccessGateway, ScadaBridge | Shared `ZB.MOM.WW.Secrets` lib (5 packages + CLI) | [`secrets/`](secrets/) |
> Add a row when you start normalizing a new component. Status: `Draft` → `Reviewed` → `Adopting` → `Converged`.
+16 -10
View File
@@ -14,18 +14,24 @@ reach the shared `ZB.MOM.WW.Auth` library. Status legend: ⛔ gap · 🟡 partia
> resolve `2.1.12`; **HistorianGateway was never exposed** (already resolved `3.50.3` via another
> dependency), so its bump is consistency-only. ScadaBridge's `0.1.3`→`0.1.5` jump crosses the
> `0.1.4` `ExpiresUtc` change, but that was additive — no source changes were needed and its
> suites match baseline exactly (Security 181, InboundAPI 269). **OtOpcUa stays at `0.1.1`** and
> was never exposed: it takes no `ApiKeys`/SQLite dependency.
> suites match baseline exactly (Security 181, InboundAPI 269). **OtOpcUa stayed at `0.1.1`** at
> the time and was never exposed (it takes no `ApiKeys`/SQLite dependency) — it then bumped
> `0.1.1`→`0.1.5` on 2026-07-20 for family alignment (`1adaa2fc`, PR #484, on `origin/master`).
>
> ⚠️ **Caveat:** HistorianGateway's bump could NOT be test-verified — a pre-existing, unrelated
> `AngleSharp` NU1902 error blocks its test project under `TreatWarningsAsErrors` (ScadaBridge's
> `CentralUI.Tests` has the same break). Both confirmed present on clean trees beforehand.
> ⚠️ **Caveat — RESOLVED 2026-07-19:** HistorianGateway's bump could NOT be test-verified at the
> time — a pre-existing, unrelated `AngleSharp` NU1902 error blocked its test project under
> `TreatWarningsAsErrors` (ScadaBridge's `CentralUI.Tests` had the same break; both confirmed
> present on clean trees beforehand). The HG blocker was fixed by HG commit `6bc005d`
> ("fix(tests): pin AngleSharp 1.5.2 — clear GHSA-pgww-w46g-26qg NU1902 build break"), after which
> the suite runs (854 pass; see the scadaproj `CLAUDE.md` index Secrets narrative).
>
> **Current state (verified 2026-07-18):** feed carries `0.1.0`–`0.1.5`; consumer pins are
> OtOpcUa `0.1.1`, ScadaBridge `0.1.3`, MxAccessGateway `0.1.4`, **HistorianGateway `0.1.4`**
> (a fourth consumer this file predates, taking all four packages). OtOpcUa is three minors
> behind — it does not get the `0.1.4` API-key-expiry enforcement. Library suite: **215 passing,
> 1 skipped**, green 2026-07-18.
> **Current state (re-verified 2026-08-07 against each repo's `Directory.Packages.props`):** feed
> carries `0.1.0`–`0.1.5`; **all four consumers pin `0.1.5`** — mxaccessgw `e107019`, ScadaBridge
> `50d79ed1`, HistorianGateway `df211ee` (all 2026-07-18), OtOpcUa `1adaa2fc` (2026-07-20).
> (The previous snapshot here — OtOpcUa `0.1.1` / ScadaBridge `0.1.3` / MxAccessGateway `0.1.4` /
> HistorianGateway `0.1.4` — predated the same-day bumps recorded in the banner above and
> contradicted it.) HistorianGateway is a fourth consumer this file predates, taking all four
> packages. Library suite: **215 passing, 1 skipped**, green 2026-07-18.
>
> **✅ ADOPTED 2026-06-02 (local-only).** The full backlog (#1–#8) was implemented across all three apps on each repo's
> **`feat/adopt-zb-auth`** branch — committed + spec/code-reviewed, then **merged to each repo's local default
+6
View File
@@ -15,6 +15,12 @@ wired for ScadaBridge Cluster/HealthMonitoring, and assorted hardening).
Status legend: ⛔ gap · 🟡 partial · ✅ matches.
> **Note (reconciled 2026-08-07):** the divergence tables below are the **pre-adoption 2026-06-01
> snapshot**. In particular, cells reading OtOpcUa "⛔ n/a (no validators)" describe the state
> *before* adoption — as the header above records, OtOpcUa gained net-new `Ldap`/`OpcUa` validators
> (via `OptionsValidatorBase` + `AddValidatedOptions`) in the adoption pass, so those cells and the
> "OtOpcUa has **no validators at all**" prose are historical, not current. Gaps B3/A1/W3 are closed.
## Divergence vs spec
### §1 `IValidateOptions` base — failure accumulation (everyone hand-rolls it)
+6 -3
View File
@@ -12,9 +12,12 @@ reach the shared `ZB.MOM.WW.Telemetry` library. Status legend: ⛔ gap · 🟡 p
>
> **The `⛔ not set` divergence tables below are the pre-adoption 2026-06-01 snapshot** — the §1
> Resource-attribute gaps they describe are what `AddZbTelemetry` closed. Read them as the
> historical case for the library, not as current state. Deferred items noted at the time
> (MxGateway `ms`→`s` + Meter rename, ScadaBridge app instruments + Site-node HTTP/1.1 metrics
> listener, OTLP wiring) were **not** re-verified in this pass.
> historical case for the library, not as current state. The items deferred at adoption time
> (MxGateway `ms`→`s` + Meter rename, ScadaBridge app instruments + Site-node `:8084` metrics
> listener, OTLP opt-in wiring) were **all subsequently executed the same day** — see the
> "Follow-ons — DONE 2026-06-01" table at the bottom of this file, which this banner previously
> contradicted (reconciled 2026-08-07). Only the operational items under "Still open" there
> (deploying an OTel collector; further ScadaBridge instruments) remain.
## Divergence vs spec
+15 -8
View File
@@ -19,10 +19,12 @@ construction).
fix. Verified: the shipped `.nuspec` declares `SQLitePCLRaw.lib.e_sqlite3 >= 2.1.12` as a direct
dependency, so **consumers get the patched native lib without needing their own pin**, and a
fresh consumer restoring `0.1.3` scans clean.
- **All four apps are still pinned at `0.1.2`** — they get neither KEK rotation nor the security
fix until bumped.
- **All four apps are pinned to `0.1.2`** — OtOpcUa, MxAccessGateway, ScadaBridge take
`Secrets` + `.Abstractions` + `.Ui`; HistorianGateway takes `Secrets` + `.Ui`.
- **All four apps now pin `0.2.3`, pushed 2026-07-19** (superseding the "still pinned at `0.1.2`"
claim that stood here — corrected 2026-08-07; the 0.1.2→0.2.1 bump and the 0.2.2/0.2.3 rollout
are recorded below and in the scadaproj `CLAUDE.md` index). OtOpcUa, MxAccessGateway, ScadaBridge
take `Secrets` + `.Abstractions` + `.Ui`; HistorianGateway takes `Secrets` + `.Ui`.
- **`0.3.0` (2026-07-19) ships in the `secret` CLI tool only** (interactive operator console); the
four apps deliberately stay on the `0.2.3` libraries — the 0.3.0 delta has no app-side surface.
- **G-7 clustered replication is BUILT (2026-07-18, lib `0.2.0`) — both options, not just one.**
The plan scoped Option A (shared SQL store) and deferred Option B (Akka) to phase 2; the build
covers **both**, as two new packages:
@@ -50,8 +52,10 @@ construction).
### Open
- ✅ **All four apps bumped `0.1.2` → `0.2.1`** (2026-07-18), each on a local `feat/secrets-0.2.0`
branch, **not pushed**. HistorianGateway `bb9d923`, MxAccessGateway `b021e29`, OtOpcUa `1ccc237c`,
ScadaBridge `0083ce35`.
branch (HistorianGateway `bb9d923`, MxAccessGateway `b021e29`, OtOpcUa `1ccc237c`,
ScadaBridge `0083ce35`). *Superseded 2026-07-19:* the branches were carried forward through the
`0.2.2`/`0.2.3` fixes and **all four apps landed on `0.2.3`, merged and pushed** (the "not
pushed" note above described the interim 0.2.1 state only — corrected 2026-08-07).
- **Correction:** the bump was originally justified as closing GHSA-2m69-gcr7-jv3q in all four
apps. Measured against the `0.1.2` baseline in every repo, **all four already resolved the
patched `SQLitePCLRaw.lib.e_sqlite3 2.1.12`** — two via their own pins, two transitively via
@@ -270,8 +274,11 @@ evidence it is correct. When a reviewer names a mechanism, probe the mechanism.
operator runbook — full suite green (82+15, 0 regressions) + end-to-end CLI smoke, adversarial
crypto review PASS with a review-caught TOCTOU closed via compare-and-swap. G-7's SQL-store-vs-Akka
fork is resolved (build the shared SQL-Server `ISecretStore`; Akka replicator deferred phase-2)
with a design doc + executable plan + `.tasks.json`, **no code built**. See the G-7/G-8 backlog
entries below. Not yet committed/pushed (awaiting go-ahead).
with a design doc + executable plan + `.tasks.json`, **no code built at that point**. See the
G-7/G-8 backlog entries below. *(Corrected 2026-08-07: the trailing "Not yet committed/pushed
(awaiting go-ahead)" note was stale — G-8 + the G-7 plan ARE committed and pushed on `main` @
`d82d345`, as the Current-state section above already records; G-7 was subsequently BUILT
2026-07-18 at lib `0.2.0`, both replication options.)*
## Design + implementation plans (2026-07-16)
@@ -1,16 +1,17 @@
{
"planPath": "docs/plans/2026-06-01-health-library-adoption.md",
"tasks": [
{"id": 0, "subject": "Task 0: Verify/publish Health nupkgs to Gitea", "status": "pending"},
{"id": 1, "subject": "Task 1: MxGateway reference wiring", "status": "pending", "blockedBy": [0]},
{"id": 2, "subject": "Task 2: MxGateway AuthStoreHealthCheck (TDD)", "status": "pending", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: MxGateway rewire to canonical tiers", "status": "pending", "blockedBy": [2]},
{"id": 4, "subject": "Task 4: OtOpcUa reference wiring", "status": "pending", "blockedBy": [0]},
{"id": 5, "subject": "Task 5: OtOpcUa swap to shared probes", "status": "pending", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: ScadaBridge reference wiring", "status": "pending", "blockedBy": [0]},
{"id": 7, "subject": "Task 7: ScadaBridge ActorSystem DI bridge (TDD)", "status": "pending", "blockedBy": [6]},
{"id": 8, "subject": "Task 8: ScadaBridge swap to shared probes", "status": "pending", "blockedBy": [6, 7]},
{"id": 9, "subject": "Task 9: Update Health GAPS bookkeeping", "status": "pending", "blockedBy": [3, 5, 8]}
{"id": 0, "subject": "Task 0: Verify/publish Health nupkgs to Gitea", "status": "completed"},
{"id": 1, "subject": "Task 1: MxGateway reference wiring", "status": "completed", "blockedBy": [0]},
{"id": 2, "subject": "Task 2: MxGateway AuthStoreHealthCheck (TDD)", "status": "completed", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: MxGateway rewire to canonical tiers", "status": "completed", "blockedBy": [2]},
{"id": 4, "subject": "Task 4: OtOpcUa reference wiring", "status": "completed", "blockedBy": [0]},
{"id": 5, "subject": "Task 5: OtOpcUa swap to shared probes", "status": "completed", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: ScadaBridge reference wiring", "status": "completed", "blockedBy": [0]},
{"id": 7, "subject": "Task 7: ScadaBridge ActorSystem DI bridge (TDD)", "status": "completed", "blockedBy": [6]},
{"id": 8, "subject": "Task 8: ScadaBridge swap to shared probes", "status": "completed", "blockedBy": [6, 7]},
{"id": 9, "subject": "Task 9: Update Health GAPS bookkeeping", "status": "completed", "blockedBy": [3, 5, 8]}
],
"lastUpdated": "2026-06-01"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (Health component Adopted \u2014 all 4 apps reference the lib + wire MapZbHealth); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,20 +1,21 @@
{
"planPath": "docs/plans/2026-06-01-telemetry-library-adoption.md",
"tasks": [
{"id": 0, "taskId": 23, "subject": "Task 0: Publish/verify Telemetry packages on Gitea", "status": "pending", "classification": "small"},
{"id": 1, "taskId": 24, "subject": "Task 1: OtOpcUa — distribution wiring", "status": "pending", "classification": "small", "blockedBy": [0]},
{"id": 2, "taskId": 25, "subject": "Task 2: OtOpcUa — swap OTel to AddZbTelemetry", "status": "pending", "classification": "standard", "blockedBy": [1]},
{"id": 3, "taskId": 26, "subject": "Task 3: OtOpcUa — swap Serilog to AddZbSerilog", "status": "pending", "classification": "standard", "blockedBy": [2]},
{"id": 4, "taskId": 27, "subject": "Task 4: ScadaBridge — distribution wiring", "status": "pending", "classification": "small", "blockedBy": [0]},
{"id": 5, "taskId": 28, "subject": "Task 5: ScadaBridge — AddZbTelemetry both roots + MapZbMetrics", "status": "pending", "classification": "standard", "blockedBy": [4]},
{"id": 6, "taskId": 29, "subject": "Task 6: ScadaBridge — TraceContextEnricher in LoggerConfigurationFactory", "status": "pending", "classification": "small", "blockedBy": [5]},
{"id": 7, "taskId": 30, "subject": "Task 7: MxAccessGateway — distribution wiring", "status": "pending", "classification": "small", "blockedBy": [0]},
{"id": 8, "taskId": 31, "subject": "Task 8: MxAccessGateway — appsettings Logging → Serilog", "status": "pending", "classification": "small", "blockedBy": [7]},
{"id": 9, "taskId": 32, "subject": "Task 9: MxAccessGateway — AddZbSerilog (MEL→Serilog provider swap)", "status": "pending", "classification": "high-risk", "blockedBy": [8]},
{"id": 10, "taskId": 33, "subject": "Task 10: MxAccessGateway — ILogRedactor seam", "status": "pending", "classification": "standard", "blockedBy": [9]},
{"id": 11, "taskId": 34, "subject": "Task 11: MxAccessGateway — AddZbTelemetry metrics export + MapZbMetrics", "status": "pending", "classification": "standard", "blockedBy": [10]},
{"id": 12, "taskId": 35, "subject": "Task 12: scadaproj — bookkeeping + correct false claim", "status": "pending", "classification": "trivial", "blockedBy": [3, 6, 11]}
{"id": 0, "taskId": 23, "subject": "Task 0: Publish/verify Telemetry packages on Gitea", "status": "completed", "classification": "small"},
{"id": 1, "taskId": 24, "subject": "Task 1: OtOpcUa — distribution wiring", "status": "completed", "classification": "small", "blockedBy": [0]},
{"id": 2, "taskId": 25, "subject": "Task 2: OtOpcUa — swap OTel to AddZbTelemetry", "status": "completed", "classification": "standard", "blockedBy": [1]},
{"id": 3, "taskId": 26, "subject": "Task 3: OtOpcUa — swap Serilog to AddZbSerilog", "status": "completed", "classification": "standard", "blockedBy": [2]},
{"id": 4, "taskId": 27, "subject": "Task 4: ScadaBridge — distribution wiring", "status": "completed", "classification": "small", "blockedBy": [0]},
{"id": 5, "taskId": 28, "subject": "Task 5: ScadaBridge — AddZbTelemetry both roots + MapZbMetrics", "status": "completed", "classification": "standard", "blockedBy": [4]},
{"id": 6, "taskId": 29, "subject": "Task 6: ScadaBridge — TraceContextEnricher in LoggerConfigurationFactory", "status": "completed", "classification": "small", "blockedBy": [5]},
{"id": 7, "taskId": 30, "subject": "Task 7: MxAccessGateway — distribution wiring", "status": "completed", "classification": "small", "blockedBy": [0]},
{"id": 8, "taskId": 31, "subject": "Task 8: MxAccessGateway — appsettings Logging → Serilog", "status": "completed", "classification": "small", "blockedBy": [7]},
{"id": 9, "taskId": 32, "subject": "Task 9: MxAccessGateway — AddZbSerilog (MEL→Serilog provider swap)", "status": "completed", "classification": "high-risk", "blockedBy": [8]},
{"id": 10, "taskId": 33, "subject": "Task 10: MxAccessGateway — ILogRedactor seam", "status": "completed", "classification": "standard", "blockedBy": [9]},
{"id": 11, "taskId": 34, "subject": "Task 11: MxAccessGateway — AddZbTelemetry metrics export + MapZbMetrics", "status": "completed", "classification": "standard", "blockedBy": [10]},
{"id": 12, "taskId": 35, "subject": "Task 12: scadaproj — bookkeeping + correct false claim", "status": "completed", "classification": "trivial", "blockedBy": [3, 6, 11]}
],
"notes": "Task 0 gates all. After Task 0 the three repo phases (OtOpcUa 1-3, ScadaBridge 4-6, MxGateway 7-11) are independent and may run concurrently across their separate working directories; within a repo tasks are sequential. Task 12 last.",
"lastUpdated": "2026-06-01"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (Observability Adopted \u2014 adopted across all three apps 2026-06-01; all 4 apps call AddZbTelemetry); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,22 +1,23 @@
{
"planPath": "docs/plans/2026-06-01-zb-mom-ww-audit-shared-library.md",
"tasks": [
{"id": 0, "subject": "Task 0: Current-state — OtOpcUa", "status": "pending"},
{"id": 1, "subject": "Task 1: Current-state — MxAccessGateway", "status": "pending"},
{"id": 2, "subject": "Task 2: Current-state — ScadaBridge", "status": "pending"},
{"id": 3, "subject": "Task 3: SPEC.md + EVENT-MODEL.md", "status": "pending", "blockedBy": [0, 1, 2]},
{"id": 4, "subject": "Task 4: shared-contract/ZB.MOM.WW.Audit.md", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: components/audit/README.md + GAPS.md", "status": "pending", "blockedBy": [3, 4]},
{"id": 6, "subject": "Task 6: Scaffold the library + test project + solution", "status": "pending", "blockedBy": [4]},
{"id": 7, "subject": "Task 7: AuditEvent record + AuditOutcome enum + seam interfaces", "status": "pending", "blockedBy": [6]},
{"id": 8, "subject": "Task 8: NullAuditRedactor", "status": "pending", "blockedBy": [7]},
{"id": 9, "subject": "Task 9: TruncatingAuditRedactor + options", "status": "pending", "blockedBy": [7]},
{"id": 10, "subject": "Task 10: NoOpAuditWriter", "status": "pending", "blockedBy": [7]},
{"id": 11, "subject": "Task 11: CompositeAuditWriter", "status": "pending", "blockedBy": [7]},
{"id": 12, "subject": "Task 12: RedactingAuditWriter", "status": "pending", "blockedBy": [7]},
{"id": 13, "subject": "Task 13: AddZbAudit DI extension", "status": "pending", "blockedBy": [8, 10]},
{"id": 14, "subject": "Task 14: Full test run + dotnet pack @ 0.1.0", "status": "pending", "blockedBy": [13]},
{"id": 15, "subject": "Task 15: Index/registry updates + GAPS cross-check", "status": "pending", "blockedBy": [14]}
{"id": 0, "subject": "Task 0: Current-state — OtOpcUa", "status": "completed"},
{"id": 1, "subject": "Task 1: Current-state — MxAccessGateway", "status": "completed"},
{"id": 2, "subject": "Task 2: Current-state — ScadaBridge", "status": "completed"},
{"id": 3, "subject": "Task 3: SPEC.md + EVENT-MODEL.md", "status": "completed", "blockedBy": [0, 1, 2]},
{"id": 4, "subject": "Task 4: shared-contract/ZB.MOM.WW.Audit.md", "status": "completed", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: components/audit/README.md + GAPS.md", "status": "completed", "blockedBy": [3, 4]},
{"id": 6, "subject": "Task 6: Scaffold the library + test project + solution", "status": "completed", "blockedBy": [4]},
{"id": 7, "subject": "Task 7: AuditEvent record + AuditOutcome enum + seam interfaces", "status": "completed", "blockedBy": [6]},
{"id": 8, "subject": "Task 8: NullAuditRedactor", "status": "completed", "blockedBy": [7]},
{"id": 9, "subject": "Task 9: TruncatingAuditRedactor + options", "status": "completed", "blockedBy": [7]},
{"id": 10, "subject": "Task 10: NoOpAuditWriter", "status": "completed", "blockedBy": [7]},
{"id": 11, "subject": "Task 11: CompositeAuditWriter", "status": "completed", "blockedBy": [7]},
{"id": 12, "subject": "Task 12: RedactingAuditWriter", "status": "completed", "blockedBy": [7]},
{"id": 13, "subject": "Task 13: AddZbAudit DI extension", "status": "completed", "blockedBy": [8, 10]},
{"id": 14, "subject": "Task 14: Full test run + dotnet pack @ 0.1.0", "status": "completed", "blockedBy": [13]},
{"id": 15, "subject": "Task 15: Index/registry updates + GAPS cross-check", "status": "completed", "blockedBy": [14]}
],
"lastUpdated": "2026-06-01"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (ZB.MOM.WW.Audit built (1 pkg @ 0.1.0, 23 tests) and DEEP-adopted by all three apps 2026-06-02); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -2,22 +2,23 @@
"planPath": "docs/plans/2026-06-01-zb-mom-ww-auth-shared-library.md",
"repo": "~/Desktop/scadaproj/ZB.MOM.WW.Auth",
"tasks": [
{"id": 1, "nativeId": 6, "subject": "Task 1: Scaffold repo, solution, projects", "status": "pending", "blockedBy": []},
{"id": 2, "nativeId": 7, "subject": "Task 2: Abstractions — all contract types", "status": "pending", "blockedBy": [1]},
{"id": 3, "nativeId": 8, "subject": "Task 3: LDAP filter & DN escaping", "status": "pending", "blockedBy": [2]},
{"id": 4, "nativeId": 9, "subject": "Task 4: ILdapConnection seam + Novell adapter + fake", "status": "pending", "blockedBy": [2]},
{"id": 5, "nativeId": 10, "subject": "Task 5: LdapAuthService happy path + validation", "status": "pending", "blockedBy": [3, 4]},
{"id": 6, "nativeId": 11, "subject": "Task 6: LdapAuthService failure modes (fail-closed)", "status": "pending", "blockedBy": [5]},
{"id": 7, "nativeId": 12, "subject": "Task 7: GLAuth integration test (skippable)", "status": "pending", "blockedBy": [6]},
{"id": 8, "nativeId": 13, "subject": "Task 8: API-key token parser + secret generator", "status": "pending", "blockedBy": [2]},
{"id": 9, "nativeId": 14, "subject": "Task 9: Peppered HMAC hasher + constant-time compare", "status": "pending", "blockedBy": [2]},
{"id": 10, "nativeId": 15, "subject": "Task 10: SQLite schema + connection factory + migrator", "status": "pending", "blockedBy": [2]},
{"id": 11, "nativeId": 16, "subject": "Task 11: SqliteApiKeyStore (read + mark-used)", "status": "pending", "blockedBy": [10]},
{"id": 12, "nativeId": 17, "subject": "Task 12: SqliteApiKeyAdminStore + audit", "status": "pending", "blockedBy": [11]},
{"id": 13, "nativeId": 18, "subject": "Task 13: ApiKeyVerifier pipeline", "status": "pending", "blockedBy": [8, 9, 11]},
{"id": 14, "nativeId": 19, "subject": "Task 14: Reusable admin command set", "status": "pending", "blockedBy": [12]},
{"id": 15, "nativeId": 20, "subject": "Task 15: AspNetCore claim types, cookie defaults, DI", "status": "pending", "blockedBy": [5, 13]},
{"id": 16, "nativeId": 21, "subject": "Task 16: Packaging — nupkgs, push script, README", "status": "pending", "blockedBy": [7, 14, 15]}
{"id": 1, "nativeId": 6, "subject": "Task 1: Scaffold repo, solution, projects", "status": "completed", "blockedBy": []},
{"id": 2, "nativeId": 7, "subject": "Task 2: Abstractions — all contract types", "status": "completed", "blockedBy": [1]},
{"id": 3, "nativeId": 8, "subject": "Task 3: LDAP filter & DN escaping", "status": "completed", "blockedBy": [2]},
{"id": 4, "nativeId": 9, "subject": "Task 4: ILdapConnection seam + Novell adapter + fake", "status": "completed", "blockedBy": [2]},
{"id": 5, "nativeId": 10, "subject": "Task 5: LdapAuthService happy path + validation", "status": "completed", "blockedBy": [3, 4]},
{"id": 6, "nativeId": 11, "subject": "Task 6: LdapAuthService failure modes (fail-closed)", "status": "completed", "blockedBy": [5]},
{"id": 7, "nativeId": 12, "subject": "Task 7: GLAuth integration test (skippable)", "status": "completed", "blockedBy": [6]},
{"id": 8, "nativeId": 13, "subject": "Task 8: API-key token parser + secret generator", "status": "completed", "blockedBy": [2]},
{"id": 9, "nativeId": 14, "subject": "Task 9: Peppered HMAC hasher + constant-time compare", "status": "completed", "blockedBy": [2]},
{"id": 10, "nativeId": 15, "subject": "Task 10: SQLite schema + connection factory + migrator", "status": "completed", "blockedBy": [2]},
{"id": 11, "nativeId": 16, "subject": "Task 11: SqliteApiKeyStore (read + mark-used)", "status": "completed", "blockedBy": [10]},
{"id": 12, "nativeId": 17, "subject": "Task 12: SqliteApiKeyAdminStore + audit", "status": "completed", "blockedBy": [11]},
{"id": 13, "nativeId": 18, "subject": "Task 13: ApiKeyVerifier pipeline", "status": "completed", "blockedBy": [8, 9, 11]},
{"id": 14, "nativeId": 19, "subject": "Task 14: Reusable admin command set", "status": "completed", "blockedBy": [12]},
{"id": 15, "nativeId": 20, "subject": "Task 15: AspNetCore claim types, cookie defaults, DI", "status": "completed", "blockedBy": [5, 13]},
{"id": 16, "nativeId": 21, "subject": "Task 16: Packaging — nupkgs, push script, README", "status": "completed", "blockedBy": [7, 14, 15]}
],
"lastUpdated": "2026-06-01"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (ZB.MOM.WW.Auth built (4 pkgs, feed 0.1.0-0.1.5, 215 tests) and adopted by all apps 2026-06-02); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,17 +1,18 @@
{
"planPath": "docs/plans/2026-06-01-zb-mom-ww-health-shared-library.md",
"tasks": [
{"id": 1, "subject": "Task 1: components/health spec + shared-contract", "status": "pending"},
{"id": 2, "subject": "Task 2: components/health current-state x3 + GAPS + README", "status": "pending"},
{"id": 3, "subject": "Task 3: scaffold solution + 3 libs + 3 tests", "status": "pending"},
{"id": 4, "subject": "Task 4: canonical tags + MapZbHealth tier mapping", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: canonical JSON response writer", "status": "pending", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: IActiveNodeGate seam + RequireActiveNode filter", "status": "pending", "blockedBy": [3]},
{"id": 7, "subject": "Task 7: GrpcDependencyHealthCheck", "status": "pending", "blockedBy": [3]},
{"id": 8, "subject": "Task 8: AkkaClusterHealthCheck + status policy", "status": "pending", "blockedBy": [3]},
{"id": 9, "subject": "Task 9: ActiveNodeHealthCheck + role filter + AkkaActiveNodeGate", "status": "pending", "blockedBy": [3, 6]},
{"id": 10, "subject": "Task 10: DatabaseHealthCheck<TContext> (EF)", "status": "pending", "blockedBy": [3]},
{"id": 11, "subject": "Task 11: pack + README + register indexes", "status": "pending", "blockedBy": [1, 2, 4, 5, 6, 7, 8, 9, 10]}
{"id": 1, "subject": "Task 1: components/health spec + shared-contract", "status": "completed"},
{"id": 2, "subject": "Task 2: components/health current-state x3 + GAPS + README", "status": "completed"},
{"id": 3, "subject": "Task 3: scaffold solution + 3 libs + 3 tests", "status": "completed"},
{"id": 4, "subject": "Task 4: canonical tags + MapZbHealth tier mapping", "status": "completed", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: canonical JSON response writer", "status": "completed", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: IActiveNodeGate seam + RequireActiveNode filter", "status": "completed", "blockedBy": [3]},
{"id": 7, "subject": "Task 7: GrpcDependencyHealthCheck", "status": "completed", "blockedBy": [3]},
{"id": 8, "subject": "Task 8: AkkaClusterHealthCheck + status policy", "status": "completed", "blockedBy": [3]},
{"id": 9, "subject": "Task 9: ActiveNodeHealthCheck + role filter + AkkaActiveNodeGate", "status": "completed", "blockedBy": [3, 6]},
{"id": 10, "subject": "Task 10: DatabaseHealthCheck<TContext> (EF)", "status": "completed", "blockedBy": [3]},
{"id": 11, "subject": "Task 11: pack + README + register indexes", "status": "completed", "blockedBy": [1, 2, 4, 5, 6, 7, 8, 9, 10]}
],
"lastUpdated": "2026-06-01"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (ZB.MOM.WW.Health built (3 pkgs, current 0.3.0) and adopted by all 4 apps); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,18 +1,19 @@
{
"planPath": "docs/plans/2026-06-01-zb-mom-ww-telemetry-shared-library.md",
"tasks": [
{"id": 1, "subject": "Task 1: components/observability spec + METRIC-CONVENTIONS + shared-contract", "status": "pending"},
{"id": 2, "subject": "Task 2: components/observability current-state x3 + GAPS + README", "status": "pending"},
{"id": 3, "subject": "Task 3: scaffold solution + 2 libs + 2 tests", "status": "pending"},
{"id": 4, "subject": "Task 4: ZbTelemetryOptions + shared OTel Resource", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: AddZbTelemetry metrics+traces bootstrap", "status": "pending", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: MapZbMetrics Prometheus endpoint", "status": "pending", "blockedBy": [5]},
{"id": 7, "subject": "Task 7: identity enrichers + AddZbSerilog bootstrap", "status": "pending", "blockedBy": [3, 4]},
{"id": 8, "subject": "Task 8: TraceContextEnricher (trace<->log correlation)", "status": "pending", "blockedBy": [7]},
{"id": 9, "subject": "Task 9: ILogRedactor seam + OTel log export", "status": "pending", "blockedBy": [8]},
{"id": 10, "subject": "Task 10: MxGateway swap bootstrap to AddZbSerilog (sister-repo)", "status": "pending", "blockedBy": [9]},
{"id": 11, "subject": "Task 11: MxGateway correlation scope + redactor on shared seam (sister-repo)", "status": "pending", "blockedBy": [10]},
{"id": 12, "subject": "Task 12: pack + README + register indexes + upcoming.md", "status": "pending", "blockedBy": [1, 2, 6, 9, 11]}
{"id": 1, "subject": "Task 1: components/observability spec + METRIC-CONVENTIONS + shared-contract", "status": "completed"},
{"id": 2, "subject": "Task 2: components/observability current-state x3 + GAPS + README", "status": "completed"},
{"id": 3, "subject": "Task 3: scaffold solution + 2 libs + 2 tests", "status": "completed"},
{"id": 4, "subject": "Task 4: ZbTelemetryOptions + shared OTel Resource", "status": "completed", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: AddZbTelemetry metrics+traces bootstrap", "status": "completed", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: MapZbMetrics Prometheus endpoint", "status": "completed", "blockedBy": [5]},
{"id": 7, "subject": "Task 7: identity enrichers + AddZbSerilog bootstrap", "status": "completed", "blockedBy": [3, 4]},
{"id": 8, "subject": "Task 8: TraceContextEnricher (trace<->log correlation)", "status": "completed", "blockedBy": [7]},
{"id": 9, "subject": "Task 9: ILogRedactor seam + OTel log export", "status": "completed", "blockedBy": [8]},
{"id": 10, "subject": "Task 10: MxGateway swap bootstrap to AddZbSerilog (sister-repo)", "status": "completed", "blockedBy": [9]},
{"id": 11, "subject": "Task 11: MxGateway correlation scope + redactor on shared seam (sister-repo)", "status": "completed", "blockedBy": [10]},
{"id": 12, "subject": "Task 12: pack + README + register indexes + upcoming.md", "status": "completed", "blockedBy": [1, 2, 6, 9, 11]}
],
"lastUpdated": "2026-06-01"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (ZB.MOM.WW.Telemetry built (2 pkgs @ 0.1.0, 34 tests) and adopted by all apps 2026-06-01); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -2,24 +2,25 @@
"planPath": "docs/plans/2026-06-01-zb-mom-ww-theme-shared-library.md",
"repo": "~/Desktop/scadaproj",
"tasks": [
{"id": 1, "nativeId": 28, "subject": "Task 1: Scaffold ZB.MOM.WW.Theme RCL", "classification": "standard", "status": "pending", "blockedBy": []},
{"id": 2, "nativeId": 29, "subject": "Task 2: Static assets — tokens, fonts, layout CSS", "classification": "standard", "status": "pending", "blockedBy": [1]},
{"id": 3, "nativeId": 30, "subject": "Task 3: StatusState enum + StatusPill", "classification": "small", "status": "pending", "blockedBy": [1]},
{"id": 4, "nativeId": 31, "subject": "Task 4: BrandBar", "classification": "small", "status": "pending", "blockedBy": [1]},
{"id": 5, "nativeId": 32, "subject": "Task 5: NavRailItem + NavRailSection", "classification": "standard", "status": "pending", "blockedBy": [1]},
{"id": 6, "nativeId": 33, "subject": "Task 6: ThemeShell canonical side-rail", "classification": "standard", "status": "pending", "blockedBy": [4]},
{"id": 7, "nativeId": 34, "subject": "Task 7: LoginCard", "classification": "standard", "status": "pending", "blockedBy": [1]},
{"id": 8, "nativeId": 35, "subject": "Task 8: TechButton + TechCard + TechField", "classification": "standard", "status": "pending", "blockedBy": [1]},
{"id": 9, "nativeId": 36, "subject": "Task 9: ThemeHead stylesheet entry point", "classification": "small", "status": "pending", "blockedBy": [1]},
{"id": 10, "nativeId": 37, "subject": "Task 10: Full build, pack, RCL README", "classification": "standard", "status": "pending", "blockedBy": [2, 3, 4, 5, 6, 7, 8, 9]},
{"id": 11, "nativeId": 38, "subject": "Task 11: ui-theme docs — spec, tokens, contract, README", "classification": "standard", "status": "pending", "blockedBy": []},
{"id": 12, "nativeId": 39, "subject": "Task 12: ui-theme docs — current-state ×3 + GAPS", "classification": "standard", "status": "pending", "blockedBy": [11]},
{"id": 13, "nativeId": 40, "subject": "Task 13: Register ui-theme component in indexes", "classification": "small", "status": "pending", "blockedBy": [11, 12]}
{"id": 1, "nativeId": 28, "subject": "Task 1: Scaffold ZB.MOM.WW.Theme RCL", "classification": "standard", "status": "completed", "blockedBy": []},
{"id": 2, "nativeId": 29, "subject": "Task 2: Static assets — tokens, fonts, layout CSS", "classification": "standard", "status": "completed", "blockedBy": [1]},
{"id": 3, "nativeId": 30, "subject": "Task 3: StatusState enum + StatusPill", "classification": "small", "status": "completed", "blockedBy": [1]},
{"id": 4, "nativeId": 31, "subject": "Task 4: BrandBar", "classification": "small", "status": "completed", "blockedBy": [1]},
{"id": 5, "nativeId": 32, "subject": "Task 5: NavRailItem + NavRailSection", "classification": "standard", "status": "completed", "blockedBy": [1]},
{"id": 6, "nativeId": 33, "subject": "Task 6: ThemeShell canonical side-rail", "classification": "standard", "status": "completed", "blockedBy": [4]},
{"id": 7, "nativeId": 34, "subject": "Task 7: LoginCard", "classification": "standard", "status": "completed", "blockedBy": [1]},
{"id": 8, "nativeId": 35, "subject": "Task 8: TechButton + TechCard + TechField", "classification": "standard", "status": "completed", "blockedBy": [1]},
{"id": 9, "nativeId": 36, "subject": "Task 9: ThemeHead stylesheet entry point", "classification": "small", "status": "completed", "blockedBy": [1]},
{"id": 10, "nativeId": 37, "subject": "Task 10: Full build, pack, RCL README", "classification": "standard", "status": "completed", "blockedBy": [2, 3, 4, 5, 6, 7, 8, 9]},
{"id": 11, "nativeId": 38, "subject": "Task 11: ui-theme docs — spec, tokens, contract, README", "classification": "standard", "status": "completed", "blockedBy": []},
{"id": 12, "nativeId": 39, "subject": "Task 12: ui-theme docs — current-state ×3 + GAPS", "classification": "standard", "status": "completed", "blockedBy": [11]},
{"id": 13, "nativeId": 40, "subject": "Task 13: Register ui-theme component in indexes", "classification": "small", "status": "completed", "blockedBy": [11, 12]}
],
"parallelism": {
"after_task_1": [2, 3, 4, 5, 7, 8, 9],
"task_6_waits_on": 4,
"docs_parallel_with_build": [11, 12, 13]
},
"lastUpdated": "2026-06-01"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (ZB.MOM.WW.Theme RCL built (feed 0.2.0-0.3.1, 48 bUnit tests) and adopted by all apps); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,32 +1,33 @@
{
"planPath": "docs/plans/2026-06-03-ui-theme-adoption.md",
"tasks": [
{"id": 44, "subject": "Task 0.1: NavRailSection persistence key", "status": "pending"},
{"id": 45, "subject": "Task 0.2: nav-state.js enhancer + ThemeScripts", "status": "pending"},
{"id": 46, "subject": "Task 0.3: Bump 0.2.0 + full suite", "status": "pending", "blockedBy": [44, 45]},
{"id": 47, "subject": "Task 0.4: Publish 0.2.0 to Gitea feed", "status": "pending", "blockedBy": [46]},
{"id": 48, "subject": "Task 1.1: OtOpcUa NuGet wiring + usings", "status": "pending", "blockedBy": [47]},
{"id": 49, "subject": "Task 1.2: OtOpcUa App.razor ThemeHead/ThemeScripts", "status": "pending", "blockedBy": [48]},
{"id": 50, "subject": "Task 1.3: OtOpcUa migrate CSS, delete theme.css/fonts/nav-state.js", "status": "pending", "blockedBy": [48]},
{"id": 51, "subject": "Task 1.4: OtOpcUa MainLayout to ThemeShell + kit nav", "status": "pending", "blockedBy": [48]},
{"id": 52, "subject": "Task 1.5: OtOpcUa delete dead StatusBadge + Login to LoginCard", "status": "pending", "blockedBy": [48]},
{"id": 53, "subject": "Task 1.6: OtOpcUa build/test/visual checklist", "status": "pending", "blockedBy": [49, 50, 51, 52]},
{"id": 54, "subject": "Task 2.1: ScadaBridge NuGet wiring + usings", "status": "pending", "blockedBy": [47]},
{"id": 55, "subject": "Task 2.2: ScadaBridge Host App.razor ThemeHead/ThemeScripts", "status": "pending", "blockedBy": [54]},
{"id": 56, "subject": "Task 2.3: ScadaBridge migrate CSS, delete theme.css/fonts/nav-state.js", "status": "pending", "blockedBy": [54]},
{"id": 57, "subject": "Task 2.4: ScadaBridge MainLayout/NavMenu to ThemeShell (preserve AuthorizeView/DialogHost/SessionExpiry)", "status": "pending", "blockedBy": [54]},
{"id": 58, "subject": "Task 2.5: ScadaBridge Login to LoginCard", "status": "pending", "blockedBy": [54]},
{"id": 59, "subject": "Task 2.6: ScadaBridge build/test/visual checklist", "status": "pending", "blockedBy": [55, 56, 57, 58]},
{"id": 60, "subject": "Task 3.1: MxGateway NuGet wiring + usings (no central PM)", "status": "pending", "blockedBy": [47]},
{"id": 61, "subject": "Task 3.2: MxGateway App.razor ThemeHead/ThemeScripts", "status": "pending", "blockedBy": [60]},
{"id": 62, "subject": "Task 3.3: MxGateway migrate CSS, delete theme.css/fonts/nav-state.js", "status": "pending", "blockedBy": [60]},
{"id": 63, "subject": "Task 3.4: MxGateway split combined MainLayout to ThemeShell", "status": "pending", "blockedBy": [60]},
{"id": 64, "subject": "Task 3.5: MxGateway StatusBadge to StatusPill adapter", "status": "pending", "blockedBy": [60]},
{"id": 65, "subject": "Task 3.6: MxGateway net-new Blazor LoginCard page", "status": "pending", "blockedBy": [63]},
{"id": 66, "subject": "Task 3.7: MxGateway build/test/login smoke", "status": "pending", "blockedBy": [61, 62, 63, 64, 65]},
{"id": 67, "subject": "Task 4.1: Update component docs", "status": "pending", "blockedBy": [53, 59, 66]},
{"id": 68, "subject": "Task 4.2: Update memory", "status": "pending", "blockedBy": [53, 59, 66]},
{"id": 69, "subject": "Task 4.3: Final integration review", "status": "pending", "blockedBy": [67, 68]}
{"id": 44, "subject": "Task 0.1: NavRailSection persistence key", "status": "completed"},
{"id": 45, "subject": "Task 0.2: nav-state.js enhancer + ThemeScripts", "status": "completed"},
{"id": 46, "subject": "Task 0.3: Bump 0.2.0 + full suite", "status": "completed", "blockedBy": [44, 45]},
{"id": 47, "subject": "Task 0.4: Publish 0.2.0 to Gitea feed", "status": "completed", "blockedBy": [46]},
{"id": 48, "subject": "Task 1.1: OtOpcUa NuGet wiring + usings", "status": "completed", "blockedBy": [47]},
{"id": 49, "subject": "Task 1.2: OtOpcUa App.razor ThemeHead/ThemeScripts", "status": "completed", "blockedBy": [48]},
{"id": 50, "subject": "Task 1.3: OtOpcUa migrate CSS, delete theme.css/fonts/nav-state.js", "status": "completed", "blockedBy": [48]},
{"id": 51, "subject": "Task 1.4: OtOpcUa MainLayout to ThemeShell + kit nav", "status": "completed", "blockedBy": [48]},
{"id": 52, "subject": "Task 1.5: OtOpcUa delete dead StatusBadge + Login to LoginCard", "status": "completed", "blockedBy": [48]},
{"id": 53, "subject": "Task 1.6: OtOpcUa build/test/visual checklist", "status": "completed", "blockedBy": [49, 50, 51, 52]},
{"id": 54, "subject": "Task 2.1: ScadaBridge NuGet wiring + usings", "status": "completed", "blockedBy": [47]},
{"id": 55, "subject": "Task 2.2: ScadaBridge Host App.razor ThemeHead/ThemeScripts", "status": "completed", "blockedBy": [54]},
{"id": 56, "subject": "Task 2.3: ScadaBridge migrate CSS, delete theme.css/fonts/nav-state.js", "status": "completed", "blockedBy": [54]},
{"id": 57, "subject": "Task 2.4: ScadaBridge MainLayout/NavMenu to ThemeShell (preserve AuthorizeView/DialogHost/SessionExpiry)", "status": "completed", "blockedBy": [54]},
{"id": 58, "subject": "Task 2.5: ScadaBridge Login to LoginCard", "status": "completed", "blockedBy": [54]},
{"id": 59, "subject": "Task 2.6: ScadaBridge build/test/visual checklist", "status": "completed", "blockedBy": [55, 56, 57, 58]},
{"id": 60, "subject": "Task 3.1: MxGateway NuGet wiring + usings (no central PM)", "status": "completed", "blockedBy": [47]},
{"id": 61, "subject": "Task 3.2: MxGateway App.razor ThemeHead/ThemeScripts", "status": "completed", "blockedBy": [60]},
{"id": 62, "subject": "Task 3.3: MxGateway migrate CSS, delete theme.css/fonts/nav-state.js", "status": "completed", "blockedBy": [60]},
{"id": 63, "subject": "Task 3.4: MxGateway split combined MainLayout to ThemeShell", "status": "completed", "blockedBy": [60]},
{"id": 64, "subject": "Task 3.5: MxGateway StatusBadge to StatusPill adapter", "status": "completed", "blockedBy": [60]},
{"id": 65, "subject": "Task 3.6: MxGateway net-new Blazor LoginCard page", "status": "completed", "blockedBy": [63]},
{"id": 66, "subject": "Task 3.7: MxGateway build/test/login smoke", "status": "completed", "blockedBy": [61, 62, 63, 64, 65]},
{"id": 67, "subject": "Task 4.1: Update component docs", "status": "completed", "blockedBy": [53, 59, 66]},
{"id": 68, "subject": "Task 4.2: Update memory", "status": "completed", "blockedBy": [53, 59, 66]},
{"id": 69, "subject": "Task 4.3: Final integration review", "status": "completed", "blockedBy": [67, 68]}
],
"lastUpdated": "2026-06-03"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (UI-theme adopted across all three apps 2026-06-03, merged + pushed; all 4 apps pinned 0.3.1); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,37 +1,38 @@
{
"planPath": "docs/plans/2026-06-23-historian-gateway-implementation.md",
"tasks": [
{"id": 1, "subject": "Task 1: Scaffold the GalaxyRepository lib project", "status": "pending"},
{"id": 2, "subject": "Task 2: Port the canonical galaxy_repository.proto (neutral namespace)", "status": "pending", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: Port the SQL browse provider", "status": "pending", "blockedBy": [2]},
{"id": 4, "subject": "Task 4: Port the in-memory hierarchy cache + snapshot + refresh service", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: Port the reusable gRPC service + DI extension", "status": "pending", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: Unit tests for projector/cache; pack 0.1.0", "status": "pending", "blockedBy": [5]},
{"id": 7, "subject": "Task 7: Vendor histsdk AVEVA.Historian.Client + golden tests", "status": "pending"},
{"id": 8, "subject": "Task 8: Init sidecar repo + solution + Directory.Build.props", "status": "pending", "blockedBy": [7]},
{"id": 9, "subject": "Task 9: Contracts project + historian_gateway.proto skeleton", "status": "pending", "blockedBy": [8]},
{"id": 10, "subject": "Task 10: Server project + minimal boot (telemetry/serilog/health)", "status": "pending", "blockedBy": [9, 7, 6]},
{"id": 11, "subject": "Task 11: Configuration options + validators + ConfigPreflight", "status": "pending", "blockedBy": [10]},
{"id": 12, "subject": "Task 12: IHistorianClient seam over vendored client", "status": "pending", "blockedBy": [10]},
{"id": 13, "subject": "Task 13: Connection pool (pre-authenticated, reused)", "status": "pending", "blockedBy": [12]},
{"id": 14, "subject": "Task 14: Write coordinator (store-forward + redundancy) + SQL live-write", "status": "pending", "blockedBy": [13]},
{"id": 15, "subject": "Task 15: HistorianRead service + proto mapper", "status": "pending", "blockedBy": [13]},
{"id": 16, "subject": "Task 16: HistorianWrite service", "status": "pending", "blockedBy": [14, 15]},
{"id": 17, "subject": "Task 17: HistorianTags service", "status": "pending", "blockedBy": [13, 15]},
{"id": 18, "subject": "Task 18: HistorianStatus service", "status": "pending", "blockedBy": [13, 15]},
{"id": 19, "subject": "Task 19: Galaxy gRPC wiring (consume shared lib)", "status": "pending", "blockedBy": [10, 5]},
{"id": 20, "subject": "Task 20: API-key auth interceptor + scope resolver", "status": "pending", "blockedBy": [15]},
{"id": 21, "subject": "Task 21: SQLite audit writer + actor accessor + wiring", "status": "pending", "blockedBy": [16, 17, 20]},
{"id": 22, "subject": "Task 22: Dashboard shell + LDAP cookie auth + login", "status": "pending", "blockedBy": [20]},
{"id": 23, "subject": "Task 23: Status + Health pages", "status": "pending", "blockedBy": [22, 14]},
{"id": 24, "subject": "Task 24: Galaxy browser page", "status": "pending", "blockedBy": [22, 19]},
{"id": 25, "subject": "Task 25: Historian console page (role-gated write)", "status": "pending", "blockedBy": [22, 15]},
{"id": 26, "subject": "Task 26: API-key admin page", "status": "pending", "blockedBy": [22]},
{"id": 27, "subject": "Task 27: App meters", "status": "pending", "blockedBy": [14]},
{"id": 28, "subject": "Task 28: Health probes", "status": "pending", "blockedBy": [14, 19]},
{"id": 29, "subject": "Task 29: Env-gated live integration tests", "status": "pending", "blockedBy": [16, 17, 18, 19]},
{"id": 30, "subject": "Task 30: Full-suite green gate + smoke", "status": "pending", "blockedBy": [21, 26, 27, 28, 29]},
{"id": 31, "subject": "Task 31: CLAUDE.md + README + gitea remote + scadaproj index", "status": "pending", "blockedBy": [30]}
{"id": 1, "subject": "Task 1: Scaffold the GalaxyRepository lib project", "status": "completed"},
{"id": 2, "subject": "Task 2: Port the canonical galaxy_repository.proto (neutral namespace)", "status": "completed", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: Port the SQL browse provider", "status": "completed", "blockedBy": [2]},
{"id": 4, "subject": "Task 4: Port the in-memory hierarchy cache + snapshot + refresh service", "status": "completed", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: Port the reusable gRPC service + DI extension", "status": "completed", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: Unit tests for projector/cache; pack 0.1.0", "status": "completed", "blockedBy": [5]},
{"id": 7, "subject": "Task 7: Vendor histsdk AVEVA.Historian.Client + golden tests", "status": "completed"},
{"id": 8, "subject": "Task 8: Init sidecar repo + solution + Directory.Build.props", "status": "completed", "blockedBy": [7]},
{"id": 9, "subject": "Task 9: Contracts project + historian_gateway.proto skeleton", "status": "completed", "blockedBy": [8]},
{"id": 10, "subject": "Task 10: Server project + minimal boot (telemetry/serilog/health)", "status": "completed", "blockedBy": [9, 7, 6]},
{"id": 11, "subject": "Task 11: Configuration options + validators + ConfigPreflight", "status": "completed", "blockedBy": [10]},
{"id": 12, "subject": "Task 12: IHistorianClient seam over vendored client", "status": "completed", "blockedBy": [10]},
{"id": 13, "subject": "Task 13: Connection pool (pre-authenticated, reused)", "status": "completed", "blockedBy": [12]},
{"id": 14, "subject": "Task 14: Write coordinator (store-forward + redundancy) + SQL live-write", "status": "completed", "blockedBy": [13]},
{"id": 15, "subject": "Task 15: HistorianRead service + proto mapper", "status": "completed", "blockedBy": [13]},
{"id": 16, "subject": "Task 16: HistorianWrite service", "status": "completed", "blockedBy": [14, 15]},
{"id": 17, "subject": "Task 17: HistorianTags service", "status": "completed", "blockedBy": [13, 15]},
{"id": 18, "subject": "Task 18: HistorianStatus service", "status": "completed", "blockedBy": [13, 15]},
{"id": 19, "subject": "Task 19: Galaxy gRPC wiring (consume shared lib)", "status": "completed", "blockedBy": [10, 5]},
{"id": 20, "subject": "Task 20: API-key auth interceptor + scope resolver", "status": "completed", "blockedBy": [15]},
{"id": 21, "subject": "Task 21: SQLite audit writer + actor accessor + wiring", "status": "completed", "blockedBy": [16, 17, 20]},
{"id": 22, "subject": "Task 22: Dashboard shell + LDAP cookie auth + login", "status": "completed", "blockedBy": [20]},
{"id": 23, "subject": "Task 23: Status + Health pages", "status": "completed", "blockedBy": [22, 14]},
{"id": 24, "subject": "Task 24: Galaxy browser page", "status": "completed", "blockedBy": [22, 19]},
{"id": 25, "subject": "Task 25: Historian console page (role-gated write)", "status": "completed", "blockedBy": [22, 15]},
{"id": 26, "subject": "Task 26: API-key admin page", "status": "completed", "blockedBy": [22]},
{"id": 27, "subject": "Task 27: App meters", "status": "completed", "blockedBy": [14]},
{"id": 28, "subject": "Task 28: Health probes", "status": "completed", "blockedBy": [14, 19]},
{"id": 29, "subject": "Task 29: Env-gated live integration tests", "status": "completed", "blockedBy": [16, 17, 18, 19]},
{"id": 30, "subject": "Task 30: Full-suite green gate + smoke", "status": "completed", "blockedBy": [21, 26, 27, 28, 29]},
{"id": 31, "subject": "Task 31: CLAUDE.md + README + gitea remote + scadaproj index", "status": "completed", "blockedBy": [30]}
],
"lastUpdated": "2026-06-23"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (HistorianGateway fully built + shipped (gRPC sidecar + dashboard, live-proven vs wonder-sql-vd03)); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,20 +1,21 @@
{
"planPath": "docs/plans/2026-07-15-secrets-manager.md",
"tasks": [
{"id": 1, "subject": "Task 1: Scaffold solution + 4 projects + build props", "status": "pending"},
{"id": 2, "subject": "Task 2: Abstractions value types/enums/exceptions", "status": "pending", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: Abstractions seam interfaces", "status": "pending", "blockedBy": [2]},
{"id": 4, "subject": "Task 4: AesGcmEnvelopeCipher", "status": "pending", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: Master-key providers + factory", "status": "pending", "blockedBy": [3]},
{"id": 6, "subject": "Task 6: SQLite factory + schema v1 + migrator", "status": "pending", "blockedBy": [3]},
{"id": 7, "subject": "Task 7: SqliteSecretStore CRUD/tombstone/manifest/LWW", "status": "pending", "blockedBy": [6]},
{"id": 8, "subject": "Task 8: DefaultSecretResolver (decrypt+cache+audit)", "status": "pending", "blockedBy": [4, 7]},
{"id": 9, "subject": "Task 9: ${secret:} config expander", "status": "pending", "blockedBy": [3]},
{"id": 10, "subject": "Task 10: SecretsOptions + AddZbSecrets DI + migration hosted service", "status": "pending", "blockedBy": [4, 5, 6, 7, 8, 9]},
{"id": 11, "subject": "Task 11: Ui RCL + authz policies + secrets list", "status": "pending", "blockedBy": [3]},
{"id": 12, "subject": "Task 12: Ui add/rotate/delete modal + gated reveal", "status": "pending", "blockedBy": [11]},
{"id": 13, "subject": "Task 13: Secrets.Cli commands", "status": "pending", "blockedBy": [10]},
{"id": 14, "subject": "Task 14: Pack + wire HistorianGateway + live verify", "status": "pending", "blockedBy": [10, 12, 13]}
{"id": 1, "subject": "Task 1: Scaffold solution + 4 projects + build props", "status": "completed"},
{"id": 2, "subject": "Task 2: Abstractions value types/enums/exceptions", "status": "completed", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: Abstractions seam interfaces", "status": "completed", "blockedBy": [2]},
{"id": 4, "subject": "Task 4: AesGcmEnvelopeCipher", "status": "completed", "blockedBy": [3]},
{"id": 5, "subject": "Task 5: Master-key providers + factory", "status": "completed", "blockedBy": [3]},
{"id": 6, "subject": "Task 6: SQLite factory + schema v1 + migrator", "status": "completed", "blockedBy": [3]},
{"id": 7, "subject": "Task 7: SqliteSecretStore CRUD/tombstone/manifest/LWW", "status": "completed", "blockedBy": [6]},
{"id": 8, "subject": "Task 8: DefaultSecretResolver (decrypt+cache+audit)", "status": "completed", "blockedBy": [4, 7]},
{"id": 9, "subject": "Task 9: ${secret:} config expander", "status": "completed", "blockedBy": [3]},
{"id": 10, "subject": "Task 10: SecretsOptions + AddZbSecrets DI + migration hosted service", "status": "completed", "blockedBy": [4, 5, 6, 7, 8, 9]},
{"id": 11, "subject": "Task 11: Ui RCL + authz policies + secrets list", "status": "completed", "blockedBy": [3]},
{"id": 12, "subject": "Task 12: Ui add/rotate/delete modal + gated reveal", "status": "completed", "blockedBy": [11]},
{"id": 13, "subject": "Task 13: Secrets.Cli commands", "status": "completed", "blockedBy": [10]},
{"id": 14, "subject": "Task 14: Pack + wire HistorianGateway + live verify", "status": "completed", "blockedBy": [10, 12, 13]}
],
"lastUpdated": "2026-07-15"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (ZB.MOM.WW.Secrets lib built + published (feed through 0.3.0)); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -4,14 +4,15 @@
"app": "MxAccessGateway",
"gaps": ["G-4", "G-5", "G-6"],
"tasks": [
{"id": 1, "subject": "Package references + nuget.config packageSourceMapping", "status": "pending", "classification": "small"},
{"id": 2, "subject": "Pre-host ${secret:} expander in GatewayApplication.CreateBuilder (G-4 mechanism)", "status": "pending", "classification": "standard", "blockedBy": [1]},
{"id": 3, "subject": "Runtime AddZbSecrets registration on the host container", "status": "pending", "classification": "trivial", "blockedBy": [2]},
{"id": 4, "subject": "Switch LDAP ServiceAccountPassword to ${secret:} + seed + remove hardcoded defaults (G-4)", "status": "pending", "classification": "standard", "blockedBy": [3]},
{"id": 5, "subject": "(Optional) Galaxy connstr + API-key pepper to ${secret:}", "status": "pending", "classification": "small", "blockedBy": [4]},
{"id": 6, "subject": "AddSecretsAuthorization + mount /admin/secrets in Router & endpoint (G-6)", "status": "pending", "classification": "standard", "blockedBy": [3]},
{"id": 7, "subject": "Master-key provider config for the NSSM box (G-5, Environment) + operator note", "status": "pending", "classification": "small", "blockedBy": [2]},
{"id": 8, "subject": "Verification gate: 0-warning build, UI reveal+audit, SignalR unaffected", "status": "pending", "classification": "standard", "blockedBy": [1, 2, 3, 4, 5, 6, 7]}
{"id": 1, "subject": "Package references + nuget.config packageSourceMapping", "status": "completed", "classification": "small"},
{"id": 2, "subject": "Pre-host ${secret:} expander in GatewayApplication.CreateBuilder (G-4 mechanism)", "status": "completed", "classification": "standard", "blockedBy": [1]},
{"id": 3, "subject": "Runtime AddZbSecrets registration on the host container", "status": "completed", "classification": "trivial", "blockedBy": [2]},
{"id": 4, "subject": "Switch LDAP ServiceAccountPassword to ${secret:} + seed + remove hardcoded defaults (G-4)", "status": "completed", "classification": "standard", "blockedBy": [3]},
{"id": 5, "subject": "(Optional) Galaxy connstr + API-key pepper to ${secret:}", "status": "completed", "classification": "small", "blockedBy": [4]},
{"id": 6, "subject": "AddSecretsAuthorization + mount /admin/secrets in Router & endpoint (G-6)", "status": "completed", "classification": "standard", "blockedBy": [3]},
{"id": 7, "subject": "Master-key provider config for the NSSM box (G-5, Environment) + operator note", "status": "completed", "classification": "small", "blockedBy": [2]},
{"id": 8, "subject": "Verification gate: 0-warning build, UI reveal+audit, SignalR unaffected", "status": "completed", "classification": "standard", "blockedBy": [1, 2, 3, 4, 5, 6, 7]}
],
"lastUpdated": "2026-07-16"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (mxaccessgw adopted G-4/G-5/G-6, merged to origin/main @ e088dfa 2026-07-16, box-verified); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -8,16 +8,17 @@
"2": {"desc": "Layer B driver secrets (G-2)", "tasks": [7, 8, 9, 10]}
},
"tasks": [
{"id": 1, "subject": "Package references + NuGet.config mapping", "status": "pending", "classification": "small", "slice": 1},
{"id": 2, "subject": "Pre-host ${secret:} expander in Host/Program.cs (G-4 mechanism)", "status": "pending", "classification": "standard", "slice": 1, "blockedBy": [1]},
{"id": 3, "subject": "Register AddZbSecrets on the runtime host UNCONDITIONALLY (surprise f)", "status": "pending", "classification": "high-risk", "slice": 1, "blockedBy": [2]},
{"id": 4, "subject": "G-4: switch config secrets to ${secret:} + seed + boot smoke + negative control", "status": "pending", "classification": "standard", "slice": 1, "blockedBy": [3]},
{"id": 5, "subject": "G-6: AddSecretsAuthorization() + mount /admin/secrets (both anchors)", "status": "pending", "classification": "standard", "slice": 1, "blockedBy": [3]},
{"id": 6, "subject": "G-5: File master-key posture for clustered nodes (the fork)", "status": "pending", "classification": "small", "slice": 1, "blockedBy": [2]},
{"id": 7, "subject": "G-2a: add secret: arm to GalaxySecretRef (Layer B)", "status": "pending", "classification": "high-risk", "slice": 2, "blockedBy": [3]},
{"id": 8, "subject": "G-2b: ISecretResolver hook in OpcUaClient factory AND probe (both call sites)", "status": "pending", "classification": "high-risk", "slice": 2, "blockedBy": [3]},
{"id": 9, "subject": "G-2c: AdminUI driver-config editor round-trip preserves secret: refs (surprise e)", "status": "pending", "classification": "standard", "slice": 2, "blockedBy": [7, 8]},
{"id": 10, "subject": "Verification (Slice 2 gate)", "status": "pending", "classification": "standard", "slice": 2, "blockedBy": [1, 2, 3, 4, 5, 6, 7, 8, 9]}
{"id": 1, "subject": "Package references + NuGet.config mapping", "status": "completed", "classification": "small", "slice": 1},
{"id": 2, "subject": "Pre-host ${secret:} expander in Host/Program.cs (G-4 mechanism)", "status": "completed", "classification": "standard", "slice": 1, "blockedBy": [1]},
{"id": 3, "subject": "Register AddZbSecrets on the runtime host UNCONDITIONALLY (surprise f)", "status": "completed", "classification": "high-risk", "slice": 1, "blockedBy": [2]},
{"id": 4, "subject": "G-4: switch config secrets to ${secret:} + seed + boot smoke + negative control", "status": "completed", "classification": "standard", "slice": 1, "blockedBy": [3]},
{"id": 5, "subject": "G-6: AddSecretsAuthorization() + mount /admin/secrets (both anchors)", "status": "completed", "classification": "standard", "slice": 1, "blockedBy": [3]},
{"id": 6, "subject": "G-5: File master-key posture for clustered nodes (the fork)", "status": "completed", "classification": "small", "slice": 1, "blockedBy": [2]},
{"id": 7, "subject": "G-2a: add secret: arm to GalaxySecretRef (Layer B)", "status": "completed", "classification": "high-risk", "slice": 2, "blockedBy": [3]},
{"id": 8, "subject": "G-2b: ISecretResolver hook in OpcUaClient factory AND probe (both call sites)", "status": "completed", "classification": "high-risk", "slice": 2, "blockedBy": [3]},
{"id": 9, "subject": "G-2c: AdminUI driver-config editor round-trip preserves secret: refs (surprise e)", "status": "completed", "classification": "standard", "slice": 2, "blockedBy": [7, 8]},
{"id": 10, "subject": "Verification (Slice 2 gate)", "status": "completed", "classification": "standard", "slice": 2, "blockedBy": [1, 2, 3, 4, 5, 6, 7, 8, 9]}
],
"lastUpdated": "2026-07-16"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (OtOpcUa adopted G-2/G-4/G-5/G-6, merged to origin/master @ 872cf7e3 2026-07-16, G-2 live-proven); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -8,16 +8,17 @@
"2": {"desc": "G-3 Layer-B MxGateway ApiKey", "tasks": [9, 10]}
},
"tasks": [
{"id": 1, "subject": "Package references + CPM versions + nuget.config mapping", "status": "pending", "classification": "small", "slice": 1},
{"id": 2, "subject": "Layer-A pre-host ${secret:} expander (G-4 mechanism)", "status": "pending", "classification": "standard", "slice": 1, "blockedBy": [1]},
{"id": 3, "subject": "Runtime AddZbSecrets on the host container", "status": "pending", "classification": "small", "slice": 1, "blockedBy": [2]},
{"id": 4, "subject": "G-4: formalize ${SCADABRIDGE_*} placeholders -> ${secret:} tokens", "status": "pending", "classification": "standard", "slice": 1, "blockedBy": [3]},
{"id": 5, "subject": "G-4 cleanup: remove committed dev plaintext + loose *_login.txt", "status": "pending", "classification": "small", "slice": 1, "blockedBy": [4]},
{"id": 6, "subject": "G-6: claim-type VERIFICATION (RequireRole vs RequireClaim)", "status": "pending", "classification": "high-risk", "slice": 1, "blockedBy": [1]},
{"id": 7, "subject": "G-6: register secrets authorization + mount /admin/secrets", "status": "pending", "classification": "standard", "slice": 1, "blockedBy": [3, 6]},
{"id": 8, "subject": "G-5: clustered master-key posture (central pair + site nodes)", "status": "pending", "classification": "standard", "slice": 1, "blockedBy": [2]},
{"id": 9, "subject": "G-3: resolve the MxGateway ApiKey secret: ref at runtime (Layer B)", "status": "pending", "classification": "high-risk", "slice": 2, "blockedBy": [3]},
{"id": 10, "subject": "Verification: build, suites, live connection", "status": "pending", "classification": "standard", "slice": 2, "blockedBy": [1, 2, 3, 4, 5, 6, 7, 8, 9]}
{"id": 1, "subject": "Package references + CPM versions + nuget.config mapping", "status": "completed", "classification": "small", "slice": 1},
{"id": 2, "subject": "Layer-A pre-host ${secret:} expander (G-4 mechanism)", "status": "completed", "classification": "standard", "slice": 1, "blockedBy": [1]},
{"id": 3, "subject": "Runtime AddZbSecrets on the host container", "status": "completed", "classification": "small", "slice": 1, "blockedBy": [2]},
{"id": 4, "subject": "G-4: formalize ${SCADABRIDGE_*} placeholders -> ${secret:} tokens", "status": "completed", "classification": "standard", "slice": 1, "blockedBy": [3]},
{"id": 5, "subject": "G-4 cleanup: remove committed dev plaintext + loose *_login.txt", "status": "completed", "classification": "small", "slice": 1, "blockedBy": [4]},
{"id": 6, "subject": "G-6: claim-type VERIFICATION (RequireRole vs RequireClaim)", "status": "completed", "classification": "high-risk", "slice": 1, "blockedBy": [1]},
{"id": 7, "subject": "G-6: register secrets authorization + mount /admin/secrets", "status": "completed", "classification": "standard", "slice": 1, "blockedBy": [3, 6]},
{"id": 8, "subject": "G-5: clustered master-key posture (central pair + site nodes)", "status": "completed", "classification": "standard", "slice": 1, "blockedBy": [2]},
{"id": 9, "subject": "G-3: resolve the MxGateway ApiKey secret: ref at runtime (Layer B)", "status": "completed", "classification": "high-risk", "slice": 2, "blockedBy": [3]},
{"id": 10, "subject": "Verification: build, suites, live connection", "status": "completed", "classification": "standard", "slice": 2, "blockedBy": [1, 2, 3, 4, 5, 6, 7, 8, 9]}
],
"lastUpdated": "2026-07-16"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (ScadaBridge adopted G-3/G-4/G-5/G-6, merged to origin/main @ 128f1596 2026-07-16, G-3 live-proven); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -1,20 +1,21 @@
{
"planPath": "docs/plans/2026-07-19-secrets-interactive-cli.md",
"tasks": [
{"id": 1, "subject": "Task 1: Package + project wiring", "status": "pending"},
{"id": 2, "subject": "Task 2: RecentTargetsStore", "status": "pending", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: TargetConfigReader + StoreTarget", "status": "pending", "blockedBy": [1]},
{"id": 4, "subject": "Task 4: SecretsSession + SecretsSessionFactory + LiteralMasterKeyProvider", "status": "pending", "blockedBy": [2, 3]},
{"id": 5, "subject": "Task 5: ReferenceAuditor", "status": "pending", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: KekDoctor", "status": "pending", "blockedBy": [4]},
{"id": 7, "subject": "Task 7: SecretBundle export/import", "status": "pending", "blockedBy": [4]},
{"id": 8, "subject": "Task 8: InteractiveShell skeleton + IInteractiveFlow + target picker", "status": "pending", "blockedBy": [4]},
{"id": 9, "subject": "Task 9: CRUD flows (list / set-rotate / reveal / delete)", "status": "pending", "blockedBy": [8]},
{"id": 10, "subject": "Task 10: Reference-audit + seeding flow", "status": "pending", "blockedBy": [5, 8]},
{"id": 11, "subject": "Task 11: KEK-doctor flow", "status": "pending", "blockedBy": [6, 8]},
{"id": 12, "subject": "Task 12: Bundle flows (export / import)", "status": "pending", "blockedBy": [7, 8]},
{"id": 13, "subject": "Task 13: Program.cs entry point + non-TTY pin", "status": "pending", "blockedBy": [9, 10, 11, 12]},
{"id": 14, "subject": "Task 14: Version bump, docs, final green run", "status": "pending", "blockedBy": [13]}
{"id": 1, "subject": "Task 1: Package + project wiring", "status": "completed"},
{"id": 2, "subject": "Task 2: RecentTargetsStore", "status": "completed", "blockedBy": [1]},
{"id": 3, "subject": "Task 3: TargetConfigReader + StoreTarget", "status": "completed", "blockedBy": [1]},
{"id": 4, "subject": "Task 4: SecretsSession + SecretsSessionFactory + LiteralMasterKeyProvider", "status": "completed", "blockedBy": [2, 3]},
{"id": 5, "subject": "Task 5: ReferenceAuditor", "status": "completed", "blockedBy": [4]},
{"id": 6, "subject": "Task 6: KekDoctor", "status": "completed", "blockedBy": [4]},
{"id": 7, "subject": "Task 7: SecretBundle export/import", "status": "completed", "blockedBy": [4]},
{"id": 8, "subject": "Task 8: InteractiveShell skeleton + IInteractiveFlow + target picker", "status": "completed", "blockedBy": [4]},
{"id": 9, "subject": "Task 9: CRUD flows (list / set-rotate / reveal / delete)", "status": "completed", "blockedBy": [8]},
{"id": 10, "subject": "Task 10: Reference-audit + seeding flow", "status": "completed", "blockedBy": [5, 8]},
{"id": 11, "subject": "Task 11: KEK-doctor flow", "status": "completed", "blockedBy": [6, 8]},
{"id": 12, "subject": "Task 12: Bundle flows (export / import)", "status": "completed", "blockedBy": [7, 8]},
{"id": 13, "subject": "Task 13: Program.cs entry point + non-TTY pin", "status": "completed", "blockedBy": [9, 10, 11, 12]},
{"id": 14, "subject": "Task 14: Version bump, docs, final green run", "status": "completed", "blockedBy": [13]}
],
"lastUpdated": "2026-07-19T00:00:00Z"
"sweepNote": "Retro-completed by the 2026-08-07 documentation truth sweep: the program this ledger tracks is recorded as shipped/complete in scadaproj CLAUDE.md (Secrets 0.3.0 interactive operator console shipped, merged to main @ 87ffe1b, 5 pkgs published 2026-07-19); the ledger was never flipped when the work landed.",
"lastUpdated": "2026-08-07T00:00:00Z"
}
@@ -4,8 +4,13 @@
**Status:** **Phase 1 EXECUTED, merged + pushed** to OtOpcUa `master` 2026-07-21 (merge `c957db52`;
live gate 8/8, `OtOpcUa/docs/plans/2026-07-20-localdb-phase1-live-gate.md`). Both limitations that gate
left open were closed the same day (merge `5fdb5a5a`, `…-followups-live-gate.md`), which turned up a
third library defect reachable only once the first was fixed. **Phase 2 is designed but NOT executed** —
plan at `OtOpcUa/docs/plans/2026-07-20-localdb-adoption-phase2.md` (9 tasks).
third library defect reachable only once the first was fixed. **Phase 2 EXECUTED — correction 2026-08-07:**
Phase 2 (alarm store-and-forward on LocalDb) was executed, live-gated and **merged to OtOpcUa `master`**
(merge `06b5d81b`, "Merge feat/localdb-phase2: alarm store-and-forward on LocalDb + live-gate fixes";
source: `src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/AlarmSfSchema.cs` + `LocalDbStoreAndForwardSink.cs`).
The "designed but NOT executed" claim that previously stood here was stale. Residual: live-gate checks 3+4
were never re-run on the post-mesh-Phase-6 topology.
Plan at `OtOpcUa/docs/plans/2026-07-20-localdb-adoption-phase2.md` (9 tasks).
Implementation plans live in the OtOpcUa repo at
`docs/plans/2026-07-20-localdb-adoption-phase1.md` and `…-phase2.md`.
**Library:** `ZB.MOM.WW.LocalDb` / `.Replication` / `.Contracts` — designed against **0.1.1**; Phase 1
@@ -2,7 +2,8 @@
"planPath": "docs/plans/2026-07-22-initjoin-selfform-fallback.md",
"note": "SPLIT 2026-07-22: executable tasks moved to the per-repo plans — ScadaBridge/docs/plans/2026-07-22-selfform-fallback-and-manual-failover.md (10 tasks) and OtOpcUa/docs/plans/2026-07-22-selfform-fallback-and-manual-failover.md (7 tasks + reserved additions). Only C1 executes from this file, after BOTH repo plans complete and merge.",
"tasks": [
{"id": 0, "subject": "Task C1: Flip akka_failover.md §6.1 status + CLAUDE.md index + memory (after both repo plans merge)", "status": "pending"}
{"id": 0, "subject": "Task C1: Flip akka_failover.md §6.1 status + CLAUDE.md index + memory (after both repo plans merge)", "status": "completed"}
],
"lastUpdated": "2026-07-22T00:00:00Z"
"sweepNote": "Task C1 verified complete 2026-08-07: akka_failover.md §6.1 status reads 'CLOSED 2026-07-22 (self-form watchdog REJECTED; self-first ordering + opt-in bootstrap guard shipped in both repos)', and the CLAUDE.md index carries the corrected record via commit 6d222ea (2026-08-01, 'docs: correct the self-form watchdog record — rejected, not shipped'). The memory half of C1 is not independently verifiable from the repo.",
"lastUpdated": "2026-08-07T00:00:00Z"
}