docs: close the plan-bookkeeping drift and state the tier truth (§8.5, §8.6, #522)
Bookkeeping: 13 .tasks.json files closed — the 8 the audit named, plus
mesh-phase4 (Task 9 landed 3a590a0c), the 4th stillpending phase file, and
historian-tcp-transport closed as OBSOLETE (it targets the retired Wonderware
sidecar; there is no Wonderware backend in the tree). Each carries a
closureNote naming the evidence rather than just a status flip.
11 archreview live gates written back from STATUS.md, which had recorded them
passed since 2026-07-13/15 without ever updating the task files: R2-01 #11,
R2-02 #15/#18, R2-05 T15, R2-06 T12, R2-07 T5/T6/T12/T14, R2-11 T22/T24.
R2-03 and R2-10 were deliberately NOT closed. STATUS.md's headline says "every
Round-2 live gate is now GREEN", but its own per-item detail says R2-03 is
"live-blocked on this data-less rig" and R2-10 verified the pipeline with
"breaker-OPEN state not forced". Both now carry an openNote recording the
actual blocker.
The point of the sweep: ~140 phantom pending tasks are gone, so the genuinely
unexecuted 19-task AdminUI follow-ups plan is now the largest open item in
docs/plans/ instead of being buried under work that shipped months ago.
Tier truth: docs/v2/driver-stability.md now states that its tier table is
aspirational — every driver runs Tier A because no factory passes a tier, so
MemoryRecycle and ScheduledRecycleScheduler have never engaged, and the config
parser validates a RecycleIntervalSeconds that does nothing. It also corrects a
staleness the audit missed: the separate-Windows-service hosting it describes
for Tier C no longer exists (Galaxy moved to the mxaccessgw sidecar in PR 7.2,
FOCAS went in-process with its managed wire client). docs/drivers/README.md
already said Tier A for both, so the two no longer contradict.
No runtime change — enabling recycle on two live drivers wants its own live
gate, not a docs-pass side effect. Keep-or-delete tracked as Gitea #522.
This commit is contained in:
@@ -1,18 +1,116 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-06-12-historian-tcp-transport.md",
|
||||
"tasks": [
|
||||
{"id": 0, "nativeTaskId": 296, "subject": "Task 0: Create feature branch", "status": "pending"},
|
||||
{"id": 1, "nativeTaskId": 297, "subject": "Task 1: Add TCP/TLS fields to client options", "status": "pending", "blockedBy": [0]},
|
||||
{"id": 2, "nativeTaskId": 298, "subject": "Task 2: Client TCP connect factory + FrameChannel rename", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 3, "nativeTaskId": 299, "subject": "Task 3: Switch client default ctor to TCP", "status": "pending", "blockedBy": [2]},
|
||||
{"id": 4, "nativeTaskId": 300, "subject": "Task 4: Host config binding (Host/Port/TLS)", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 5, "nativeTaskId": 301, "subject": "Task 5: Sidecar TcpFrameServer", "status": "pending", "blockedBy": [0]},
|
||||
{"id": 6, "nativeTaskId": 302, "subject": "Task 6: Sidecar Program.cs — TCP bootstrap + env", "status": "pending", "blockedBy": [5]},
|
||||
{"id": 7, "nativeTaskId": 303, "subject": "Task 7: Remove dead pipe code + finalize options shape", "status": "pending", "blockedBy": [3, 4, 6]},
|
||||
{"id": 8, "nativeTaskId": 304, "subject": "Task 8: Deploy scripts — env block + firewall + cert", "status": "pending", "blockedBy": [7]},
|
||||
{"id": 9, "nativeTaskId": 305, "subject": "Task 9: AdminUI Test-Connect probe to host/port/TLS", "status": "pending", "blockedBy": [7]},
|
||||
{"id": 10, "nativeTaskId": 306, "subject": "Task 10: Docs — TCP transport", "status": "pending", "blockedBy": [7]},
|
||||
{"id": 11, "nativeTaskId": 307, "subject": "Task 11: Verification (build + test + live)", "status": "pending", "blockedBy": [8, 9, 10]}
|
||||
{
|
||||
"id": 0,
|
||||
"nativeTaskId": 296,
|
||||
"subject": "Task 0: Create feature branch",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"nativeTaskId": 297,
|
||||
"subject": "Task 1: Add TCP/TLS fields to client options",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"nativeTaskId": 298,
|
||||
"subject": "Task 2: Client TCP connect factory + FrameChannel rename",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"nativeTaskId": 299,
|
||||
"subject": "Task 3: Switch client default ctor to TCP",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"nativeTaskId": 300,
|
||||
"subject": "Task 4: Host config binding (Host/Port/TLS)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"nativeTaskId": 301,
|
||||
"subject": "Task 5: Sidecar TcpFrameServer",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"nativeTaskId": 302,
|
||||
"subject": "Task 6: Sidecar Program.cs \u2014 TCP bootstrap + env",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"nativeTaskId": 303,
|
||||
"subject": "Task 7: Remove dead pipe code + finalize options shape",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
3,
|
||||
4,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"nativeTaskId": 304,
|
||||
"subject": "Task 8: Deploy scripts \u2014 env block + firewall + cert",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"nativeTaskId": 305,
|
||||
"subject": "Task 9: AdminUI Test-Connect probe to host/port/TLS",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"nativeTaskId": 306,
|
||||
"subject": "Task 10: Docs \u2014 TCP transport",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"nativeTaskId": 307,
|
||||
"subject": "Task 11: Verification (build + test + live)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
8,
|
||||
9,
|
||||
10
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-06-12"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "OBSOLETE \u2014 targets the bespoke Wonderware TCP/ArchestrA historian sidecar, retired when HistorianGateway became the sole historian backend. There is no Wonderware backend in the tree. Closed as obsolete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -1,18 +1,111 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-06-15-stillpending-phase-0-1.md",
|
||||
"tasks": [
|
||||
{"id": 402, "subject": "SP Task 0: Feature branch feat/stillpending-phase-0-1", "status": "pending"},
|
||||
{"id": 403, "subject": "SP Task 1: Phase 0 — correct 7 stale code comments", "status": "pending", "blockedBy": [402]},
|
||||
{"id": 404, "subject": "SP Task 2: Phase 0 — fix docs/security.md + benign-residue comments", "status": "pending", "blockedBy": [402]},
|
||||
{"id": 405, "subject": "SP Task 3: Phase 0 — mark shipped .tasks.json completed", "status": "pending", "blockedBy": [402]},
|
||||
{"id": 406, "subject": "SP Task 4: Phase 1 H1a — Phase7Applier rebuilds on Changed*", "status": "pending", "blockedBy": [402]},
|
||||
{"id": 407, "subject": "SP Task 5: Phase 1 H1b — VirtualTagHostActor respawns changed child", "status": "pending", "blockedBy": [402]},
|
||||
{"id": 408, "subject": "SP Task 6: Phase 1 H5a — EquipmentVirtualTagPlan.Historize + composer", "status": "pending", "blockedBy": [402]},
|
||||
{"id": 409, "subject": "SP Task 7: Phase 1 H5b — DeploymentArtifact decodes Historize (byte-parity)", "status": "pending", "blockedBy": [408]},
|
||||
{"id": 410, "subject": "SP Task 8: Phase 1 H5c — VirtualTagHostActor invokes IHistoryWriter", "status": "pending", "blockedBy": [407, 409]},
|
||||
{"id": 411, "subject": "SP Task 9: Phase 1 H5d — thread IHistoryWriter through DriverHostActor + DI", "status": "pending", "blockedBy": [410, 403]},
|
||||
{"id": 412, "subject": "SP Task 10: Phase 1 — docs + follow-up bookkeeping", "status": "pending", "blockedBy": [411]},
|
||||
{"id": 413, "subject": "SP Task 11: Phase 0+1 — full build + test + integration review", "status": "pending", "blockedBy": [403, 404, 405, 406, 407, 408, 409, 410, 411, 412]}
|
||||
{
|
||||
"id": 402,
|
||||
"subject": "SP Task 0: Feature branch feat/stillpending-phase-0-1",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 403,
|
||||
"subject": "SP Task 1: Phase 0 \u2014 correct 7 stale code comments",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
402
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 404,
|
||||
"subject": "SP Task 2: Phase 0 \u2014 fix docs/security.md + benign-residue comments",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
402
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 405,
|
||||
"subject": "SP Task 3: Phase 0 \u2014 mark shipped .tasks.json completed",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
402
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 406,
|
||||
"subject": "SP Task 4: Phase 1 H1a \u2014 Phase7Applier rebuilds on Changed*",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
402
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 407,
|
||||
"subject": "SP Task 5: Phase 1 H1b \u2014 VirtualTagHostActor respawns changed child",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
402
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 408,
|
||||
"subject": "SP Task 6: Phase 1 H5a \u2014 EquipmentVirtualTagPlan.Historize + composer",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
402
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 409,
|
||||
"subject": "SP Task 7: Phase 1 H5b \u2014 DeploymentArtifact decodes Historize (byte-parity)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
408
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 410,
|
||||
"subject": "SP Task 8: Phase 1 H5c \u2014 VirtualTagHostActor invokes IHistoryWriter",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
407,
|
||||
409
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 411,
|
||||
"subject": "SP Task 9: Phase 1 H5d \u2014 thread IHistoryWriter through DriverHostActor + DI",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
410,
|
||||
403
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 412,
|
||||
"subject": "SP Task 10: Phase 1 \u2014 docs + follow-up bookkeeping",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
411
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 413,
|
||||
"subject": "SP Task 11: Phase 0+1 \u2014 full build + test + integration review",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
403,
|
||||
404,
|
||||
405,
|
||||
406,
|
||||
407,
|
||||
408,
|
||||
409,
|
||||
410,
|
||||
411,
|
||||
412
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-06-15"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Shipped \u2014 the stillpending backlog audit cites the landing commits (1e95856b, ada01e1a, fc8121cb, 3e609a2b, 70e6d3d2, c236263e, bd8fee61, 5e27b5f7, fcb38014). Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -2,15 +2,72 @@
|
||||
"planPath": "docs/plans/2026-06-15-stillpending-phase-2-servicelevel.md",
|
||||
"branch": "feat/stillpending-phase-2-servicelevel",
|
||||
"tasks": [
|
||||
{"id": 414, "subject": "P2 Task 1: Move ServiceLevelCalculator to Core.Cluster", "status": "pending"},
|
||||
{"id": 415, "subject": "P2 Task 2a: OpcUaPublishActor calculator path (DB+stale+leader+Detached guard, legacy seam)", "status": "pending", "blockedBy": [414]},
|
||||
{"id": 416, "subject": "P2 Task 2b: OpcUaProbeOk from peer-probes-me (freshness + debounce)", "status": "pending", "blockedBy": [415]},
|
||||
{"id": 417, "subject": "P2 Task 3: HealthTick — periodic DB Ask/PipeTo + PreStart immediate refresh", "status": "pending", "blockedBy": [416]},
|
||||
{"id": 418, "subject": "P2 Task 4: PeerProbeSupervisor — one peer probe per driver peer", "status": "pending"},
|
||||
{"id": 419, "subject": "P2 Task 5: Wire WithOtOpcUaRuntimeActors (dbHealth ref + spawn supervisor)", "status": "pending", "blockedBy": [417, 418]},
|
||||
{"id": 420, "subject": "P2 Task 6: docs/Redundancy.md — calculator is WIRED", "status": "pending"},
|
||||
{"id": 421, "subject": "P2 Task 7: Full build + test + final integration review", "status": "pending", "blockedBy": [419, 420]},
|
||||
{"id": 422, "subject": "P2 Task 8: Live /run on the 2-node rig (acceptance gate)", "status": "pending", "blockedBy": [421]}
|
||||
{
|
||||
"id": 414,
|
||||
"subject": "P2 Task 1: Move ServiceLevelCalculator to Core.Cluster",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 415,
|
||||
"subject": "P2 Task 2a: OpcUaPublishActor calculator path (DB+stale+leader+Detached guard, legacy seam)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
414
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 416,
|
||||
"subject": "P2 Task 2b: OpcUaProbeOk from peer-probes-me (freshness + debounce)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
415
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 417,
|
||||
"subject": "P2 Task 3: HealthTick \u2014 periodic DB Ask/PipeTo + PreStart immediate refresh",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
416
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 418,
|
||||
"subject": "P2 Task 4: PeerProbeSupervisor \u2014 one peer probe per driver peer",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 419,
|
||||
"subject": "P2 Task 5: Wire WithOtOpcUaRuntimeActors (dbHealth ref + spawn supervisor)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
417,
|
||||
418
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 420,
|
||||
"subject": "P2 Task 6: docs/Redundancy.md \u2014 calculator is WIRED",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 421,
|
||||
"subject": "P2 Task 7: Full build + test + final integration review",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
419,
|
||||
420
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 422,
|
||||
"subject": "P2 Task 8: Live /run on the 2-node rig (acceptance gate)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
421
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-06-15"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Shipped \u2014 the stillpending backlog audit cites the landing commits (1e95856b, ada01e1a, fc8121cb, 3e609a2b, 70e6d3d2, c236263e, bd8fee61, 5e27b5f7, fcb38014). Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -2,16 +2,80 @@
|
||||
"planPath": "docs/plans/2026-06-15-stillpending-phase-3-opcua-standards.md",
|
||||
"branch": "feat/stillpending-phase-3-opcua-standards",
|
||||
"tasks": [
|
||||
{"id": 423, "subject": "P3 Task 1: H2-bit — NodePermissions.HistoryUpdate + evaluator mapping", "status": "pending"},
|
||||
{"id": 424, "subject": "P3 Task 2: H6a — mark native conditions (isNative through the sink)", "status": "pending"},
|
||||
{"id": 425, "subject": "P3 Task 3: H4 — wire OnEnableDisable over OPC UA", "status": "pending", "blockedBy": [424]},
|
||||
{"id": 426, "subject": "P3 Task 4: H6b — AlarmAcknowledgeRequest.OperatorUser + Galaxy/ScriptedAlarmSource", "status": "pending"},
|
||||
{"id": 427, "subject": "P3 Task 5: H6c — NativeAlarmAckRouter seam + native OnAcknowledge routing", "status": "pending", "blockedBy": [424]},
|
||||
{"id": 428, "subject": "P3 Task 6: H6d — DriverHostActor inverse map + native-ack route to driver", "status": "pending", "blockedBy": [426, 427]},
|
||||
{"id": 429, "subject": "P3 Task 7: H6e — wire NativeAlarmAckRouter in host DI", "status": "pending", "blockedBy": [427, 428]},
|
||||
{"id": 430, "subject": "P3 Task 8: Docs — Enable/Disable + native-ack→AVEVA + HistoryUpdate bit", "status": "pending"},
|
||||
{"id": 431, "subject": "P3 Task 9: Full build + test + final integration review", "status": "pending", "blockedBy": [423, 425, 429, 430]},
|
||||
{"id": 432, "subject": "P3 Task 10: Live /run — H4 Enable/Disable + H6 native-ack route", "status": "pending", "blockedBy": [431]}
|
||||
{
|
||||
"id": 423,
|
||||
"subject": "P3 Task 1: H2-bit \u2014 NodePermissions.HistoryUpdate + evaluator mapping",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 424,
|
||||
"subject": "P3 Task 2: H6a \u2014 mark native conditions (isNative through the sink)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 425,
|
||||
"subject": "P3 Task 3: H4 \u2014 wire OnEnableDisable over OPC UA",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
424
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 426,
|
||||
"subject": "P3 Task 4: H6b \u2014 AlarmAcknowledgeRequest.OperatorUser + Galaxy/ScriptedAlarmSource",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 427,
|
||||
"subject": "P3 Task 5: H6c \u2014 NativeAlarmAckRouter seam + native OnAcknowledge routing",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
424
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 428,
|
||||
"subject": "P3 Task 6: H6d \u2014 DriverHostActor inverse map + native-ack route to driver",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
426,
|
||||
427
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 429,
|
||||
"subject": "P3 Task 7: H6e \u2014 wire NativeAlarmAckRouter in host DI",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
427,
|
||||
428
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 430,
|
||||
"subject": "P3 Task 8: Docs \u2014 Enable/Disable + native-ack\u2192AVEVA + HistoryUpdate bit",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 431,
|
||||
"subject": "P3 Task 9: Full build + test + final integration review",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
423,
|
||||
425,
|
||||
429,
|
||||
430
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 432,
|
||||
"subject": "P3 Task 10: Live /run \u2014 H4 Enable/Disable + H6 native-ack route",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
431
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-06-15"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Shipped \u2014 the stillpending backlog audit cites the landing commits (1e95856b, ada01e1a, fc8121cb, 3e609a2b, 70e6d3d2, c236263e, bd8fee61, 5e27b5f7, fcb38014). Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -2,14 +2,68 @@
|
||||
"planPath": "docs/plans/2026-06-16-stillpending-phase-4-driver-datatypes.md",
|
||||
"branch": "feat/stillpending-phase-4-driver-datatypes",
|
||||
"tasks": [
|
||||
{"id": 433, "subject": "P4 Task 1: Modbus Int64/UInt64 node DataType (MapDataType split)", "status": "pending"},
|
||||
{"id": 434, "subject": "P4 Task 2: FOCAS fail-fast factory (EnsureUsable at init)", "status": "pending"},
|
||||
{"id": 435, "subject": "P4 Task 3: FOCAS position scaling (PositionDecimalPlaces)", "status": "pending", "blockedBy": [434]},
|
||||
{"id": 436, "subject": "P4 Task 4: Historian Total aggregate (client-side Average x interval-seconds)", "status": "pending"},
|
||||
{"id": 437, "subject": "P4 Task 5: Historian poison-event dead-letter cap (maxAttempts)", "status": "pending"},
|
||||
{"id": 438, "subject": "P4 Task 6: Docs + bookkeeping", "status": "pending", "blockedBy": [433, 434, 435, 436, 437]},
|
||||
{"id": 439, "subject": "P4 Task 7: Full build + test + final integration review", "status": "pending", "blockedBy": [433, 434, 435, 436, 437, 438]},
|
||||
{"id": 440, "subject": "P4 Task 8: Live /run — Modbus Int64 (acceptance gate)", "status": "pending", "blockedBy": [439]}
|
||||
{
|
||||
"id": 433,
|
||||
"subject": "P4 Task 1: Modbus Int64/UInt64 node DataType (MapDataType split)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 434,
|
||||
"subject": "P4 Task 2: FOCAS fail-fast factory (EnsureUsable at init)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 435,
|
||||
"subject": "P4 Task 3: FOCAS position scaling (PositionDecimalPlaces)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
434
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 436,
|
||||
"subject": "P4 Task 4: Historian Total aggregate (client-side Average x interval-seconds)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 437,
|
||||
"subject": "P4 Task 5: Historian poison-event dead-letter cap (maxAttempts)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 438,
|
||||
"subject": "P4 Task 6: Docs + bookkeeping",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
433,
|
||||
434,
|
||||
435,
|
||||
436,
|
||||
437
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 439,
|
||||
"subject": "P4 Task 7: Full build + test + final integration review",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
433,
|
||||
434,
|
||||
435,
|
||||
436,
|
||||
437,
|
||||
438
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 440,
|
||||
"subject": "P4 Task 8: Live /run \u2014 Modbus Int64 (acceptance gate)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
439
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-06-16"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Shipped \u2014 the stillpending backlog audit cites the landing commits (1e95856b, ada01e1a, fc8121cb, 3e609a2b, 70e6d3d2, c236263e, bd8fee61, 5e27b5f7, fcb38014). Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -4,16 +4,61 @@
|
||||
"designCommit": "f90017bc",
|
||||
"baseMaster": "c081917a",
|
||||
"branch": "feat/stillpending-phase-4b-driver-gaps (merged to master 08a65513, deleted)",
|
||||
"executionState": "COMPLETE — shipped + pushed to master 08a65513 (ff). Final integration review = SHIP. Build clean; AdminUI 450, Galaxy 279(+3 skip), FOCAS 200, Modbus 277, DriverProbeRegistration 2 — all green. Live: Modbus typed editor + Build-address proven on the rig's seeded MAIN-modbus-eq (Modbus reconcile, conclusive); Galaxy browse rendered a nested hierarchical root via the real driver path (corroborated, unit-proven 8 ways); FOCAS unit-proven (no CNC).",
|
||||
"nativeTaskIds": {"1": 482, "2": 483, "3a": 484, "3b": 485, "4": 486, "5": 487, "6": 488},
|
||||
"executionState": "COMPLETE \u2014 shipped + pushed to master 08a65513 (ff). Final integration review = SHIP. Build clean; AdminUI 450, Galaxy 279(+3 skip), FOCAS 200, Modbus 277, DriverProbeRegistration 2 \u2014 all green. Live: Modbus typed editor + Build-address proven on the rig's seeded MAIN-modbus-eq (Modbus reconcile, conclusive); Galaxy browse rendered a nested hierarchical root via the real driver path (corroborated, unit-proven 8 ways); FOCAS unit-proven (no CNC).",
|
||||
"nativeTaskIds": {
|
||||
"1": 482,
|
||||
"2": 483,
|
||||
"3a": 484,
|
||||
"3b": 485,
|
||||
"4": 486,
|
||||
"5": 487,
|
||||
"6": 488
|
||||
},
|
||||
"tasks": [
|
||||
{"id": 1, "subject": "Task 1: Modbus driver-type-string reconcile (canonicalize on \"Modbus\")", "status": "completed", "commit": "8b4675b1", "reviewFixCommit": "a40c77de"},
|
||||
{"id": 2, "subject": "Task 2: Galaxy nested gobject hierarchy", "status": "completed", "commit": "21c7645d", "reviewFixCommit": "bec37848"},
|
||||
{"id": "3a", "subject": "Task 3a: IFocasClient.GetPositionFiguresAsync (cnc_getfigure binding)", "status": "completed", "commit": "3fcbc70c"},
|
||||
{"id": "3b", "subject": "Task 3b: FOCAS driver auto-scale wiring (auto wins, manual fallback)", "status": "completed", "commit": "6855be28"},
|
||||
{"id": 4, "subject": "Task 4: Docs + bookkeeping", "status": "completed", "commit": "08a65513"},
|
||||
{"id": 5, "subject": "Task 5: Full build + test + final integration review", "status": "completed", "note": "final integration review = SHIP (no Critical/Important); 3 Minor non-blocking notes recorded"},
|
||||
{"id": 6, "subject": "Task 6: Live /run verification", "status": "completed", "note": "Modbus typed editor live-proven on rig; Galaxy nested root corroborated; FOCAS unit-proven"}
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Task 1: Modbus driver-type-string reconcile (canonicalize on \"Modbus\")",
|
||||
"status": "completed",
|
||||
"commit": "8b4675b1",
|
||||
"reviewFixCommit": "a40c77de"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "Task 2: Galaxy nested gobject hierarchy",
|
||||
"status": "completed",
|
||||
"commit": "21c7645d",
|
||||
"reviewFixCommit": "bec37848"
|
||||
},
|
||||
{
|
||||
"id": "3a",
|
||||
"subject": "Task 3a: IFocasClient.GetPositionFiguresAsync (cnc_getfigure binding)",
|
||||
"status": "completed",
|
||||
"commit": "3fcbc70c"
|
||||
},
|
||||
{
|
||||
"id": "3b",
|
||||
"subject": "Task 3b: FOCAS driver auto-scale wiring (auto wins, manual fallback)",
|
||||
"status": "completed",
|
||||
"commit": "6855be28"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "Task 4: Docs + bookkeeping",
|
||||
"status": "completed",
|
||||
"commit": "08a65513"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Task 5: Full build + test + final integration review",
|
||||
"status": "completed",
|
||||
"note": "final integration review = SHIP (no Critical/Important); 3 Minor non-blocking notes recorded"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "Task 6: Live /run verification",
|
||||
"status": "completed",
|
||||
"note": "Modbus typed editor live-proven on rig; Galaxy nested root corroborated; FOCAS unit-proven"
|
||||
}
|
||||
],
|
||||
"reviewFollowUps": [
|
||||
"FOCAS minor: no upper-bound clamp on a misbehaving cnc_getfigure value (Math.Pow overflow; same latent risk the manual path had)",
|
||||
@@ -21,5 +66,6 @@
|
||||
"FOCAS: live auto-fetch on the real backend needs a cnc_getfigure command added to the managed FocasWireClient wire protocol (WireFocasClient returns empty today)",
|
||||
"Galaxy minor: 3-node chain cycle provably-correct but not directly tested (2-node mutual cycle is tested)"
|
||||
],
|
||||
"lastUpdated": "2026-06-16"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Shipped \u2014 the stillpending backlog audit cites the landing commits (1e95856b, ada01e1a, fc8121cb, 3e609a2b, 70e6d3d2, c236263e, bd8fee61, 5e27b5f7, fcb38014). Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -4,28 +4,121 @@
|
||||
"designCommit": "efccd8d1",
|
||||
"baseMaster": "050164b2",
|
||||
"branch": "feat/stillpending-phase-4c-array-support (merged to master 0f92e9e2, deleted)",
|
||||
"executionState": "COMPLETE — shipped + pushed to master 0f92e9e2 (ff, 23 commits). Big-bang all 5 drivers + full AbLegacy. Build clean; OpcUaServer 230, Runtime 272, AdminUI 472, Modbus 289, AbCip 292, TwinCAT 153, S7 143, AbLegacy 188 — all green. Bundle integration review caught the cross-driver isArray-gating divergence (C-1/C-2 Modbus+AbLegacy ignored isArray; I-1/I-2/I-3 the arrayLength=1 edge); final integration review = SHIP WITH MINOR FOLLOW-UPS (I-1 S7 clarity, I-2 AbCip degenerate-scalar, I-3 AbLegacy >256 author-validation, M-1 array nodes read-only) — all closed. LIVE /run PASS: a Modbus array equipment tag (HR[0..3], UInt16[4]) materialises as ValueRank=OneDimension/ArrayDimensions=[4] and a Good array value flows end-to-end from the live sim (read over the wire, Status 0x00000000, Value System.UInt16[]); the address-100 first attempt correctly surfaced the sim's Illegal-Data-Address as Bad (faithful device status). S7/AbCip/TwinCAT/AbLegacy unit-proven (fixtures down).",
|
||||
"executionState": "COMPLETE \u2014 shipped + pushed to master 0f92e9e2 (ff, 23 commits). Big-bang all 5 drivers + full AbLegacy. Build clean; OpcUaServer 230, Runtime 272, AdminUI 472, Modbus 289, AbCip 292, TwinCAT 153, S7 143, AbLegacy 188 \u2014 all green. Bundle integration review caught the cross-driver isArray-gating divergence (C-1/C-2 Modbus+AbLegacy ignored isArray; I-1/I-2/I-3 the arrayLength=1 edge); final integration review = SHIP WITH MINOR FOLLOW-UPS (I-1 S7 clarity, I-2 AbCip degenerate-scalar, I-3 AbLegacy >256 author-validation, M-1 array nodes read-only) \u2014 all closed. LIVE /run PASS: a Modbus array equipment tag (HR[0..3], UInt16[4]) materialises as ValueRank=OneDimension/ArrayDimensions=[4] and a Good array value flows end-to-end from the live sim (read over the wire, Status 0x00000000, Value System.UInt16[]); the address-100 first attempt correctly surfaced the sim's Illegal-Data-Address as Bad (faithful device status). S7/AbCip/TwinCAT/AbLegacy unit-proven (fixtures down).",
|
||||
"scope": "Big-bang all 5 drivers (AskUserQuestion) + full AbLegacy array read (AskUserQuestion). 1-D read-surface only; array writes / multi-dim / array historization out of scope (array nodes forced read-only at the applier per review M-1).",
|
||||
"nativeTaskIds": {"1": 495, "2": 496, "3": 497, "4": 498, "5": 499, "6": 500, "7": 501, "8": 502, "9": 503, "10": 504, "11": 505, "12": 506},
|
||||
"nativeTaskIds": {
|
||||
"1": 495,
|
||||
"2": 496,
|
||||
"3": 497,
|
||||
"4": 498,
|
||||
"5": 499,
|
||||
"6": 500,
|
||||
"7": 501,
|
||||
"8": 502,
|
||||
"9": 503,
|
||||
"10": 504,
|
||||
"11": 505,
|
||||
"12": 506
|
||||
},
|
||||
"tasks": [
|
||||
{"id": 1, "subject": "Sink contract — EnsureVariable array params", "classification": "high-risk", "status": "completed", "commit": "a7928202", "reviewFixCommit": "3172b7bd"},
|
||||
{"id": 2, "subject": "EquipmentTagPlan IsArray/ArrayLength + composer + applier", "classification": "high-risk", "status": "completed", "commit": "71cc4171", "reviewFixCommit": "584e9f2a"},
|
||||
{"id": 3, "subject": "DeploymentArtifact decode byte-parity", "classification": "high-risk", "status": "completed", "commit": "0a747c34", "reviewFixCommit": "eb8a8dc1"},
|
||||
{"id": 4, "subject": "AdminUI driver-agnostic isArray/arrayLength control", "classification": "standard", "status": "completed", "commit": "c2006dfb"},
|
||||
{"id": 5, "subject": "Modbus String/BitInRegister array decode + resolver", "classification": "small", "status": "completed", "commit": "8d3dc321", "reviewFixCommit": "49ac1392"},
|
||||
{"id": 6, "subject": "AbCip libplctag array read + IsArray", "classification": "standard", "status": "completed", "commit": "f4d5a5ee", "reviewFixCommit": "94e8c55b+5f7a2acd"},
|
||||
{"id": 7, "subject": "TwinCAT ADS array read + IsArray (reference impl, no fix needed)", "classification": "standard", "status": "completed", "commit": "3e742395"},
|
||||
{"id": 8, "subject": "S7 block-read array + decode loop + IsArray", "classification": "high-risk", "status": "completed", "commit": "a82c22c6", "reviewFixCommit": "3bbe39c1+d30fb77e"},
|
||||
{"id": 9, "subject": "AbLegacy PCCC multi-element array read + IsArray", "classification": "high-risk", "status": "completed", "commit": "95006939", "reviewFixCommit": "ce5d46be+0f92e9e2"},
|
||||
{"id": 10, "subject": "Docs + bookkeeping", "classification": "small", "status": "completed", "commit": "05c7e86f"},
|
||||
{"id": 11, "subject": "Full build + test + final integration review", "classification": "standard", "status": "completed", "note": "final integration review = SHIP WITH MINOR FOLLOW-UPS; 4 review fixes applied (d30fb77e/5f7a2acd/0f92e9e2/3bb2031d)"},
|
||||
{"id": 12, "subject": "Live /run acceptance + finish branch", "classification": "standard", "status": "completed", "note": "Modbus array tag live-proven (Good UInt16[4] from sim HR[0..3], over the wire); others unit-proven; root-caused the address-100 Bad as a sim Illegal-Data-Address (not a code bug)"}
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Sink contract \u2014 EnsureVariable array params",
|
||||
"classification": "high-risk",
|
||||
"status": "completed",
|
||||
"commit": "a7928202",
|
||||
"reviewFixCommit": "3172b7bd"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "EquipmentTagPlan IsArray/ArrayLength + composer + applier",
|
||||
"classification": "high-risk",
|
||||
"status": "completed",
|
||||
"commit": "71cc4171",
|
||||
"reviewFixCommit": "584e9f2a"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"subject": "DeploymentArtifact decode byte-parity",
|
||||
"classification": "high-risk",
|
||||
"status": "completed",
|
||||
"commit": "0a747c34",
|
||||
"reviewFixCommit": "eb8a8dc1"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "AdminUI driver-agnostic isArray/arrayLength control",
|
||||
"classification": "standard",
|
||||
"status": "completed",
|
||||
"commit": "c2006dfb"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Modbus String/BitInRegister array decode + resolver",
|
||||
"classification": "small",
|
||||
"status": "completed",
|
||||
"commit": "8d3dc321",
|
||||
"reviewFixCommit": "49ac1392"
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "AbCip libplctag array read + IsArray",
|
||||
"classification": "standard",
|
||||
"status": "completed",
|
||||
"commit": "f4d5a5ee",
|
||||
"reviewFixCommit": "94e8c55b+5f7a2acd"
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"subject": "TwinCAT ADS array read + IsArray (reference impl, no fix needed)",
|
||||
"classification": "standard",
|
||||
"status": "completed",
|
||||
"commit": "3e742395"
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"subject": "S7 block-read array + decode loop + IsArray",
|
||||
"classification": "high-risk",
|
||||
"status": "completed",
|
||||
"commit": "a82c22c6",
|
||||
"reviewFixCommit": "3bbe39c1+d30fb77e"
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"subject": "AbLegacy PCCC multi-element array read + IsArray",
|
||||
"classification": "high-risk",
|
||||
"status": "completed",
|
||||
"commit": "95006939",
|
||||
"reviewFixCommit": "ce5d46be+0f92e9e2"
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"subject": "Docs + bookkeeping",
|
||||
"classification": "small",
|
||||
"status": "completed",
|
||||
"commit": "05c7e86f"
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"subject": "Full build + test + final integration review",
|
||||
"classification": "standard",
|
||||
"status": "completed",
|
||||
"note": "final integration review = SHIP WITH MINOR FOLLOW-UPS; 4 review fixes applied (d30fb77e/5f7a2acd/0f92e9e2/3bb2031d)"
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"subject": "Live /run acceptance + finish branch",
|
||||
"classification": "standard",
|
||||
"status": "completed",
|
||||
"note": "Modbus array tag live-proven (Good UInt16[4] from sim HR[0..3], over the wire); others unit-proven; root-caused the address-100 Bad as a sim Illegal-Data-Address (not a code bug)"
|
||||
}
|
||||
],
|
||||
"reviewFollowUps": [
|
||||
"Foundation array test asserts in-process variable.Value only — add a wire-level Session.ReadValueAsync assertion over an array node (the live /run proved it works, but it's not unit-covered)",
|
||||
"Client.CLI read/subscribe prints an array value's type name (System.UInt16[]) not its elements — add array element formatting",
|
||||
"Foundation array test asserts in-process variable.Value only \u2014 add a wire-level Session.ReadValueAsync assertion over an array node (the live /run proved it works, but it's not unit-covered)",
|
||||
"Client.CLI read/subscribe prints an array value's type name (System.UInt16[]) not its elements \u2014 add array element formatting",
|
||||
"Array WRITES (inbound client->device), multi-dimensional arrays, array historization remain out of scope (named deferrals)",
|
||||
"Live array read for S7/AbCip/TwinCAT/AbLegacy is fixture-gated/operator-gated (unit-proven only); the 5 AbLegacy libplctag PCCC array-read assumptions need a real SLC/MicroLogix to confirm"
|
||||
],
|
||||
"lastUpdated": "2026-06-16"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Shipped \u2014 the stillpending backlog audit cites the landing commits (1e95856b, ada01e1a, fc8121cb, 3e609a2b, 70e6d3d2, c236263e, bd8fee61, 5e27b5f7, fcb38014). Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -1,27 +1,185 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-06-26-otopcua-historian-gateway-integration.md",
|
||||
"tasks": [
|
||||
{ "id": 0, "subject": "Task 1: Consume gateway packages + scaffold Gateway driver project", "status": "pending", "blockedBy": [] },
|
||||
{ "id": 1, "subject": "Task 2: HistoryAggregateType->RetrievalMode mapper (matrix-guarded)", "status": "pending", "blockedBy": [0] },
|
||||
{ "id": 2, "subject": "Task 3: DriverDataType->HistorianDataType mapper + write-gap fallbacks (matrix-guarded)", "status": "pending", "blockedBy": [0] },
|
||||
{ "id": 3, "subject": "Task 4: HistorianSample/Aggregate->DataValueSnapshot + quality mapper", "status": "pending", "blockedBy": [0] },
|
||||
{ "id": 4, "subject": "Task 5: HistorianEvent->HistoricalEvent mapper (+ severity)", "status": "pending", "blockedBy": [0] },
|
||||
{ "id": 5, "subject": "Task 6: AlarmHistorianEvent->HistorianEvent mapper (SendEvent)", "status": "pending", "blockedBy": [0] },
|
||||
{ "id": 6, "subject": "Task 7: GatewayHistorianDataSource read paths (raw/processed/at-time)", "status": "pending", "blockedBy": [1, 3] },
|
||||
{ "id": 7, "subject": "Task 8: GetHealthSnapshot via Probe/GetConnectionStatus", "status": "pending", "blockedBy": [6] },
|
||||
{ "id": 8, "subject": "Task 9: Reshape ServerHistorianOptions to gateway form", "status": "pending", "blockedBy": [0] },
|
||||
{ "id": 9, "subject": "Task 10: Swap AddServerHistorian factory in Program.cs (READ CUTOVER)", "status": "pending", "blockedBy": [6, 8] },
|
||||
{ "id": 10, "subject": "Task 11: ReadEventsAsync alarm-history on the data source", "status": "pending", "blockedBy": [6, 4] },
|
||||
{ "id": 11, "subject": "Task 12: GatewayAlarmHistorianWriter (SendEvent + outcome mapping)", "status": "pending", "blockedBy": [9, 5] },
|
||||
{ "id": 12, "subject": "Task 13: Swap AddAlarmHistorian factory in Program.cs", "status": "pending", "blockedBy": [11] },
|
||||
{ "id": 13, "subject": "Task 14: IHistorianProvisioning + GatewayTagProvisioner (EnsureTags)", "status": "pending", "blockedBy": [9, 2] },
|
||||
{ "id": 14, "subject": "Task 15: Hook provisioning into AddressSpaceApplier.Apply()", "status": "pending", "blockedBy": [13] },
|
||||
{ "id": 15, "subject": "Task 16: FasterLog historization outbox store", "status": "pending", "blockedBy": [9] },
|
||||
{ "id": 16, "subject": "Task 17: ContinuousHistorizationRecorder actor", "status": "pending", "blockedBy": [15, 9] },
|
||||
{ "id": 17, "subject": "Task 18: Wire recorder into DI + hosted lifecycle", "status": "pending", "blockedBy": [16] },
|
||||
{ "id": 18, "subject": "Task 19: Retire Wonderware historian projects", "status": "pending", "blockedBy": [9, 12, 17, 19] },
|
||||
{ "id": 19, "subject": "Task 20: Env-gated live validation vs wonder-sql-vd03", "status": "pending", "blockedBy": [9, 10, 12, 17] },
|
||||
{ "id": 20, "subject": "Task 21: Documentation (CLAUDE.md, appsettings, README)", "status": "pending", "blockedBy": [18] }
|
||||
{
|
||||
"id": 0,
|
||||
"subject": "Task 1: Consume gateway packages + scaffold Gateway driver project",
|
||||
"status": "completed",
|
||||
"blockedBy": []
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Task 2: HistoryAggregateType->RetrievalMode mapper (matrix-guarded)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "Task 3: DriverDataType->HistorianDataType mapper + write-gap fallbacks (matrix-guarded)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"subject": "Task 4: HistorianSample/Aggregate->DataValueSnapshot + quality mapper",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "Task 5: HistorianEvent->HistoricalEvent mapper (+ severity)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Task 6: AlarmHistorianEvent->HistorianEvent mapper (SendEvent)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "Task 7: GatewayHistorianDataSource read paths (raw/processed/at-time)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"subject": "Task 8: GetHealthSnapshot via Probe/GetConnectionStatus",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"subject": "Task 9: Reshape ServerHistorianOptions to gateway form",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"subject": "Task 10: Swap AddServerHistorian factory in Program.cs (READ CUTOVER)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
6,
|
||||
8
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"subject": "Task 11: ReadEventsAsync alarm-history on the data source",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
6,
|
||||
4
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"subject": "Task 12: GatewayAlarmHistorianWriter (SendEvent + outcome mapping)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"subject": "Task 13: Swap AddAlarmHistorian factory in Program.cs",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
11
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"subject": "Task 14: IHistorianProvisioning + GatewayTagProvisioner (EnsureTags)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9,
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"subject": "Task 15: Hook provisioning into AddressSpaceApplier.Apply()",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
13
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"subject": "Task 16: FasterLog historization outbox store",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"subject": "Task 17: ContinuousHistorizationRecorder actor",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
15,
|
||||
9
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"subject": "Task 18: Wire recorder into DI + hosted lifecycle",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
16
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"subject": "Task 19: Retire Wonderware historian projects",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9,
|
||||
12,
|
||||
17,
|
||||
19
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"subject": "Task 20: Env-gated live validation vs wonder-sql-vd03",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9,
|
||||
10,
|
||||
12,
|
||||
17
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"subject": "Task 21: Documentation (CLAUDE.md, appsettings, README)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
18
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-06-26"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Shipped as PR #423 and live-validated against the gateway on wonder-sql-vd03. Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -2,14 +2,69 @@
|
||||
"planPath": "docs/plans/2026-07-22-per-cluster-mesh-program.md",
|
||||
"note": "PROGRAM plan: each task = write that phase's detailed plan (writing-plans), execute it (executing-plans), run its exit gate, update the tracking tables. Prereq task 0 is the separate selfform-fallback plan in this repo.",
|
||||
"tasks": [
|
||||
{"id": 0, "subject": "Prereq: execute 2026-07-22-selfform-fallback-and-manual-failover.md (7 tasks)", "status": "completed", "note": "Shipped as self-first seed ordering + AkkaClusterOptionsValidator, NOT the planned SelfFormAfter watchdog (live gate caught it islanding a failed-over node). Merged a78425ea."},
|
||||
{"id": 1, "subject": "Phase 1: ClusterNode Akka+gRPC address columns; ConfigPublishCoordinator ack set from DB", "status": "completed", "note": "Merged 7654f24d. Escape hatch is ClusterNode.MaintenanceMode, not Enabled=0."},
|
||||
{"id": 2, "subject": "Phase 2: comm actors + receptionist + ClusterClient transport (deploy notify/acks, driver-control)", "status": "in_progress", "blockedBy": [1]},
|
||||
{"id": 3, "subject": "Phase 3: config fetch-and-cache from central; LocalDb steady-state config store (live gate)", "status": "pending", "blockedBy": [2]},
|
||||
{"id": 4, "subject": "Phase 4: cut driver-side ConfigDb — EfAlarmConditionStateStore to LocalDb, DbHealthProbeActor ServiceLevel input, OpcUaPublishActor audit (live gate)", "status": "pending", "blockedBy": [3]},
|
||||
{"id": 5, "subject": "Phase 5: gRPC oneof stream contract; migrate 7 observability topics; AdminUI reconnect story", "status": "pending", "blockedBy": [2]},
|
||||
{"id": 6, "subject": "Phase 6: mesh partition — per-pair seeds, cluster-scoped roles/singletons, co-location rig rewrite, secrets replication re-scope", "status": "pending", "blockedBy": [0, 4, 5]},
|
||||
{"id": 7, "subject": "Phase 7: failover drill per pair (incl. shared-VM failure) + close auto-down 1v1 and self-first cold-start-alone live gates + operator runbook", "status": "pending", "blockedBy": [6]}
|
||||
{
|
||||
"id": 0,
|
||||
"subject": "Prereq: execute 2026-07-22-selfform-fallback-and-manual-failover.md (7 tasks)",
|
||||
"status": "completed",
|
||||
"note": "Shipped as self-first seed ordering + AkkaClusterOptionsValidator, NOT the planned SelfFormAfter watchdog (live gate caught it islanding a failed-over node). Merged a78425ea."
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Phase 1: ClusterNode Akka+gRPC address columns; ConfigPublishCoordinator ack set from DB",
|
||||
"status": "completed",
|
||||
"note": "Merged 7654f24d. Escape hatch is ClusterNode.MaintenanceMode, not Enabled=0."
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "Phase 2: comm actors + receptionist + ClusterClient transport (deploy notify/acks, driver-control)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"subject": "Phase 3: config fetch-and-cache from central; LocalDb steady-state config store (live gate)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "Phase 4: cut driver-side ConfigDb \u2014 EfAlarmConditionStateStore to LocalDb, DbHealthProbeActor ServiceLevel input, OpcUaPublishActor audit (live gate)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Phase 5: gRPC oneof stream contract; migrate 7 observability topics; AdminUI reconnect story",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "Phase 6: mesh partition \u2014 per-pair seeds, cluster-scoped roles/singletons, co-location rig rewrite, secrets replication re-scope",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0,
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"subject": "Phase 7: failover drill per pair (incl. shared-VM failure) + close auto-down 1v1 and self-first cold-start-alone live gates + operator runbook",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
6
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-07-22T00:00:00Z"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Program COMPLETE (Phases 0a-7 + bootstrap guard), origin/master d1dac87f. Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@
|
||||
{
|
||||
"id": 9,
|
||||
"subject": "Task 9: Drop dead ConfigDb ScriptedAlarmState table + retire EfAlarmConditionStateStore",
|
||||
"status": "deferred",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
6
|
||||
],
|
||||
@@ -128,5 +128,6 @@
|
||||
"result": "LIVE GATE PASSED \u2014 deploy sealed green w/ 4 DB-less site nodes acking; ServiceLevel 240 w/ central SQL down; restart booted last-known-good from LocalDb pointer; grep proof; alarm_condition_state table live+replicated. Doc: 2026-07-23-mesh-phase4-live-gate.md"
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-07-23"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Task 9 landed 3a590a0c; live gate PASSED 1281aebf. Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -1,17 +1,91 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-07-24-modbus-rtu-driver.md",
|
||||
"tasks": [
|
||||
{"id": 0, "subject": "Task 0: Add the ModbusTransportMode enum (Tcp | RtuOverTcp)", "status": "pending"},
|
||||
{"id": 1, "subject": "Task 1: ModbusCrc CRC-16/MODBUS helper + golden vectors", "status": "pending"},
|
||||
{"id": 2, "subject": "Task 2: ModbusRtuFraming ADU build + FC-aware length-less deframe", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 3, "subject": "Task 3: Extract ModbusSocketLifecycle from ModbusTcpTransport (behaviour-preserving)", "status": "pending"},
|
||||
{"id": 4, "subject": "Task 4: ModbusRtuOverTcpTransport (RTU framing over socket lifecycle)", "status": "pending", "blockedBy": [2, 3]},
|
||||
{"id": 5, "subject": "Task 5: ModbusTransportFactory.Create switch on Transport mode", "status": "pending", "blockedBy": [0, 4]},
|
||||
{"id": 6, "subject": "Task 6: Bind Transport on options/DTO/factory (string-enum guard)", "status": "pending", "blockedBy": [0]},
|
||||
{"id": 7, "subject": "Task 7: Route driver default closure + probe through ModbusTransportFactory", "status": "pending", "blockedBy": [5, 6]},
|
||||
{"id": 8, "subject": "Task 8: AdminUI Transport selector on ModbusDriverForm", "status": "pending", "blockedBy": [6]},
|
||||
{"id": 9, "subject": "Task 9: Docker rtu_over_tcp fixture + RTU-over-TCP integration test", "status": "pending", "blockedBy": [4, 7]},
|
||||
{"id": 10, "subject": "Task 10: Live /run verification on docker-dev", "status": "pending", "blockedBy": [8, 9]}
|
||||
{
|
||||
"id": 0,
|
||||
"subject": "Task 0: Add the ModbusTransportMode enum (Tcp | RtuOverTcp)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Task 1: ModbusCrc CRC-16/MODBUS helper + golden vectors",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "Task 2: ModbusRtuFraming ADU build + FC-aware length-less deframe",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"subject": "Task 3: Extract ModbusSocketLifecycle from ModbusTcpTransport (behaviour-preserving)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "Task 4: ModbusRtuOverTcpTransport (RTU framing over socket lifecycle)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Task 5: ModbusTransportFactory.Create switch on Transport mode",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0,
|
||||
4
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "Task 6: Bind Transport on options/DTO/factory (string-enum guard)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"subject": "Task 7: Route driver default closure + probe through ModbusTransportFactory",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
5,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"subject": "Task 8: AdminUI Transport selector on ModbusDriverForm",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"subject": "Task 9: Docker rtu_over_tcp fixture + RTU-over-TCP integration test",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
4,
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"subject": "Task 10: Live /run verification on docker-dev",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
8,
|
||||
9
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-07-24"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Merged 0f38f486 (#495); live gate PASSED. Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -1,34 +1,315 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-07-24-mqtt-sparkplug-driver.md",
|
||||
"note": "Wave 2 MQTT/Sparkplug B driver. Two phases both in-scope: P1 (plain MQTT, Tasks 0-14) is a complete shippable milestone; P2 (Sparkplug B ingest, Tasks 15-26) builds on it and every P2 task chains back to Task 14. Write-through (NCMD/DCMD/plain publish) is DEFERRED (design P3). Hard rules: Task 0 (MQTTnet-5/net10 restore+build under central pinning with transitive pinning OFF) is the mandatory FIRST gate. Hand-roll Tahu proto over ONE MQTTnet-5 client (NOT SparkplugNet — its MQTTnet-4.x transitive pin collides with the repo's deliberately-OFF CentralPackageTransitivePinning). DriverType string is 'Mqtt' everywhere (grep-enforced). Enum-serialization trap: every JSON seam uses shared JsonSerializerOptions with JsonStringEnumConverter. Fixtures enforce TLS+auth, never anonymous/public-broker. Google.Protobuf (3.34.1) + Grpc.Tools (2.76.0) already pinned; MQTTnet is the one new pin. High-risk tasks: 4 (hand-rolled reconnect loop), 18/19 (alias/seq state-machine components), 21 (the full 3.6 ingest matrix).",
|
||||
"note": "Wave 2 MQTT/Sparkplug B driver. Two phases both in-scope: P1 (plain MQTT, Tasks 0-14) is a complete shippable milestone; P2 (Sparkplug B ingest, Tasks 15-26) builds on it and every P2 task chains back to Task 14. Write-through (NCMD/DCMD/plain publish) is DEFERRED (design P3). Hard rules: Task 0 (MQTTnet-5/net10 restore+build under central pinning with transitive pinning OFF) is the mandatory FIRST gate. Hand-roll Tahu proto over ONE MQTTnet-5 client (NOT SparkplugNet \u2014 its MQTTnet-4.x transitive pin collides with the repo's deliberately-OFF CentralPackageTransitivePinning). DriverType string is 'Mqtt' everywhere (grep-enforced). Enum-serialization trap: every JSON seam uses shared JsonSerializerOptions with JsonStringEnumConverter. Fixtures enforce TLS+auth, never anonymous/public-broker. Google.Protobuf (3.34.1) + Grpc.Tools (2.76.0) already pinned; MQTTnet is the one new pin. High-risk tasks: 4 (hand-rolled reconnect loop), 18/19 (alias/seq state-machine components), 21 (the full 3.6 ingest matrix).",
|
||||
"tasks": [
|
||||
{"id": 0, "subject": "Task 0 (P1): Dependency-validation spike — MQTTnet-5 pin + net10 restore/build under central pinning", "status": "pending", "classification": "standard", "parallelizableWith": []},
|
||||
{"id": 1, "subject": "Task 1 (P1): .Contracts enums + MqttDriverOptions DTO (name-serialized)", "status": "pending", "classification": "small", "parallelizableWith": [], "blockedBy": [0]},
|
||||
{"id": 2, "subject": "Task 2 (P1): .Contracts MqttTagDefinition + MqttEquipmentTagParser (plain, strict enum)", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [1]},
|
||||
{"id": 3, "subject": "Task 3 (P1): .Driver + MqttConnection connect/TLS/auth (bounded deadline)", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [1]},
|
||||
{"id": 4, "subject": "Task 4 (P1): MqttConnection hand-rolled reconnect loop (backoff + resubscribe)", "status": "pending", "classification": "high-risk", "parallelizableWith": [], "blockedBy": [3]},
|
||||
{"id": 5, "subject": "Task 5 (P1): LastValueCache + IReadable (per-ref no-data)", "status": "pending", "classification": "small", "parallelizableWith": [6], "blockedBy": [3]},
|
||||
{"id": 6, "subject": "Task 6 (P1): ISubscribable plain topic subscribe→OnDataChange + retained seed", "status": "pending", "classification": "standard", "parallelizableWith": [5], "blockedBy": [2, 4]},
|
||||
{"id": 7, "subject": "Task 7 (P1): MqttDriver shell — IDriver + authored-only ITagDiscovery (Once) + probe interface", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [5, 6]},
|
||||
{"id": 8, "subject": "Task 8 (P1): MqttDriverProbe CONNECT handshake", "status": "pending", "classification": "small", "parallelizableWith": [10], "blockedBy": [3]},
|
||||
{"id": 9, "subject": "Task 9 (P1): Factory + DriverTypeNames.Mqtt + Host factory/probe registration", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [7, 8]},
|
||||
{"id": 10, "subject": "Task 10 (P1): .Browser bespoke #-observation browser (passive)", "status": "pending", "classification": "standard", "parallelizableWith": [8], "blockedBy": [2]},
|
||||
{"id": 11, "subject": "Task 11 (P1): Register MqttDriverBrowser (bespoke-first for Mqtt)", "status": "pending", "classification": "trivial", "parallelizableWith": [12], "blockedBy": [10]},
|
||||
{"id": 12, "subject": "Task 12 (P1): Typed AdminUI editor + validator (plain shape)", "status": "pending", "classification": "standard", "parallelizableWith": [11], "blockedBy": [2]},
|
||||
{"id": 13, "subject": "Task 13 (P1): Mosquitto+JSON-publisher fixture (TLS+auth) + env-gated live suite", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [9]},
|
||||
{"id": 14, "subject": "Task 14 (P1): Live /run verify on docker-dev — P1 MILESTONE COMPLETE", "status": "pending", "classification": "small", "parallelizableWith": [], "blockedBy": [9, 11, 12, 13]},
|
||||
{"id": 15, "subject": "Task 15 (P2): Vendor Tahu sparkplug_b.proto + Grpc.Tools codegen", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [14]},
|
||||
{"id": 16, "subject": "Task 16 (P2): SparkplugCodec decode + golden payload vectors", "status": "pending", "classification": "standard", "parallelizableWith": [17], "blockedBy": [15]},
|
||||
{"id": 17, "subject": "Task 17 (P2): SparkplugTopic parse/format + SparkplugDataType.ToDriverDataType map", "status": "pending", "classification": "small", "parallelizableWith": [16], "blockedBy": [15]},
|
||||
{"id": 18, "subject": "Task 18 (P2): BirthCache + AliasTable — bind-by-name, rebuild-per-birth", "status": "pending", "classification": "high-risk", "parallelizableWith": [19], "blockedBy": [16, 17]},
|
||||
{"id": 19, "subject": "Task 19 (P2): SequenceTracker seq-gap + bdSeq death-tie", "status": "pending", "classification": "high-risk", "parallelizableWith": [18], "blockedBy": [16, 17]},
|
||||
{"id": 20, "subject": "Task 20 (P2): RebirthRequester NCMD encode", "status": "pending", "classification": "small", "parallelizableWith": [], "blockedBy": [16]},
|
||||
{"id": 21, "subject": "Task 21 (P2): Sparkplug ingest state machine — the 3.6 matrix", "status": "pending", "classification": "high-risk", "parallelizableWith": [], "blockedBy": [18, 19, 20]},
|
||||
{"id": 22, "subject": "Task 22 (P2): ITagDiscovery UntilStable + IRediscoverable (rediscover-on-DBIRTH)", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [21]},
|
||||
{"id": 23, "subject": "Task 23 (P2): Sparkplug browser tree + AttributesAsync + scoped RequestRebirthAsync", "status": "pending", "classification": "standard", "parallelizableWith": [24], "blockedBy": [20, 21]},
|
||||
{"id": 24, "subject": "Task 24 (P2): AdminUI editor Sparkplug mode shape + validator", "status": "pending", "classification": "small", "parallelizableWith": [23], "blockedBy": [12, 17]},
|
||||
{"id": 25, "subject": "Task 25 (P2): C# edge-node simulator fixture + 3.6 live matrix", "status": "pending", "classification": "standard", "parallelizableWith": [], "blockedBy": [21, 22, 23]},
|
||||
{"id": 26, "subject": "Task 26 (P2): Live /run verify Sparkplug — P2 COMPLETE", "status": "pending", "classification": "small", "parallelizableWith": [], "blockedBy": [23, 24, 25]}
|
||||
{
|
||||
"id": 0,
|
||||
"subject": "Task 0 (P1): Dependency-validation spike \u2014 MQTTnet-5 pin + net10 restore/build under central pinning",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": []
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Task 1 (P1): .Contracts enums + MqttDriverOptions DTO (name-serialized)",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "Task 2 (P1): .Contracts MqttTagDefinition + MqttEquipmentTagParser (plain, strict enum)",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"subject": "Task 3 (P1): .Driver + MqttConnection connect/TLS/auth (bounded deadline)",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "Task 4 (P1): MqttConnection hand-rolled reconnect loop (backoff + resubscribe)",
|
||||
"status": "completed",
|
||||
"classification": "high-risk",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Task 5 (P1): LastValueCache + IReadable (per-ref no-data)",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [
|
||||
6
|
||||
],
|
||||
"blockedBy": [
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "Task 6 (P1): ISubscribable plain topic subscribe\u2192OnDataChange + retained seed",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [
|
||||
5
|
||||
],
|
||||
"blockedBy": [
|
||||
2,
|
||||
4
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"subject": "Task 7 (P1): MqttDriver shell \u2014 IDriver + authored-only ITagDiscovery (Once) + probe interface",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
5,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"subject": "Task 8 (P1): MqttDriverProbe CONNECT handshake",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [
|
||||
10
|
||||
],
|
||||
"blockedBy": [
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"subject": "Task 9 (P1): Factory + DriverTypeNames.Mqtt + Host factory/probe registration",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
7,
|
||||
8
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"subject": "Task 10 (P1): .Browser bespoke #-observation browser (passive)",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [
|
||||
8
|
||||
],
|
||||
"blockedBy": [
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"subject": "Task 11 (P1): Register MqttDriverBrowser (bespoke-first for Mqtt)",
|
||||
"status": "completed",
|
||||
"classification": "trivial",
|
||||
"parallelizableWith": [
|
||||
12
|
||||
],
|
||||
"blockedBy": [
|
||||
10
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"subject": "Task 12 (P1): Typed AdminUI editor + validator (plain shape)",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [
|
||||
11
|
||||
],
|
||||
"blockedBy": [
|
||||
2
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"subject": "Task 13 (P1): Mosquitto+JSON-publisher fixture (TLS+auth) + env-gated live suite",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
9
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"subject": "Task 14 (P1): Live /run verify on docker-dev \u2014 P1 MILESTONE COMPLETE",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
9,
|
||||
11,
|
||||
12,
|
||||
13
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"subject": "Task 15 (P2): Vendor Tahu sparkplug_b.proto + Grpc.Tools codegen",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
14
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"subject": "Task 16 (P2): SparkplugCodec decode + golden payload vectors",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [
|
||||
17
|
||||
],
|
||||
"blockedBy": [
|
||||
15
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"subject": "Task 17 (P2): SparkplugTopic parse/format + SparkplugDataType.ToDriverDataType map",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [
|
||||
16
|
||||
],
|
||||
"blockedBy": [
|
||||
15
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"subject": "Task 18 (P2): BirthCache + AliasTable \u2014 bind-by-name, rebuild-per-birth",
|
||||
"status": "completed",
|
||||
"classification": "high-risk",
|
||||
"parallelizableWith": [
|
||||
19
|
||||
],
|
||||
"blockedBy": [
|
||||
16,
|
||||
17
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"subject": "Task 19 (P2): SequenceTracker seq-gap + bdSeq death-tie",
|
||||
"status": "completed",
|
||||
"classification": "high-risk",
|
||||
"parallelizableWith": [
|
||||
18
|
||||
],
|
||||
"blockedBy": [
|
||||
16,
|
||||
17
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"subject": "Task 20 (P2): RebirthRequester NCMD encode",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
16
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"subject": "Task 21 (P2): Sparkplug ingest state machine \u2014 the 3.6 matrix",
|
||||
"status": "completed",
|
||||
"classification": "high-risk",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
18,
|
||||
19,
|
||||
20
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"subject": "Task 22 (P2): ITagDiscovery UntilStable + IRediscoverable (rediscover-on-DBIRTH)",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
21
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 23,
|
||||
"subject": "Task 23 (P2): Sparkplug browser tree + AttributesAsync + scoped RequestRebirthAsync",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [
|
||||
24
|
||||
],
|
||||
"blockedBy": [
|
||||
20,
|
||||
21
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 24,
|
||||
"subject": "Task 24 (P2): AdminUI editor Sparkplug mode shape + validator",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [
|
||||
23
|
||||
],
|
||||
"blockedBy": [
|
||||
12,
|
||||
17
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 25,
|
||||
"subject": "Task 25 (P2): C# edge-node simulator fixture + 3.6 live matrix",
|
||||
"status": "completed",
|
||||
"classification": "standard",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
21,
|
||||
22,
|
||||
23
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 26,
|
||||
"subject": "Task 26 (P2): Live /run verify Sparkplug \u2014 P2 COMPLETE",
|
||||
"status": "completed",
|
||||
"classification": "small",
|
||||
"parallelizableWith": [],
|
||||
"blockedBy": [
|
||||
23,
|
||||
24,
|
||||
25
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-07-24"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "All 27 tasks shipped, both phases live-gated. Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -1,29 +1,199 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-07-24-mtconnect-driver.md",
|
||||
"tasks": [
|
||||
{"id": 0, "subject": "Task 0: Verify TrakHound MTConnect.NET pin (or record the hand-roll decision)", "status": "pending"},
|
||||
{"id": 1, "subject": "Task 1: Scaffold the two driver projects + the test project", "status": "pending", "blockedBy": [0]},
|
||||
{"id": 2, "subject": "Task 2: MTConnectDriverOptions + MTConnectTagDefinition in .Contracts", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 3, "subject": "Task 3: MTConnectDataTypeInference.Infer + golden type-map test", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 4, "subject": "Task 4: Capture the canned XML fixtures", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 5, "subject": "Task 5: IMTConnectAgentClient seam + return DTOs", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 6, "subject": "Task 6: MTConnectAgentClient — parse /probe into the device model", "status": "pending", "blockedBy": [4, 5]},
|
||||
{"id": 7, "subject": "Task 7: MTConnectAgentClient — parse /current + /sample, detect the sequence gap", "status": "pending", "blockedBy": [4, 5, 6]},
|
||||
{"id": 8, "subject": "Task 8: MTConnectObservationIndex + UNAVAILABLE -> BadNoCommunication", "status": "pending", "blockedBy": [7]},
|
||||
{"id": 9, "subject": "Task 9: MTConnectDriver shell — IDriver lifecycle", "status": "pending", "blockedBy": [2, 8]},
|
||||
{"id": 10, "subject": "Task 10: IReadable.ReadAsync — /current, ordered snapshots", "status": "pending", "blockedBy": [9]},
|
||||
{"id": 11, "subject": "Task 11: ISubscribable — /sample long-poll pump + ring-buffer re-baseline", "status": "pending", "blockedBy": [9, 7]},
|
||||
{"id": 12, "subject": "Task 12: ITagDiscovery.DiscoverAsync + SupportsOnlineDiscovery=true", "status": "pending", "blockedBy": [9, 6]},
|
||||
{"id": 13, "subject": "Task 13: IHostConnectivityProbe + IRediscoverable (instanceId watch)", "status": "pending", "blockedBy": [9]},
|
||||
{"id": 14, "subject": "Task 14: MTConnectDriverProbe : IDriverProbe", "status": "pending", "blockedBy": [2, 5]},
|
||||
{"id": 15, "subject": "Task 15: MTConnectDriverFactoryExtensions", "status": "pending", "blockedBy": [2, 9]},
|
||||
{"id": 16, "subject": "Task 16: Host registration + DriverTypeNames.MTConnect + guard-test parity", "status": "pending", "blockedBy": [14, 15]},
|
||||
{"id": 17, "subject": "Task 17: AdminUI typed model MTConnectTagConfigModel", "status": "pending", "blockedBy": [3, 16]},
|
||||
{"id": 18, "subject": "Task 18: AdminUI editor razor + map/validator registration", "status": "pending", "blockedBy": [17]},
|
||||
{"id": 19, "subject": "Task 19: mtconnect/cppagent docker fixture", "status": "pending", "blockedBy": [16]},
|
||||
{"id": 20, "subject": "Task 20: Env-gated integration suite against cppagent", "status": "pending", "blockedBy": [19]},
|
||||
{"id": 21, "subject": "Task 21: Live /run verify on docker-dev — browse picker, editor, read, subscribe, deploy", "status": "pending", "blockedBy": [18, 20]},
|
||||
{"id": 22, "subject": "Task 22: Docs + deferred-writeback note; update the tracking doc", "status": "pending", "blockedBy": [21]}
|
||||
{
|
||||
"id": 0,
|
||||
"subject": "Task 0: Verify TrakHound MTConnect.NET pin (or record the hand-roll decision)",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Task 1: Scaffold the two driver projects + the test project",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "Task 2: MTConnectDriverOptions + MTConnectTagDefinition in .Contracts",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"subject": "Task 3: MTConnectDataTypeInference.Infer + golden type-map test",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "Task 4: Capture the canned XML fixtures",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Task 5: IMTConnectAgentClient seam + return DTOs",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "Task 6: MTConnectAgentClient \u2014 parse /probe into the device model",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
4,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"subject": "Task 7: MTConnectAgentClient \u2014 parse /current + /sample, detect the sequence gap",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
4,
|
||||
5,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"subject": "Task 8: MTConnectObservationIndex + UNAVAILABLE -> BadNoCommunication",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"subject": "Task 9: MTConnectDriver shell \u2014 IDriver lifecycle",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2,
|
||||
8
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"subject": "Task 10: IReadable.ReadAsync \u2014 /current, ordered snapshots",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"subject": "Task 11: ISubscribable \u2014 /sample long-poll pump + ring-buffer re-baseline",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9,
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"subject": "Task 12: ITagDiscovery.DiscoverAsync + SupportsOnlineDiscovery=true",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"subject": "Task 13: IHostConnectivityProbe + IRediscoverable (instanceId watch)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"subject": "Task 14: MTConnectDriverProbe : IDriverProbe",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2,
|
||||
5
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"subject": "Task 15: MTConnectDriverFactoryExtensions",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2,
|
||||
9
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"subject": "Task 16: Host registration + DriverTypeNames.MTConnect + guard-test parity",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
14,
|
||||
15
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"subject": "Task 17: AdminUI typed model MTConnectTagConfigModel",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
3,
|
||||
16
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"subject": "Task 18: AdminUI editor razor + map/validator registration",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
17
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"subject": "Task 19: mtconnect/cppagent docker fixture",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
16
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"subject": "Task 20: Env-gated integration suite against cppagent",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
19
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"subject": "Task 21: Live /run verify on docker-dev \u2014 browse picker, editor, read, subscribe, deploy",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
18,
|
||||
20
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 22,
|
||||
"subject": "Task 22: Docs + deferred-writeback note; update the tracking doc",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
21
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-07-24"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Merged at master 90bdaa44 (#506); 5-leg live gate PASSED. Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
@@ -1,28 +1,191 @@
|
||||
{
|
||||
"planPath": "docs/plans/2026-07-24-sql-poll-driver.md",
|
||||
"tasks": [
|
||||
{"id": 0, "subject": "Task 0: Scaffold Driver.Sql.Contracts project + register in slnx", "status": "pending"},
|
||||
{"id": 1, "subject": "Task 1: SqlProvider/SqlTagModel enums + SqlDriverConfigDto", "status": "pending", "blockedBy": [0]},
|
||||
{"id": 2, "subject": "Task 2: SqlTagDefinition + SqlEquipmentTagParser (strict enums, malicious-input safe)", "status": "pending", "blockedBy": [1]},
|
||||
{"id": 3, "subject": "Task 3: Scaffold Driver.Sql runtime project + register in slnx", "status": "pending", "blockedBy": [0]},
|
||||
{"id": 4, "subject": "Task 4: ISqlDialect + SqlServerDialect (QuoteIdentifier, catalog SQL, MapColumnType)", "status": "pending", "blockedBy": [1, 3]},
|
||||
{"id": 5, "subject": "Task 5: SqlQueryPlan grouping + parameter binding (pure)", "status": "pending", "blockedBy": [2, 4]},
|
||||
{"id": 6, "subject": "Task 6: Scaffold Driver.Sql.Tests + SqliteDialect + SqlitePollFixture", "status": "pending", "blockedBy": [3, 4]},
|
||||
{"id": 7, "subject": "Task 7: SqlPollReader core — grouped read, bounded deadline, ordered slice-back", "status": "pending", "blockedBy": [5, 6]},
|
||||
{"id": 8, "subject": "Task 8: SqlDriver shell — IDriver/ITagDiscovery/IReadable/ISubscribable/IHostConnectivityProbe", "status": "pending", "blockedBy": [7]},
|
||||
{"id": 9, "subject": "Task 9: SqlDriverFactoryExtensions + connectionStringRef env resolution + enum guard", "status": "pending", "blockedBy": [8]},
|
||||
{"id": 10, "subject": "Task 10: SqlDriverProbe (SELECT 1 liveness)", "status": "pending", "blockedBy": [4, 6]},
|
||||
{"id": 11, "subject": "Task 11: Host registration — DriverTypeNames.Sql + factory + probe + guard test", "status": "pending", "blockedBy": [9, 10]},
|
||||
{"id": 12, "subject": "Task 12: Scaffold Driver.Sql.Browser project + register in slnx", "status": "pending", "blockedBy": [3]},
|
||||
{"id": 13, "subject": "Task 13: SqlBrowseSession — schema walk over dialect catalog", "status": "pending", "blockedBy": [4, 12, 6]},
|
||||
{"id": 14, "subject": "Task 14: SqlDriverBrowser — env-ref/literal transient-connection open", "status": "pending", "blockedBy": [13]},
|
||||
{"id": 15, "subject": "Task 15: AdminUI browser DI + SqlAddressPickerBody.razor", "status": "pending", "blockedBy": [14]},
|
||||
{"id": 16, "subject": "Task 16: Env-gated central-SQL integration fixture + read round-trip", "status": "pending", "blockedBy": [8]},
|
||||
{"id": 17, "subject": "Task 17: Injection regression test (bind value / reject identifier)", "status": "pending", "blockedBy": [7]},
|
||||
{"id": 18, "subject": "Task 18: Blackhole/timeout live-gate on a dedicated mssql container", "status": "pending", "blockedBy": [16]},
|
||||
{"id": 19, "subject": "Task 19: AdminUI typed Sql tag-config model + validator (string enums)", "status": "pending", "blockedBy": [1, 11]},
|
||||
{"id": 20, "subject": "Task 20: SqlTagConfigEditor.razor shell", "status": "pending", "blockedBy": [19]},
|
||||
{"id": 21, "subject": "Task 21: Live /run verification on docker-dev (picker + editor + deploy + read)", "status": "pending", "blockedBy": [11, 15, 20]}
|
||||
{
|
||||
"id": 0,
|
||||
"subject": "Task 0: Scaffold Driver.Sql.Contracts project + register in slnx",
|
||||
"status": "completed"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"subject": "Task 1: SqlProvider/SqlTagModel enums + SqlDriverConfigDto",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"subject": "Task 2: SqlTagDefinition + SqlEquipmentTagParser (strict enums, malicious-input safe)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"subject": "Task 3: Scaffold Driver.Sql runtime project + register in slnx",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
0
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"subject": "Task 4: ISqlDialect + SqlServerDialect (QuoteIdentifier, catalog SQL, MapColumnType)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1,
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"subject": "Task 5: SqlQueryPlan grouping + parameter binding (pure)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
2,
|
||||
4
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"subject": "Task 6: Scaffold Driver.Sql.Tests + SqliteDialect + SqlitePollFixture",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
3,
|
||||
4
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 7,
|
||||
"subject": "Task 7: SqlPollReader core \u2014 grouped read, bounded deadline, ordered slice-back",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
5,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 8,
|
||||
"subject": "Task 8: SqlDriver shell \u2014 IDriver/ITagDiscovery/IReadable/ISubscribable/IHostConnectivityProbe",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 9,
|
||||
"subject": "Task 9: SqlDriverFactoryExtensions + connectionStringRef env resolution + enum guard",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
8
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 10,
|
||||
"subject": "Task 10: SqlDriverProbe (SELECT 1 liveness)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
4,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 11,
|
||||
"subject": "Task 11: Host registration \u2014 DriverTypeNames.Sql + factory + probe + guard test",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
9,
|
||||
10
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 12,
|
||||
"subject": "Task 12: Scaffold Driver.Sql.Browser project + register in slnx",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
3
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 13,
|
||||
"subject": "Task 13: SqlBrowseSession \u2014 schema walk over dialect catalog",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
4,
|
||||
12,
|
||||
6
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 14,
|
||||
"subject": "Task 14: SqlDriverBrowser \u2014 env-ref/literal transient-connection open",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
13
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 15,
|
||||
"subject": "Task 15: AdminUI browser DI + SqlAddressPickerBody.razor",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
14
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 16,
|
||||
"subject": "Task 16: Env-gated central-SQL integration fixture + read round-trip",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
8
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 17,
|
||||
"subject": "Task 17: Injection regression test (bind value / reject identifier)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
7
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 18,
|
||||
"subject": "Task 18: Blackhole/timeout live-gate on a dedicated mssql container",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
16
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 19,
|
||||
"subject": "Task 19: AdminUI typed Sql tag-config model + validator (string enums)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
1,
|
||||
11
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 20,
|
||||
"subject": "Task 20: SqlTagConfigEditor.razor shell",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
19
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": 21,
|
||||
"subject": "Task 21: Live /run verification on docker-dev (picker + editor + deploy + read)",
|
||||
"status": "completed",
|
||||
"blockedBy": [
|
||||
11,
|
||||
15,
|
||||
20
|
||||
]
|
||||
}
|
||||
],
|
||||
"lastUpdated": "2026-07-24"
|
||||
"lastUpdated": "2026-07-27",
|
||||
"closureNote": "Merged 4ad54037 + follow-ups 28c28667. Marked complete 2026-07-27 (deferment.md \u00a78.5)."
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user