docs(plans): add v2 implementation plan with 66 bite-sized tasks
Converts the akka-hosting-alignment design into an executable plan: 12 phases covering branch/scaffold, ConfigDb schema, Commons, Cluster, Security, ControlPlane singletons, Runtime per-node actors, OpcUaServer extraction, AdminUI migration, Host entry point, cleanup, integration tests, deploy scripts, and docs. Each task has files, TDD steps, exact commands, classification, time estimate, and parallelizable list. Co-located .tasks.json drives executing-plans resume from any session.
This commit is contained in:
1944
docs/plans/2026-05-26-akka-hosting-alignment-plan.md
Normal file
1944
docs/plans/2026-05-26-akka-hosting-alignment-plan.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
"planPath": "docs/plans/2026-05-26-akka-hosting-alignment-plan.md",
|
||||||
|
"branch": "v2-akka-fuse",
|
||||||
|
"designDoc": "docs/plans/2026-05-26-akka-hosting-alignment-design.md",
|
||||||
|
"lastUpdated": "2026-05-26T00:00:00Z",
|
||||||
|
"tasks": [
|
||||||
|
{"id": 0, "subject": "Task 0: Create branch and central package management", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": []},
|
||||||
|
{"id": 1, "subject": "Task 1: Create OtOpcUa.Commons project", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [2,3,4,5,6,7,8], "blockedBy": [0]},
|
||||||
|
{"id": 2, "subject": "Task 2: Create OtOpcUa.Cluster project", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,3,4,5,6,7,8], "blockedBy": [0]},
|
||||||
|
{"id": 3, "subject": "Task 3: Create OtOpcUa.Security project", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,4,5,6,7,8], "blockedBy": [0]},
|
||||||
|
{"id": 4, "subject": "Task 4: Create OtOpcUa.ControlPlane project", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,5,6,7,8], "blockedBy": [0]},
|
||||||
|
{"id": 5, "subject": "Task 5: Create OtOpcUa.Runtime project", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,4,6,7,8], "blockedBy": [0]},
|
||||||
|
{"id": 6, "subject": "Task 6: Create OtOpcUa.OpcUaServer project", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,4,5,7,8], "blockedBy": [0]},
|
||||||
|
{"id": 7, "subject": "Task 7: Create OtOpcUa.AdminUI Razor class library", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,4,5,6,8], "blockedBy": [0]},
|
||||||
|
{"id": 8, "subject": "Task 8: Create OtOpcUa.Host Web SDK project", "status": "pending", "classification": "small", "estMinutes": 5, "parallelizableWith": [1,2,3,4,5,6,7], "blockedBy": [0]},
|
||||||
|
{"id": 9, "subject": "Task 9: Build green smoke check", "status": "pending", "classification": "trivial", "estMinutes": 2, "parallelizableWith": [], "blockedBy": [1,2,3,4,5,6,7,8]},
|
||||||
|
{"id": 10, "subject": "Task 10: Add Deployment entity", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [11,12,13], "blockedBy": [9]},
|
||||||
|
{"id": 11, "subject": "Task 11: Add NodeDeploymentState entity", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [10,12,13], "blockedBy": [9]},
|
||||||
|
{"id": 12, "subject": "Task 12: Add ConfigEdit audit entity", "status": "pending", "classification": "small", "estMinutes": 4, "parallelizableWith": [10,11,13], "blockedBy": [9]},
|
||||||
|
{"id": 13, "subject": "Task 13: Add DataProtection keys table", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [10,11,12], "blockedBy": [9]},
|
||||||
|
{"id": 14, "subject": "Task 14: EF migration V2HostingAlignment", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [10,11,12,13]},
|
||||||
|
{"id": 15, "subject": "Task 15: Migrate-To-V2.ps1 idempotent script", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [16,17,18], "blockedBy": [14]},
|
||||||
|
{"id": 16, "subject": "Task 16: Common types (CorrelationId, ExecutionId, NodeId, ...)", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [17,18], "blockedBy": [9]},
|
||||||
|
{"id": 17, "subject": "Task 17: Akka message contracts", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [16,18], "blockedBy": [16]},
|
||||||
|
{"id": 18, "subject": "Task 18: Common interfaces", "status": "pending", "classification": "small", "estMinutes": 4, "parallelizableWith": [16,17], "blockedBy": [16]},
|
||||||
|
{"id": 19, "subject": "Task 19: HOCON config", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [20,21,22], "blockedBy": [2]},
|
||||||
|
{"id": 20, "subject": "Task 20: AkkaHostedService implementation", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [19,21,22], "blockedBy": [2,18]},
|
||||||
|
{"id": 21, "subject": "Task 21: Role parser from OTOPCUA_ROLES env", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [19,20,22], "blockedBy": [2]},
|
||||||
|
{"id": 22, "subject": "Task 22: ClusterRoleInfo implementation", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [19,20,21], "blockedBy": [18,20]},
|
||||||
|
{"id": 23, "subject": "Task 23: Cluster test project + tests", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [19,20,21,22]},
|
||||||
|
{"id": 24, "subject": "Task 24: Move LdapAuthService into OtOpcUa.Security", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [25], "blockedBy": [3]},
|
||||||
|
{"id": 25, "subject": "Task 25: JwtTokenService", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [24], "blockedBy": [3]},
|
||||||
|
{"id": 26, "subject": "Task 26: Cookie+JWT hybrid AddOtOpcUaAuth extension", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [27,28], "blockedBy": [13,24,25]},
|
||||||
|
{"id": 27, "subject": "Task 27: /auth/login, /auth/ping, /auth/token endpoints", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [26,28], "blockedBy": [24,25]},
|
||||||
|
{"id": 28, "subject": "Task 28: CookieAuthenticationStateProvider for Blazor", "status": "pending", "classification": "small", "estMinutes": 4, "parallelizableWith": [26,27], "blockedBy": [25]},
|
||||||
|
{"id": 29, "subject": "Task 29: Security test project + tests", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [24,25,26,27,28]},
|
||||||
|
{"id": 30, "subject": "Task 30: ConfigPublishCoordinator happy path", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [32,33,34,35], "blockedBy": [4,17,18,10,11]},
|
||||||
|
{"id": 31, "subject": "Task 31: Coordinator timeout + failover recovery", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [32,33,34,35], "blockedBy": [30]},
|
||||||
|
{"id": 32, "subject": "Task 32: AdminOperationsActor + StartDeployment", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [30,31,33,34,35], "blockedBy": [4,17,18,10,12]},
|
||||||
|
{"id": 33, "subject": "Task 33: AuditWriterActor batched idempotent insert", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [30,31,32,34,35], "blockedBy": [4,17]},
|
||||||
|
{"id": 34, "subject": "Task 34: FleetStatusBroadcaster", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [30,31,32,33,35], "blockedBy": [4,17]},
|
||||||
|
{"id": 35, "subject": "Task 35: RedundancyStateActor + ServiceLevelCalculator", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [30,31,32,33,34], "blockedBy": [4,17,18]},
|
||||||
|
{"id": 36, "subject": "Task 36: Singleton registration extension (admin role)", "status": "pending", "classification": "standard", "estMinutes": 4, "parallelizableWith": [], "blockedBy": [30,31,32,33,34,35]},
|
||||||
|
{"id": 37, "subject": "Task 37: DriverHostActor scaffolding + PreStart recovery", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [41,42,43,44], "blockedBy": [5,17,18,11]},
|
||||||
|
{"id": 38, "subject": "Task 38: DriverHostActor DispatchDeployment handler", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [41,42,43,44], "blockedBy": [37]},
|
||||||
|
{"id": 39, "subject": "Task 39: DriverHostActor stale-config fallback", "status": "pending", "classification": "standard", "estMinutes": 4, "parallelizableWith": [41,42,43,44], "blockedBy": [38]},
|
||||||
|
{"id": 40, "subject": "Task 40: Runtime test project bootstrap", "status": "pending", "classification": "small", "estMinutes": 3, "parallelizableWith": [], "blockedBy": [37,38,39]},
|
||||||
|
{"id": 41, "subject": "Task 41: DriverInstanceActor state machine", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [42,43,44], "blockedBy": [5,17,40]},
|
||||||
|
{"id": 42, "subject": "Task 42: VirtualTagActor", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [41,43,44], "blockedBy": [5,17,40]},
|
||||||
|
{"id": 43, "subject": "Task 43: ScriptedAlarmActor", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [41,42,44], "blockedBy": [5,17,40]},
|
||||||
|
{"id": 44, "subject": "Task 44: OpcUaPublishActor on synchronized dispatcher", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [41,42,43], "blockedBy": [5,6,17,19,40]},
|
||||||
|
{"id": 45, "subject": "Task 45: HistorianAdapter + PeerOpcUaProbe + DbHealthProbe actors", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [37,40]},
|
||||||
|
{"id": 46, "subject": "Task 46: Extract OpcUaApplicationHost + Phase7Composer", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [6]},
|
||||||
|
{"id": 47, "subject": "Task 47: Phase7Composer purity + property tests", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [48,49,50,51,52], "blockedBy": [46]},
|
||||||
|
{"id": 48, "subject": "Task 48: Move Blazor components into AdminUI library", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [47], "blockedBy": [7]},
|
||||||
|
{"id": 49, "subject": "Task 49: Move SignalR hubs and rewire to FleetStatusBroadcaster", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [50,51,52], "blockedBy": [34,48]},
|
||||||
|
{"id": 50, "subject": "Task 50: IAdminOperationsClient via ClusterSingletonProxy", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [49,51,52], "blockedBy": [18,32,48]},
|
||||||
|
{"id": 51, "subject": "Task 51: Replace DriverDiagnosticsClient with IFleetDiagnosticsClient", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [49,50,52], "blockedBy": [18,48]},
|
||||||
|
{"id": 52, "subject": "Task 52: Drift indicator + Deploy button UI", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [49,50,51], "blockedBy": [50,48]},
|
||||||
|
{"id": 53, "subject": "Task 53: Host Program.cs role-gated startup", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [54,55], "blockedBy": [8,15,20,21,22,26,36,40,45,46,48,49]},
|
||||||
|
{"id": 54, "subject": "Task 54: Health endpoints + appsettings layout", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [53,55], "blockedBy": [8,22]},
|
||||||
|
{"id": 55, "subject": "Task 55: Mac dev mode + DEV-STUB drivers", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [53,54], "blockedBy": [41]},
|
||||||
|
{"id": 56, "subject": "Task 56: Delete OtOpcUa.Server + OtOpcUa.Admin projects", "status": "pending", "classification": "high-risk", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [53,54,55]},
|
||||||
|
{"id": 57, "subject": "Task 57: Build & test green check", "status": "pending", "classification": "trivial", "estMinutes": 3, "parallelizableWith": [], "blockedBy": [56]},
|
||||||
|
{"id": 58, "subject": "Task 58: 2-node integration test harness", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [57]},
|
||||||
|
{"id": 59, "subject": "Task 59: Deploy + failover integration tests", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [60], "blockedBy": [58]},
|
||||||
|
{"id": 60, "subject": "Task 60: OPC UA dual-endpoint + ServiceLevel tests", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [59], "blockedBy": [58]},
|
||||||
|
{"id": 61, "subject": "Task 61: E2E test infrastructure + GitHub Actions CI", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [], "blockedBy": [59,60]},
|
||||||
|
{"id": 62, "subject": "Task 62: Rewrite Install-Services.ps1", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [63,64,65], "blockedBy": [53]},
|
||||||
|
{"id": 63, "subject": "Task 63: Traefik config + docker-dev compose", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [62,64,65], "blockedBy": [53]},
|
||||||
|
{"id": 64, "subject": "Task 64: Update existing docs (Redundancy, ServiceHosting, security)", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [62,63,65], "blockedBy": [57]},
|
||||||
|
{"id": 65, "subject": "Task 65: New v2 docs (Architecture-v2, Cluster, ControlPlane, Runtime)", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [62,63,64], "blockedBy": [57]}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user