diff --git a/archreview/plans/00-MASTER-TRACKER.md b/archreview/plans/00-MASTER-TRACKER.md index 0d507060..6f125065 100644 --- a/archreview/plans/00-MASTER-TRACKER.md +++ b/archreview/plans/00-MASTER-TRACKER.md @@ -10,7 +10,7 @@ Every plan follows the TDD bite-sized-task format and ships a co-located `.tasks | Plan | Domain | Tasks | Done | Status | Findings coverage | |------|--------|------:|-----:|--------|-------------------| -| [PLAN-01](PLAN-01-cluster-host-failover.md) | Cluster, Host & Failover | 23 | 3 | ๐ŸŸจ In progress (P0: T1, T3, T4) | 28 findings: 20 fixed, 3 โ†’ other plans, 3 accepted, 2 roadmap-deferred | +| [PLAN-01](PLAN-01-cluster-host-failover.md) | Cluster, Host & Failover | 23 | 12 | ๐ŸŸจ In progress (P0: T1,T3,T4; Wave 1: T2,T5โ€“T12) | 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 | 2 | ๐ŸŸจ In progress (P0: T1, T2) | 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 | 0 | โฌœ Not started | 28 actionable: 25 fixed, 3 deferred with rationale | | [PLAN-04](PLAN-04-data-audit-backbone.md) | Data & Audit Backbone | 26 | 0 | โฌœ Not started | 27 items: 22 fixed, 4 deferred, 1 won't-fix (incl. NodeB reconcile from report 08) | @@ -23,6 +23,8 @@ Status values: โฌœ Not started ยท ๐ŸŸจ In progress ยท โœ… Complete ยท โธ Blocke **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 in progress โ€” PLAN-01 (2026-07-08):** T2, T5โ€“T12 delivered on worktree branch `worktree-archreview-wave1-plan01` (NOT yet merged/pushed). Active-node semantics unified on oldest-member (`ClusterActivityEvaluator`; T5โ€“T8, incl. partition-safe `/health/active` + graceful-leave divergence proof), all seven central singletons routed through `CentralSingletonRegistrar` with drains (T2, T9, T10), and end-to-end health-report acking (`SiteHealthReportAck`; T11โ€“T12). PLAN-01 now **12 / 23**. Remaining PLAN-01: T13โ€“T23. Initiative total: **19 of 192**. Each task TDD + pathspec-committed; full solution builds clean. + ## 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. diff --git a/archreview/plans/PLAN-01-cluster-host-failover.md.tasks.json b/archreview/plans/PLAN-01-cluster-host-failover.md.tasks.json index ecc86d82..169cc6c3 100644 --- a/archreview/plans/PLAN-01-cluster-host-failover.md.tasks.json +++ b/archreview/plans/PLAN-01-cluster-host-failover.md.tasks.json @@ -1,29 +1,177 @@ { "planPath": "archreview/plans/PLAN-01-cluster-host-failover.md", "tasks": [ - { "id": 1, "subject": "Task 1: Enable the SBR downing provider in BuildHocon", "status": "completed", "blockedBy": [] }, - { "id": 2, "subject": "Task 2: Raise the cluster-leave CoordinatedShutdown phase timeout above the drain budget", "status": "pending", "blockedBy": [1] }, - { "id": 3, "subject": "Task 3: Two-node in-process cluster fixture (the reusable failover rig)", "status": "completed", "blockedBy": [1] }, - { "id": 4, "subject": "Task 4: SBR behavioral proof โ€” DELIVERED as younger-node-crash (SBR downs it, oldest keeps singleton); the planned oldest-crash 'singleton migration' is impossible under 2-node keep-oldest โ€” see master-tracker follow-up", "status": "completed", "blockedBy": [3] }, - { "id": 5, "subject": "Task 5: ClusterActivityEvaluator โ€” single oldest-member \"active node\" definition", "status": "pending", "blockedBy": [] }, - { "id": 6, "subject": "Task 6: Rewire ActiveNodeGate, AkkaClusterNodeProvider and Primary labels onto the evaluator", "status": "pending", "blockedBy": [5] }, - { "id": 7, "subject": "Task 7: Oldest-based /health/active check + require DB reachability for Active", "status": "pending", "blockedBy": [5] }, - { "id": 8, "subject": "Task 8: Divergence proof โ€” restarted first node must NOT become active again", "status": "pending", "blockedBy": [3, 6] }, - { "id": 9, "subject": "Task 9: CentralSingletonRegistrar helper (manager + drain task + proxy)", "status": "pending", "blockedBy": [2] }, - { "id": 10, "subject": "Task 10: Route all seven central singletons through the registrar (adds missing outbox/ingest drains)", "status": "pending", "blockedBy": [9] }, - { "id": 11, "subject": "Task 11: SiteHealthReportAck message + ack semantics in the communication actors", "status": "pending", "blockedBy": [] }, - { "id": 12, "subject": "Task 12: Acked async health-report transport so counter-restore actually fires", "status": "pending", "blockedBy": [11] }, - { "id": 13, "subject": "Task 13: Metrics-staleness signal + status-transition timestamps in the aggregator", "status": "pending", "blockedBy": [] }, - { "id": 14, "subject": "Task 14: Surface metrics-stale + offline-since on the Health dashboard", "status": "pending", "blockedBy": [13] }, - { "id": 15, "subject": "Task 15: Fix the metrics-port seed in appsettings.Site.json + close the validator gap", "status": "pending", "blockedBy": [] }, - { "id": 16, "subject": "Task 16: Single-node installs โ€” explicit AllowSingleNodeCluster instead of phantom seeds", "status": "pending", "blockedBy": [] }, - { "id": 17, "subject": "Task 17: stop_grace_period for all app containers (both topologies)", "status": "pending", "blockedBy": [] }, - { "id": 18, "subject": "Task 18: Evict deleted sites from the health aggregator", "status": "pending", "blockedBy": [13] }, - { "id": 19, "subject": "Task 19: Rate-limit dead-letter warnings", "status": "pending", "blockedBy": [] }, - { "id": 20, "subject": "Task 20: Down-if-alone recovery โ€” exit on unexpected ActorSystem termination + service restart actions", "status": "pending", "blockedBy": [10] }, - { "id": 21, "subject": "Task 21: Docker failover drill script (manual/CI kill test against the real topology)", "status": "pending", "blockedBy": [1, 17] }, - { "id": 22, "subject": "Task 22: Reconcile REQ-HOST-6 (Akka.Hosting) with the hand-rolled bootstrap", "status": "pending", "blockedBy": [1] }, - { "id": 23, "subject": "Task 23: Docs & deploy-config cleanup batch (Traefik doc, NodeName overlays, TLS roadmap note)", "status": "pending", "blockedBy": [7, 16] } + { + "id": 1, + "subject": "Task 1: Enable the SBR downing provider in BuildHocon", + "status": "completed", + "blockedBy": [] + }, + { + "id": 2, + "subject": "Task 2: Raise the cluster-leave CoordinatedShutdown phase timeout above the drain budget", + "status": "completed", + "blockedBy": [ + 1 + ] + }, + { + "id": 3, + "subject": "Task 3: Two-node in-process cluster fixture (the reusable failover rig)", + "status": "completed", + "blockedBy": [ + 1 + ] + }, + { + "id": 4, + "subject": "Task 4: SBR behavioral proof โ€” DELIVERED as younger-node-crash (SBR downs it, oldest keeps singleton); the planned oldest-crash 'singleton migration' is impossible under 2-node keep-oldest โ€” see master-tracker follow-up", + "status": "completed", + "blockedBy": [ + 3 + ] + }, + { + "id": 5, + "subject": "Task 5: ClusterActivityEvaluator โ€” single oldest-member \"active node\" definition", + "status": "completed", + "blockedBy": [] + }, + { + "id": 6, + "subject": "Task 6: Rewire ActiveNodeGate, AkkaClusterNodeProvider and Primary labels onto the evaluator", + "status": "completed", + "blockedBy": [ + 5 + ] + }, + { + "id": 7, + "subject": "Task 7: Oldest-based /health/active check + require DB reachability for Active", + "status": "completed", + "blockedBy": [ + 5 + ] + }, + { + "id": 8, + "subject": "Task 8: Divergence proof โ€” restarted first node must NOT become active again", + "status": "completed", + "blockedBy": [ + 3, + 6 + ] + }, + { + "id": 9, + "subject": "Task 9: CentralSingletonRegistrar helper (manager + drain task + proxy)", + "status": "completed", + "blockedBy": [ + 2 + ] + }, + { + "id": 10, + "subject": "Task 10: Route all seven central singletons through the registrar (adds missing outbox/ingest drains)", + "status": "completed", + "blockedBy": [ + 9 + ] + }, + { + "id": 11, + "subject": "Task 11: SiteHealthReportAck message + ack semantics in the communication actors", + "status": "completed", + "blockedBy": [] + }, + { + "id": 12, + "subject": "Task 12: Acked async health-report transport so counter-restore actually fires", + "status": "completed", + "blockedBy": [ + 11 + ] + }, + { + "id": 13, + "subject": "Task 13: Metrics-staleness signal + status-transition timestamps in the aggregator", + "status": "pending", + "blockedBy": [] + }, + { + "id": 14, + "subject": "Task 14: Surface metrics-stale + offline-since on the Health dashboard", + "status": "pending", + "blockedBy": [ + 13 + ] + }, + { + "id": 15, + "subject": "Task 15: Fix the metrics-port seed in appsettings.Site.json + close the validator gap", + "status": "pending", + "blockedBy": [] + }, + { + "id": 16, + "subject": "Task 16: Single-node installs โ€” explicit AllowSingleNodeCluster instead of phantom seeds", + "status": "pending", + "blockedBy": [] + }, + { + "id": 17, + "subject": "Task 17: stop_grace_period for all app containers (both topologies)", + "status": "pending", + "blockedBy": [] + }, + { + "id": 18, + "subject": "Task 18: Evict deleted sites from the health aggregator", + "status": "pending", + "blockedBy": [ + 13 + ] + }, + { + "id": 19, + "subject": "Task 19: Rate-limit dead-letter warnings", + "status": "pending", + "blockedBy": [] + }, + { + "id": 20, + "subject": "Task 20: Down-if-alone recovery โ€” exit on unexpected ActorSystem termination + service restart actions", + "status": "pending", + "blockedBy": [ + 10 + ] + }, + { + "id": 21, + "subject": "Task 21: Docker failover drill script (manual/CI kill test against the real topology)", + "status": "pending", + "blockedBy": [ + 1, + 17 + ] + }, + { + "id": 22, + "subject": "Task 22: Reconcile REQ-HOST-6 (Akka.Hosting) with the hand-rolled bootstrap", + "status": "pending", + "blockedBy": [ + 1 + ] + }, + { + "id": 23, + "subject": "Task 23: Docs & deploy-config cleanup batch (Traefik doc, NodeName overlays, TLS roadmap note)", + "status": "pending", + "blockedBy": [ + 7, + 16 + ] + } ], "lastUpdated": "2026-07-08" -} +} \ No newline at end of file