Files
ScadaBridge/archreview/plans/00-MASTER-TRACKER.md
T
Joseph Doherty dbd3ed2fc7 docs(archreview): sync PLAN-04 tasks.json + tracker — Task 26 sweep GREEN, plan COMPLETE (26/26)
Full-solution build 0 warn/0 err; all 30 unit+integration test assemblies pass
after fixing one stale enum-count lock-in test (22d52390). Playwright E2E residue
is environmental (stale docker cluster, SQLite-open on site-container deploy;
non-deterministic set; zero PLAN-04 file overlap). Initiative total 104/192.

Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
2026-07-09 14:59:20 -04:00

148 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Architecture Review Fix Plans — Master Tracker
**Created:** 2026-07-08
**Source:** [`archreview/00-OVERALL.md`](../00-OVERALL.md) and domain reports 0108
**Plans:** 8 implementation plans, **192 tasks** (191 net of one cross-plan duplicate — see Dedupe Rulings)
Every plan follows the TDD bite-sized-task format and ships a co-located `.tasks.json` manifest. Execute a plan with the `superpowers-extended-cc:executing-plans` skill (pass the plan path); it reads/updates the `.tasks.json`. **When a plan's status changes, update the table below** — this file is the single source of truth for initiative progress.
## Status Board
| Plan | Domain | Tasks | Done | Status | Findings coverage |
|------|--------|------:|-----:|--------|-------------------|
| [PLAN-01](PLAN-01-cluster-host-failover.md) | Cluster, Host & Failover | 23 | 23 | ✅ Complete (all 23 tasks; merged to `main` `ec47cb56`) | 28 findings: 20 fixed, 3 → other plans, 3 accepted, 2 roadmap-deferred |
| [PLAN-02](PLAN-02-communication-store-and-forward.md) | Communication & S&F | 24 | 24 | ✅ Complete (all 24 tasks; merged to `main`) | 28 findings: 25 fixed, 1 → plan 01, 1 deferred (serializer swap), 1 won't-fix |
| [PLAN-03](PLAN-03-site-runtime-dcl.md) | Site Runtime & DCL | 26 | 26 | ✅ Complete (all 26 tasks; merged to `main` `c7a0c922`) | 28 actionable: 25 fixed, 3 deferred with rationale |
| [PLAN-04](PLAN-04-data-audit-backbone.md) | Data & Audit Backbone | 26 | 26 | ✅ Complete (T26 sweep green; on branch `worktree-archreview-wave2-plan04` — Batches 13 merged to `main`, Batches 48 + T24 + T26 fix unmerged, pending finishing-a-development-branch) | 27 items: 22 fixed, 4 deferred, 1 won't-fix (incl. NodeB reconcile from report 08) |
| [PLAN-05](PLAN-05-templates-deployment-transport.md) | Templates, Deployment & Transport | 25 | 1 | 🟨 In progress (P0: T1) | 33 line-items: 27 fixed, 6 deferred with rationale |
| [PLAN-06](PLAN-06-edge-integrations.md) | Edge Integrations | 24 | 0 | ⬜ Not started | 24 findings: 21 fixed, 3 deferred/won't-fix |
| [PLAN-07](PLAN-07-ui-management-security.md) | UI, Management & Security | 33 | 3 | 🟨 In progress (P0: T1, T2, T3) | 24 items: 20 fixed, 3 partial (deferrals documented), 1 won't-fix |
| [PLAN-08](PLAN-08-conventions-tests.md) | Conventions & Tests | 11 | 1 | 🟨 In progress (P0: T1) | 13 covered, 4 owned by other plans, ~20 triaged into deferred-work register |
Status values: ⬜ Not started · 🟨 In progress · ✅ Complete · ⏸ Blocked
**Progress:** P0 (Wave 0) complete — **10 of 192 tasks done** (2026-07-08): PLAN-01 T1/T3/T4, PLAN-02 T1/T2, PLAN-05 T1, PLAN-07 T1/T2/T3, PLAN-08 T1. Merged to `main` (`3f8e18c6`). One follow-up surfaced during execution — see the [active-node-crash SBR gap](#follow-up-discovered-during-p0-execution-2026-07-08) in the deferred registry.
**Wave 1 — PLAN-02 COMPLETE (2026-07-08):** all 24 tasks delivered and **merged to `main`** (`ce239f6f`). Store-and-Forward: active-node delivery gate (`Func<bool>` seam), bounded/short-circuiting retry sweep, upsert-based standby applies + anti-entropy peer resync, WAL+busy_timeout, epoch-ms due-check, ordered single-reader audit-observer channel; `Notify.Send` enqueue-only (`deferToSweep`, `maxRetries:0`, corrupt-payload parks not discards); gRPC channel keying + DropOldest debug-stream eviction counting + 5s application heartbeat; oldest-parked-age health field. Docker cluster rebuilt on merged image (Healthy, 5 singletons, corrected active-node semantics) and 3 sites seeded. Initiative total: **52 of 192** (sum of the Done column above).
**Wave 1 — PLAN-01 COMPLETE (2026-07-08):** all 23 tasks delivered on worktree branch `worktree-archreview-wave1-plan01` (**merged to `main` `ec47cb56` 2026-07-09; branch since removed**). Beyond the P0/early-Wave-1 spine (SBR downing + two-node rig T1/T3/T4; oldest-member active-node unification via `ClusterActivityEvaluator` T5T8; `CentralSingletonRegistrar` drains T2/T9/T10; health-report acking T11T12), Wave 1 also landed: metrics-staleness + status-transition state machine and its dashboard surface (T13/T14), deleted-site eviction from the aggregator (T18), seed-vs-metrics-port validator + `AllowSingleNodeCluster` + docker `stop_grace_period` (T15T17), rate-limited dead-letter warnings (T19), the down-if-alone process-exit recovery loop (T20), the `failover-drill.sh` SIGKILL drill (T21), and the REQ-HOST-6 + Traefik/Host doc reconciliation with unused-Akka.Hosting-package removal (T22/T23). PLAN-01 now **23 / 23**. Initiative total: **30 of 192**. Each task TDD + pathspec-committed; full solution builds clean (0 warnings). Three deploy-artifact sub-edits (`deploy/wonder-app-vd03/` appsettings + install.ps1, Tasks 16/20/23) were deferred because that production artifact is not tracked in this repo — logged in the deferred register below.
**Wave 1 — PLAN-03 COMPLETE (2026-07-09):** all 26 tasks delivered and **merged to `main`** (`c7a0c922`). Site Runtime & DCL hardening across nine TDD batches: reconnect/backoff leak fixes and the `DeployCompileValidator` compile gate, DCL adapter lifecycle + alarm-filter overwrite warning (S10) + observed adapter dispose on stop (S9), site-node cert reconcile (CertStoreActor trusted-store export → `DeploymentManagerActor` MemberUp-driven additive push), replicated config-fetch retry (`ConfigFetchRetryCount`), invariant-culture conditional-trigger fallback (C6), bounded/DropOldest event-channel comment fix (C2), and the SiteRuntime/DCL requirements-doc sync. Three low-severity items deferred with rationale (see PLAN-03 coverage table). Full CentralUI/SiteRuntime/DCL suites green. Initiative total: **78 of 192** (sum of the Done column above). Two out-of-band fixes also landed post-merge: PLAN-07's SecuredWrites `IBrowseService` bUnit-harness gap (resolved 2026-07-09, `9049690b`) — a pre-existing failure surfaced during PLAN-03's full-suite run, not a plan task.
**Wave 2 — PLAN-04 COMPLETE (2026-07-09):** all 26 tasks delivered on worktree branch `worktree-archreview-wave2-plan04` (Batches 13 fast-forwarded to `main`+`origin`; Batches 48 + T24 + the T26 fix still on the branch, pending `finishing-a-development-branch`). Site SQLite retention chain + partition-switch hardening + purger role-grants/index migrations (T1T9), backlog KPI + SiteCalls freshness upsert + EF `EnableRetryOnFailure` (T10T12), operator-identity audit on Retry/Discard relays + reconciliation composite-keyset cursor/abandoned-row audit/NodeB failover (T13T18), time-sliced KpiSample purge + single-query NotificationOutbox KPI + SiteCalls `OPTION (RECOMPILE)` (T19T21), short-first-tick purge timers + data-layer cleanups + bounded parallel notification delivery (T22, T23, T25), the design-doc reconciliation pass (T24). **T26 (final `dotnet build`/`dotnet test` sweep):** build 0 warn/0 err; all 30 unit + integration test assemblies green after fixing one stale enum-count lock-in test (`22d52390` — Task 17 added `AuditKind.ReconciliationAbandoned` but left `AuditEnumTests` asserting 14 members; the per-task filtered runs never hit that Commons guard, so the full sweep caught it). The Playwright E2E residue (89 fails) is environmental — a 17h-old docker cluster whose site containers fail `instance deploy` with `SQLite Error 14: unable to open database file`; the failure set is non-deterministic and PLAN-04 changed zero files in that project or the deployment-DB path. Initiative total: **104 of 192** (sum of the Done column).
## Parallelization Map — Incomplete Tasks (2026-07-09)
Covers the plans with open tasks: PLAN-05 (24), PLAN-06 (24), PLAN-07 (30), PLAN-08 (10). PLAN-01/02/03/04 are complete — nothing to parallelize there (PLAN-04 finished 2026-07-09; the section below is retained for its cross-plan mutex analysis, which still governs PLAN-0508). **"Ready"** = every `blockedBy` entry is already `completed` in the plan's `.tasks.json`, so the task can start now. Ready sets are recomputed below from the live manifests; re-derive after each merge.
### Cross-plan serialization mutexes (a task holding one must be the ONLY task touching that surface, anywhere)
| Shared surface | Tasks that touch it (P0n = PLAN-0n) | Rule |
|---|---|---|
| `ManagementService/ManagementActor.cs` | P05 T13; P06 T2, T3, T11, T20, T22; P07 T5, T7, T8, T9, T10, T11, T12, T15, T16, T17, T22, T23, T28, T30, T31 | **Global single-writer.** At most one ManagementActor task in flight across ALL plans. PLAN-07 already serializes its 15 internally — extend the same mutex to P05 T13 and the five P06 tasks. |
| EF migration model-snapshot (`ConfigurationDatabase/Migrations/*` + `*ModelSnapshot`) | P06 T8 (ready), T19 | **Never two migration tasks concurrently.** Build first, never `--no-build` (empty-scaffold gotcha). Only P06 T8 is ready now. |
| `Host/Program.cs` | P06 T7; P08 T4 | Single-writer — don't run P06 T7 and P08 T4 at the same time. |
| `DeploymentManager/ArtifactDeploymentService.cs` | P06 T10; P07 T4 | Single-writer (P06 T10 not yet ready; P07 T4 is). |
| `SiteRuntime/Persistence/SiteStorageService.cs` | P06 T10; P08 T6 | Single-writer (neither ready yet). |
| `NotificationOutbox/NotificationOutboxActor.cs` | P06 T18, T21 | Intra-PLAN-06 (PLAN-04's delivery work is done and no longer touches it). |
| `CentralUI/.../Monitoring/AlarmSummary.razor` | P07 T29, T32 | Intra-PLAN-07 — serialize. |
| Docs (low-risk, coordinate — pathspec-commit + last-writer reconcile): `CLAUDE.md` (P05 T25, P06 T18, P07 T15/T31/T33, P08 T10), `Component-ManagementService.md`, `Component-InboundAPI.md`, `Component-ExternalSystemGateway.md`, `Component-NotificationService.md` | multiple | Not a hard blocker; do not co-edit the same file in the same wall-clock window. |
**Dedupe reminder:** **P07 T33 is a skip** — CLI.Tests is already in the slnx via P08 T1 (done). Mark it `skipped-duplicate` in `PLAN-07-…tasks.json`; do not execute it.
### Ready set + concurrent lanes per plan
- **PLAN-04** — ✅ COMPLETE (2026-07-09); all 26 tasks done, T26 sweep green. Pending only `finishing-a-development-branch` (merge Batches 48 + T24 + T26 fix). No longer a parallelization lane.
- **PLAN-05** — ready: **{2, 7, 9, 13, 14, 15, 16, 21, 22}**. Lanes: *(a)* `BundleImporter.cs` mutex — **T2 ↔ T14** (one at a time); *(b)* global ManagementActor lane — **T13** (also edits `FlatteningService.cs`, so not concurrent with T9); *(c)* free-concurrent, file-disjoint — **T7, T9, T15, T16, T21, T22** (Export / FlatteningService / TemplateEngine-Validation / DeploymentManager-pipeline / ScriptAnalysis / LineDiffer). Up to ~6 concurrent implementers once the two mutex lanes are accounted for.
- **PLAN-06** — ready: **{1, 6, 7, 8, 17, 23}**. Lanes: **T8** is the sole migration in flight; **T7** holds the `Host/Program.cs` mutex (coordinate with P08 T4); **T1, T6, T17, T23** are free-concurrent (InboundScriptExecutor / InboundApiEndpointFilter / SmsAdapter / DelmiaNotifier docs). The ExternalSystem (T9→…), Notification (T18/T19→…) and inbound-contract (T2→T3→T4→T5) chains stay blocked.
- **PLAN-07** — ready non-ManagementActor (mutually concurrent, file-disjoint): **{4, 6, 14, 19, 21, 26, 29 | 32}** (ArtifactDeploymentService / ConfigSecretScrubber / SecuredWriteRepository / ManagementEndpoints+options / Commons Browse-Cert message records / Security LoginThrottle / CentralUI PollGate — T29 and T32 share `AlarmSummary.razor`, so serialize those two). Ready **ManagementActor** tasks (→ the ONE global Lane M): **{8, 9, 10, 12, 28, 30, 31}** — **start with T10** (it unblocks T11, T13, T22, T23). **T33 = skip (dedupe).**
- **PLAN-08** — ready: **{2, 3, 4, 5, 7, 8, 9, 11}** — each is a new per-component validator file or an isolated test/doc, so **mutually parallel**, with one caveat: **T4 shares `Host/Program.cs` with P06 T7** (sequence them). This is the initiative's single highest-parallelism slice (independent validator files). T6, T10 stay blocked.
### Recommended concurrent execution
Run up to **five plan-lane executor sessions concurrently** (one each for PLAN-04/05/06/07/08 — PLAN-01/02/03 are done), with these coordination rules layered on top:
1. **One ManagementActor task at a time, initiative-wide** — route P05 T13 and every ready P07 ManagementActor task ({8,9,10,12,28,30,31}) through a single serialized "Lane M"; start with **P07 T10**.
2. **One migration at a time** — only **P06 T8** is a ready migration; hold the snapshot until it lands.
3. **`Host/Program.cs` mutex** — **P06 T7 ⟂ P08 T4**.
4. Inside each session, dispatch that plan's ready, file-disjoint tasks as concurrent implementers per the lanes above; use **pathspec-scoped commits and verify each landed on HEAD** (known repo failure mode — see Execution hygiene).
5. Highest-value immediate fan-out: **PLAN-08 T2/T3/T5/T7/T8/T9/T11** (independent validator + test + doc files) and **PLAN-07's non-ManagementActor octet** can run as many concurrent implementers today; the throughput ceiling is Lane M (ManagementActor) and the single migration lane.
## P0 — Do These First (regardless of plan order)
**✅ All six delivered 2026-07-08** on branch `archreview-p0` (worktree). TDD throughout; full solution builds clean; touched suites green (Host, Communication 244, Security 163, Transport 127+63, IntegrationTests cluster rig). One finding surfaced — see the active-node-crash SBR gap in the deferred registry below.
1.**PLAN-01 Task 1** — enable the SBR downing provider (the system-wide Critical; one line + parsed-config test). *Provider verified active via the live two-node rig.*
2.**PLAN-01 Tasks 34** — the two-node kill-test rig (`TwoNodeClusterFixture`); integration-proves Task 1 and later PLAN-02 work. *Task 4 rewritten to the achievable keep-oldest guarantee (younger-crash → SBR downs it → oldest keeps singleton); oldest-crash gap registered as follow-up.*
3.**PLAN-07 Tasks 13**`DisableLoginGuard` + scrub `deploy/wonder-app-vd03` (Critical; unauthenticated prod surface). *Guard + Host wiring committed; `deploy/` is gitignored so its scrub is on-disk-only (not version-controlled), effective on next redeploy.*
4.**PLAN-02 Tasks 12** — ClusterClient generation-suffixed names (Critical crash-loop dropping routing to all sites).
5.**PLAN-05 Task 1** — bundle import consumes `BaseTemplateName` (Critical silent data loss).
6.**PLAN-08 Task 1** — CLI.Tests into the slnx (protects every subsequent plan's test runs). *341 CLI tests now run at the solution level.*
## Cross-Plan Dependency Map
**Hard-ish sequencing (execute earlier):**
- **PLAN-01 Tasks 57 → PLAN-02 Tasks 34.** PLAN-02's standby S&F delivery gate is a `Func<bool>` seam with marked swap points; it works standalone but its final wiring consumes PLAN-01's `ClusterActivityEvaluator` / `SelfIsPrimary` (singleton-host semantics).
- **PLAN-01 Tasks 34 → PLAN-02 integration proof.** The two-node rig is how PLAN-02's Critical fixes get integration-verified.
- **PLAN-04 Task 13 (additive `RequestedBy` message change) before any PLAN-07 sender refactors** touching the same messages.
**Soft seams (either order works, coordinate):**
- **PLAN-05 Task 14 (`IScriptArtifactChangeBus`) ↔ PLAN-06 Task 3 (`InboundScriptExecutor.InvalidateMethod`).** PLAN-06 Task 1's per-request revision check is the designed correctness fallback, so there is no hard sequencing; when both land, wire the bus to the invalidate seam.
- **PLAN-03's `DeployCompileValidator` should adopt PLAN-05's compile-cache abstraction** once it exists (later refactor, not a blocker).
- **PLAN-03 Task 8's stuck-thread watchdog pattern is reusable by PLAN-06 Task 4** (inbound orphan counter).
**EF Core migrations — serialize globally.** Migration-adding tasks exist in PLAN-04 (Tasks 6, 8), PLAN-06 (Tasks 8, 19), and possibly PLAN-07 (secured-write expiry). All share one model snapshot: **never run two migration tasks concurrently**, and always build first (never `--no-build` on `dotnet ef migrations add` — known empty-scaffold gotcha).
**Shared-file merge surfaces (don't run these plans' overlapping tasks concurrently):**
| File / area | Plans touching it |
|---|---|
| `ManagementActor.cs` | PLAN-07 (15 tasks, serialized within plan), PLAN-05 (management-path publish), PLAN-06 (method-update paths) |
| `deploy/wonder-app-vd03/appsettings.Central.json` | PLAN-07 (auth), PLAN-01 (Cluster/Node sections) |
| `NotificationOutboxActor.cs` | PLAN-04, PLAN-06 (SMS retry policy) |
| `StoreAndForwardService.cs` / site tracking store | PLAN-02 (primary owner), PLAN-04 Task 15 (keyset query) |
| `Host/Program.cs` + service registration | PLAN-01, PLAN-08 (options validation) |
| `SiteHealthReport` (Commons record, additive fields) | PLAN-03 Task 6, PLAN-04 health-event fields |
| Transport `BundleImporter.cs` | PLAN-05 (primary, serialized chain), PLAN-07 (import idempotency note) |
## Dedupe Rulings (one owner per finding)
| Finding | Owner | Others must skip |
|---|---|---|
| CLI.Tests into slnx | **PLAN-08 Task 1** (also retires CLAUDE.md gotcha + memory note) | PLAN-07 Task 33 — **skip as duplicate**; mark `skipped-duplicate` in its tasks.json |
| `DisableLogin: true` artifact | **PLAN-07 Tasks 13** | PLAN-01 references only |
| AuditLog reconciliation NodeB failover | **PLAN-04 Task 18** | PLAN-08 pointer only |
| `SmsConfiguration.MaxRetryCount` unused | **PLAN-06 Task 18** | PLAN-08 pointer only |
| Transport `AreaName: null` | **PLAN-05 Task 7** | PLAN-08 pointer only |
| Role-casing normalization | **PLAN-07 Task 10 chain** | PLAN-08 pointer only |
| Two-node failover rig | **PLAN-01 Tasks 34** | PLAN-08 Task 8 is a documented placeholder; PLAN-02 consumes |
| Script-artifact invalidation contract | **PLAN-05 Task 14** (design + publisher) | PLAN-06 implements the inbound consumer |
## Recommended Execution Waves
- **Wave 0 (P0 list above).** Independent files; all six items can run in parallel. ~1 focused session.
- **Wave 1 — stability spine.** Rest of PLAN-01 (active-node semantics, drains); PLAN-02 Tasks 39 (standby gate, gRPC channel keying, sweep bounding); PLAN-03 Tasks 14 (reconnect leak, compile gate); PLAN-04 Tasks 15 (purge chains); PLAN-05 import chain Tasks 26; PLAN-06 Tasks 14 + 8; PLAN-07 Tasks 49 (deploy scoping, secret elision).
- **Wave 2 — remainder.** All other tasks per intra-plan `blockedBy` edges; migration tasks serialized globally; docs-update tasks land with their code tasks (repo rule: doc + code + tests together).
- **Wave 3 — closeout.** PLAN-08 Task 11 (deferred-work register), each plan's doc-sweep task, then a full `dotnet build ZB.MOM.WW.ScadaBridge.slnx` + `dotnet test` (which now includes CLI.Tests) + `bash docker/deploy.sh` + the two-node drill from PLAN-01.
**Execution hygiene:** work in a dedicated worktree (not the primary checkout); one plan per executor session where possible; for parallel implementers use pathspec-scoped commits and verify every commit landed on HEAD afterward (both are known failure modes in this repo's history). Re-verify a finding's line numbers before editing — reports and plans cite the code as of 2026-07-08.
## Deferred / Won't-Fix Registry (initiative-level)
Consolidated in **PLAN-08 Task 11**`docs/plans/2026-07-08-deferred-work-register.md` (triages the 23-item inventory from report 08 plus each plan's coverage-table deferrals: serializer swap, hash-chain/Parquet, aggregated live alarm stream, central cert-trust persistence, runtime script sandbox, clustered-GUID benchmark, TLS profile, Dockerfile HEALTHCHECK, etc.). Nothing from the review is silently dropped: every report finding is either a task, an ownership pointer, or a registered deferral with rationale.
### Follow-up discovered during P0 execution (2026-07-08)
- **Active(oldest)-node hard crash is NOT covered by two-node `keep-oldest` — total central outage until restart.** PLAN-01 Task 1's `downing-provider-class` fix is verified active (a hard-crashed node now transitions `Unreachable → Down → Removed`, impossible under the pre-fix NoDowning default). **But** while building PLAN-01 Task 4's behavioral proof, the live two-node rig showed (Akka 1.5.62) that `keep-oldest` downs the partition *without* the oldest: crashing the **younger** node is survivable (oldest keeps its singletons), but crashing the **oldest** node makes the younger survivor **down itself** (`Down` ~8s, terminated ~10s) → the whole central cluster is lost until the crashed node restarts. `down-if-alone = on` does not help on a hard crash (the alone-oldest is dead and cannot down itself). Because ScadaBridge treats **oldest = active node** (PLAN-01 Task 5 `ClusterActivityEvaluator`), this means a crash of the *active* central node does not fail over to the standby — the scenario operators care most about. Task 4's test was rewritten to prove the achievable guarantee (younger-crash → SBR downs it → oldest keeps singleton) and documents this asymmetry in its XML doc. **Remedy is a topology/strategy decision (deferred, owner: user):** e.g. `keep-majority` + a 3rd/lighthouse seed node, `static-quorum`, or an explicit accepted-risk note. Not fixed in P0 to avoid silently changing the production SBR strategy.
### Deferred during Wave 1 PLAN-01 execution (2026-07-08)
- **`deploy/wonder-app-vd03/` overlay edits not applied — that production deploy artifact is not tracked in this repo.** PLAN-01 Tasks 16, 20, and 23 each specified a small edit to the on-host deployment overlay (`appsettings.Central.json`: add `AllowSingleNodeCluster: true` + drop the phantom seed, add `NodeName: central-a`; `install.ps1`: add `sc.exe failure` service-recovery actions for the down-if-alone restart contract). Only the *deployment-record* doc (`docs/deployment/deployment-records/2026-06-27-wonder-app-vd03.md`) is version-controlled; the `deploy/wonder-app-vd03/` artifact directory itself is not present in the repo (production config kept out of source control). The **code/validator/doc** halves of all three tasks shipped and are what make the features usable (`AllowSingleNodeCluster` flag + validator, the `IHostApplicationLifetime` process-exit watchdog, the oldest-member Traefik/Host doc reconciliation + TLS roadmap note). **Owner: whoever maintains the on-host artifact** — apply the three overlay edits out-of-band on `wonder-app-vd03` (see the referenced task steps); without `NodeName` every audit row from that deployment stamps a NULL `SourceNode`, and without the service-recovery actions a self-downed node will not auto-restart.
### Plan deviations during Wave 1 PLAN-03 execution (2026-07-09)
- **Task 15 (S6) — deploy-success reporting redesigned: readiness handshake, not swallow-only.** The plan's Task 15 relied on the `Terminated` signal beating the persistence result, so a stale persistence `Success` could simply be swallowed once the init-failure path had already replied `Failed`. **In practice the store commits FIRST** (the optimistic `StoreDeployedConfigAsync` completes before the child's async `PreStart` throws), so the swallow-only guard still reported `Success` for an actor that then died — the exact S6 bug. Fix as shipped makes the join deterministic: `InstanceActor.PreStart` now sends a new `InstanceActorInitialized` readiness message to the DeploymentManager as its final init step, and deployment `Success` requires **both** the persistence commit **and** that signal (`InFlightDeploy.Persisted && Initialized`); an actor that dies during init never signals readiness, so the `Terminated` fallback fails the deployment and rolls back the optimistic state. A second, related bug was fixed at the same time: the optimistic `Store…` and the rollback `Remove…` were independent `Task.Run`s with no ordering guarantee, so the persisted-row rollback is now **deferred until the store commits** (`_initFailedPendingRowRemoval`) and can never race ahead of it. New public surface: `Messages/InstanceActorInitialized.cs` (additive). **Follow-up owner: PLAN-03 Task 26** — the design-doc updates must describe the two-signal deploy-success join + the readiness message (alongside Task 4's already-flagged synchronous-compile-gate deviation). No further code work outstanding; this is a doc-capture follow-up.
### Pre-existing failure discovered during Wave 1 PLAN-03 execution — owner PLAN-07 (2026-07-09)
- **✅ RESOLVED 2026-07-09 — 3 `CentralUI.Tests / SecuredWritesTests` render tests fixed by registering a stub `IBrowseService` in the bUnit harness; suite now 7/7 green. Original report retained below for history.** ~~`IBrowseService` not registered in the page's bUnit harness (PLAN-07 / Secured Writes, NOT PLAN-03).~~ PLAN-03's final full-solution `dotnet test` surfaced 3 failures in `SecuredWritesTests` (`Operator_SeesSubmitForm`, `Operator_Submit_CallsServiceWithEnteredValues`, `Verifier_OwnSubmission_HasApproveAndRejectDisabled`), all `InvalidOperationException: Cannot provide a value for property 'BrowseService' on type 'NodeBrowserDialog' — no registered service of type 'IBrowseService'`. Root cause: the Secured Writes page (`Components/Pages/Operations/SecuredWrites.razor`) renders `Components/Dialogs/NodeBrowserDialog.razor`, which `@inject`s `IBrowseService`; the test fixture (`SecuredWritesTests`) registers `_service`/`_siteRepo`/`_dialog`/auth but **not** a fake `IBrowseService`, so rendering the child dialog throws. **Confirmed pre-existing and out of PLAN-03 scope** — the failing files were last touched by commits outside the PLAN-03 session (`1a7e7351` page/test, `9cff87fe` dialog), and PLAN-03 never touches Secured Writes / CentralUI. Merged to `main` (`c7a0c922`) with this red present because it is not a regression from this branch. **Owner: PLAN-07** — register a stub `IBrowseService` in the `SecuredWritesTests` `Services` collection before `RenderPage()` (or in the shared bUnit fixture). See PLAN-07 "Post-plan known issues".