chore(bit-rmw): mark all 5 tasks complete + live results + follow-ups
v2-ci / build (push) Failing after 38s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped

This commit is contained in:
Joseph Doherty
2026-06-17 12:14:56 -04:00
parent 098adf43d0
commit c402872c0c
@@ -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"
}