docs(plans): split Task 14 into 14a-14f (entity-model rewrite)

The original Task 14 (5-min EF migration that "drops ConfigGeneration") was
under-scoped: the design doc (live-edit model, ~line 208) requires removing
GenerationId from 13 entities (Equipment, DriverInstance, Device, Tag,
PollGroup, Namespace, UnsArea, UnsLine, NodeAcl, Script, VirtualTag,
ScriptedAlarm) and adding RowVersion columns for last-write-wins detection.
That cascades into GenerationApplier / GenerationDiff / GenerationSealedCache
and the legacy Server/Admin CRUD services.

New decomposition (~85 min total, replacing the original 5-min estimate):

  14a  standard   10m  Add RowVersion to live-edit entities
  14b  high-risk  30m  Drop GenerationId FK from those entities
  14c  high-risk  20m  Obsolete GenerationApplier/Diff/SealedCache
  14d  standard   5m   Drop ClusterNode.RedundancyRole
  14e  small      5m   Delete ConfigGeneration + ClusterNodeGenerationState
  14f  high-risk  15m  Consolidator: generate V2HostingAlignment migration

Policy decision (recorded with user): OtOpcUa.Server + OtOpcUa.Admin are
allowed to fail-to-compile between 14b and Task 56 - only the new v2 projects
need to stay green. Task 56 deletes the legacy projects.

Plan markdown: replaces the original Task 14 section with the 6-task
decomposition + a header explaining the rewrite. Task index table at the
bottom of the plan updated.

Tasks JSON: replaces the single Task 14 row with 6 string-id rows
("14a", "14b", ..., "14f"). Task 15 (Migrate-To-V2.ps1) and downstream
consumers re-pointed at "14f".

Verification step in 14f rewritten to use the shared docker host at
10.100.0.35 per CLAUDE.md (Docker is not installed on this Mac dev VM).
This commit is contained in:
Joseph Doherty
2026-05-26 03:55:48 -04:00
parent 8e2c4f2835
commit 990ce343fe
2 changed files with 167 additions and 40 deletions

View File

@@ -4,22 +4,27 @@
"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": 0, "subject": "Task 0: Create branch and central package management", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [], "commit": "2b81147"},
{"id": 1, "subject": "Task 1: Create OtOpcUa.Commons project", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [2,3,4,5,6,7,8], "blockedBy": [0], "commit": "30a2104"},
{"id": 2, "subject": "Task 2: Create OtOpcUa.Cluster project", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,3,4,5,6,7,8], "blockedBy": [0], "commit": "30a2104"},
{"id": 3, "subject": "Task 3: Create OtOpcUa.Security project", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,4,5,6,7,8], "blockedBy": [0], "commit": "30a2104"},
{"id": 4, "subject": "Task 4: Create OtOpcUa.ControlPlane project", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,5,6,7,8], "blockedBy": [0], "commit": "30a2104"},
{"id": 5, "subject": "Task 5: Create OtOpcUa.Runtime project", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,4,6,7,8], "blockedBy": [0], "commit": "30a2104"},
{"id": 6, "subject": "Task 6: Create OtOpcUa.OpcUaServer project", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,4,5,7,8], "blockedBy": [0], "commit": "30a2104"},
{"id": 7, "subject": "Task 7: Create OtOpcUa.AdminUI Razor class library", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [1,2,3,4,5,6,8], "blockedBy": [0], "commit": "30a2104"},
{"id": 8, "subject": "Task 8: Create OtOpcUa.Host Web SDK project", "status": "completed", "classification": "small", "estMinutes": 5, "parallelizableWith": [1,2,3,4,5,6,7], "blockedBy": [0], "commit": "30a2104"},
{"id": 9, "subject": "Task 9: Build green smoke check", "status": "completed", "classification": "trivial", "estMinutes": 2, "parallelizableWith": [], "blockedBy": [1,2,3,4,5,6,7,8], "commit": "30a2104"},
{"id": 10, "subject": "Task 10: Add Deployment entity", "status": "completed", "classification": "standard", "estMinutes": 5, "parallelizableWith": [11,12,13], "blockedBy": [9], "commit": "8e2c4f2"},
{"id": 11, "subject": "Task 11: Add NodeDeploymentState entity", "status": "completed", "classification": "standard", "estMinutes": 5, "parallelizableWith": [10,12,13], "blockedBy": [9], "commit": "8e2c4f2"},
{"id": 12, "subject": "Task 12: Add ConfigEdit audit entity", "status": "completed", "classification": "small", "estMinutes": 4, "parallelizableWith": [10,11,13], "blockedBy": [9], "commit": "8e2c4f2"},
{"id": 13, "subject": "Task 13: Add DataProtection keys table", "status": "completed", "classification": "small", "estMinutes": 3, "parallelizableWith": [10,11,12], "blockedBy": [9], "commit": "8e2c4f2"},
{"id": "14a", "subject": "Task 14a: Add RowVersion to live-edit entities", "status": "pending", "classification": "standard", "estMinutes": 10, "parallelizableWith": [], "blockedBy": [13]},
{"id": "14b", "subject": "Task 14b: Decouple live-edit entities from ConfigGeneration", "status": "pending", "classification": "high-risk", "estMinutes": 30, "parallelizableWith": [], "blockedBy": ["14a"]},
{"id": "14c", "subject": "Task 14c: Obsolete GenerationApplier/Diff/SealedCache", "status": "pending", "classification": "high-risk", "estMinutes": 20, "parallelizableWith": [], "blockedBy": ["14b"]},
{"id": "14d", "subject": "Task 14d: Drop ClusterNode.RedundancyRole", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": ["14a","14b","14c"], "blockedBy": [13]},
{"id": "14e", "subject": "Task 14e: Delete ConfigGeneration + ClusterNodeGenerationState", "status": "pending", "classification": "small", "estMinutes": 5, "parallelizableWith": [], "blockedBy": ["14b","14c"]},
{"id": "14f", "subject": "Task 14f: V2HostingAlignment EF migration (consolidator)", "status": "pending", "classification": "high-risk", "estMinutes": 15, "parallelizableWith": [], "blockedBy": ["14a","14b","14c","14d","14e"]},
{"id": 15, "subject": "Task 15: Migrate-To-V2.ps1 idempotent script", "status": "pending", "classification": "standard", "estMinutes": 5, "parallelizableWith": [16,17,18], "blockedBy": ["14f"]},
{"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]},