From c402872c0c03608ea0d9570f7880f42395cf781d Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Wed, 17 Jun 2026 12:14:56 -0400 Subject: [PATCH] chore(bit-rmw): mark all 5 tasks complete + live results + follow-ups --- ...-17-stillpending-bit-rmw-writes.md.tasks.json | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/docs/plans/2026-06-17-stillpending-bit-rmw-writes.md.tasks.json b/docs/plans/2026-06-17-stillpending-bit-rmw-writes.md.tasks.json index 56fe7643..6d757756 100644 --- a/docs/plans/2026-06-17-stillpending-bit-rmw-writes.md.tasks.json +++ b/docs/plans/2026-06-17-stillpending-bit-rmw-writes.md.tasks.json @@ -7,11 +7,17 @@ "scope": "Inbound bit-index RMW writes. AbLegacy: drop the B/I/O exclusion so B/I/O-file bit writes route through the existing WriteBitInWordAsync RMW (input-image write is device-gated, faithful status). TwinCAT: driver-level BOOL-within-word RMW in TwinCATDriver.WriteAsync (read parent as UDInt->uint, flip bit, write back, per-parent SemaphoreSlim) + remove the AdsTwinCATClient throw. Closes 2 stillpending.md §2 lines. NO Commons/wire/proto/EF change; NO bUnit. Live = fixture-gated/unit-proven.", "dependencyGraph": "{T1 ∥ T2} → T3 → T4 → T5 (T1 AbLegacy ∥ T2 TwinCAT touch disjoint projects)", "tasks": [ - {"id": 1, "subject": "AbLegacy B/I/O-file bit writes (drop the WriteBitInWordAsync exclusion) + tests", "classification": "standard", "status": "pending", "parallelizableWith": [2]}, - {"id": 2, "subject": "TwinCAT BOOL-within-word driver-level RMW (read/flip/write parent as UDInt, per-parent lock) + remove client throw + tests", "classification": "standard", "status": "pending", "parallelizableWith": [1]}, - {"id": 3, "subject": "Docs (AbLegacy.md + TwinCAT.md) + plan-record §2 clear (do NOT stage stillpending.md)", "classification": "small", "status": "pending", "blockedBy": [1, 2]}, - {"id": 4, "subject": "Full build + AbLegacy + TwinCAT tests + final integration review", "classification": "standard", "status": "pending", "blockedBy": [3]}, - {"id": 5, "subject": "Live /run best-effort (fixture-gated) + finish branch (merge to master + push) + memory", "classification": "standard", "status": "pending", "blockedBy": [4]} + {"id": 1, "subject": "AbLegacy B/I/O-file bit writes (drop the WriteBitInWordAsync exclusion) + tests", "classification": "standard", "status": "completed", "commit": "5c6b7cd6", "reviewFixCommit": "c48f2999", "review": "spec ✅; code APPROVE. Drop-the-exclusion routes B/I/O (16-bit Int parent) through the unchanged WriteBitInWordAsync; T/C/R can't reach (parser rejects subElement+bitIndex). Review-fix c48f2999 added a device-rejection-status test via a test-only WriteStatusOverride hook on FakeAbLegacyTag (read stays Good, write returns ErrorTimeout→BadTimeout)."}, + {"id": 2, "subject": "TwinCAT BOOL-within-word driver-level RMW (read/flip/write parent as UDInt, per-parent lock) + remove client throw + tests", "classification": "standard", "status": "completed", "commit": "a73e20fb", "reviewFixCommit": "340c145e", "review": "spec ✅; code APPROVE. Driver-level RMW (fake-testable; real AdsClient non-injectable). Review-fix 340c145e: dispose+clear _bitRmwLocks on ShutdownAsync+Dispose; null-parent-after-Good guard → BadCommunicationError (was silently zeroing the word). Removed the AdsTwinCATClient throw."}, + {"id": 3, "subject": "Docs (AbLegacy.md + TwinCAT.md) + plan-record §2 clear (do NOT stage stillpending.md)", "classification": "small", "status": "completed", "commit": "56ccaa79", "review": "code ✅ accurate, no overclaim (single-bit BOOL-within-word only)."}, + {"id": 4, "subject": "Full build + AbLegacy + TwinCAT tests + final integration review", "classification": "standard", "status": "completed", "reviewFixCommit": "098adf43", "review": "build 0 errors; AbLegacy 195, TwinCAT 159 green. Final integration review = SHIP, all 6 checks PASS. Closed its one Important follow-up (098adf43): AbLegacy DeviceState._rmwLocks (+_creationLocks/_runtimeLocks) now disposed+cleared in DisposeRuntimes() with a reinit regression test — symmetry with the TwinCAT fix."}, + {"id": 5, "subject": "Live /run best-effort (fixture-gated) + finish branch (merge to master + push) + memory", "classification": "standard", "status": "completed", "live": "AbLegacy LIVE-PROVEN ON THE WIRE vs a local ab_server SLC500 sim (built from the AbLegacy.IntegrationTests/Docker fixture, --plc=SLC500 --tag=B3[10], localhost:44818) via the AbLegacy CLI (same AbLegacyDriver codec, gateway ab://localhost:44818/1,0): zeroed B3:0 → set B3:0/0 → set B3:0/3 → read word=9 (0b1001, RMW set preserved bit 0) → read B3:0/3=true → clear B3:0/0 → read word=8 (0b1000, RMW clear preserved bit 3); all Good 0x0. Pre-branch the first B3:0/0 bit write was BadNotSupported. TwinCAT live stays OPERATOR-GATED (no local ADS runtime — Windows-only); unit-proven (159)."} + ], + "executionState": "COMPLETE — merged to master + pushed. AbLegacy B/I/O bit writes (drop exclusion → existing RMW) + TwinCAT BOOL-within-word driver-level RMW shipped. Build 0 errors; AbLegacy 195, TwinCAT 159 green. AbLegacy B-file bit RMW LIVE-PROVEN on the wire vs a local ab_server SLC500 sim (set/clear/preserve compose); TwinCAT unit-proven (operator-gated live). NO contract/wire/proto/EF change.", + "reviewFollowUps": [ + "AbLegacy I/O-image (I/O-file) bit writes are enabled but device-gated (the PLC may reject an Input-image write) — unit-proven; not exercised live (ab_server SLC500 seeds no I/O image files, only N/B/F/L). Confirm against a real SLC/MicroLogix.", + "TwinCAT BOOL-within-word live /run is OPERATOR-GATED — needs a real TwinCAT/ADS target (Windows-only runtime); unit-proven only.", + "Both: the per-parent RMW lock serialises the driver's own bit-writers but cannot guard against the PLC program writing the same word mid-RMW (inherent to RMW; documented)." ], "lastUpdated": "2026-06-17" }