chore(plan): mark Galaxy handle-sharing tasks complete + live gate results
v2-ci / build (push) Failing after 43s
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-18 04:35:14 -04:00
parent 15922d8483
commit 8480e301ab
@@ -4,14 +4,19 @@
"designCommit": "c85c4e5c",
"baseMaster": "70e1bde9",
"branch": "feat/galaxy-writer-handle-sharing",
"scope": "Galaxy writer borrows live MXAccess item handles from the SubscriptionRegistry so the first write to an already-subscribed tag skips a redundant AddItem round-trip. T1: SubscriptionRegistry.TryResolveItemHandle forward fullRef->handle lookup with a liveness guard. T2: writer optional Func<string,int?> subscribedHandleSource + TryResolveCachedOrBorrowed seam (borrowed handles NOT cached) + AddItemCallCount seam. T3: GalaxyDriver wires _subscriptions.TryResolveItemHandle into the production writer ctor. T4: skip-gated live-gw smoke proving a subscribed-tag write commits with AddItemCallCount==0 (control: ==1). NO Commons/proto/EF/migration change; NO bUnit; AdminUI untouched.",
"scope": "Galaxy writer borrows live MXAccess item handles from the SubscriptionRegistry so the first write to an already-subscribed tag skips a redundant AddItem round-trip. NO Commons/proto/EF/migration change; NO bUnit; AdminUI untouched.",
"dependencyGraph": "{T1 ∥ T2} -> T3 -> T4",
"tasks": [
{"id": 1, "subject": "SubscriptionRegistry.TryResolveItemHandle forward lookup + tests", "classification": "small", "status": "pending", "parallelizableWith": [2], "files": ["src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/Runtime/SubscriptionRegistry.cs", "tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/SubscriptionRegistryHandleResolveTests.cs"]},
{"id": 2, "subject": "Writer borrow seam + AddItemCallCount + tests", "classification": "small", "status": "pending", "parallelizableWith": [1], "files": ["src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/Runtime/GatewayGalaxyDataWriter.cs", "tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GatewayGalaxyDataWriterTests.cs"]},
{"id": 3, "subject": "Wire registry resolver into the production writer in GalaxyDriver", "classification": "small", "status": "pending", "blockedBy": [1, 2], "files": ["src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/GalaxyDriver.cs"]},
{"id": 4, "subject": "Live-gw borrow smoke + build/test + live run + finish", "classification": "small", "status": "pending", "blockedBy": [3], "files": ["tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Tests/Runtime/GatewayGalaxyLiveReopenAndWriteTests.cs"]}
{"id": 1, "subject": "SubscriptionRegistry.TryResolveItemHandle forward lookup + tests", "classification": "small", "status": "completed", "commit": "14119500 (+ review fix e9da9c29)", "review": "Bundle code-review (sonnet) APPROVE-WITH-MINOR. IMPORTANT finding (cross-ref-same-handle could borrow the wrong tag's handle) FIXED — but NOT via the reviewer's suggested 'unconditional remove' (which would have regressed the legitimate multiple-subscriptions-per-tag borrow). Instead made TryResolveItemHandle AUTHORITATIVE: it confirms a live subscription genuinely binds fullRef->handle via the per-entry reverse index, so a stale forward entry can never hand out a dead/wrong handle, AND a tag stays resolvable while any subscription still binds it. Added cross-ref + same-ref-multi-sub tests (both green; the same-ref test would have failed the reviewer's fix). Dropped a pre-existing duplicate SubscriptionEntry <summary> (MINOR)."},
{"id": 2, "subject": "Writer borrow seam + AddItemCallCount + tests", "classification": "small", "status": "completed", "commit": "2e3f528a (+ doc note e9da9c29)", "review": "Bundle-reviewed. Optional last ctor param Func<string,int?>? subscribedHandleSource (default null = unchanged behavior); TryResolveCachedOrBorrowed (borrowed handle NOT cached in _itemHandles — registry owns its lifecycle, self-heals on reconnect); AddItemCallCount seam (Interlocked/Volatile). Documented the supervisory-advise reconnect lifecycle (MINOR). 5 unit tests. NOTE: T1+T2 implementers ran concurrently on a SHARED tree and raced on the git index — commit boundaries got misattributed (14119500 wrongly bundled T2's writer code; 2e3f528a has the tail). Final tree at HEAD is coherent + verified; boundary cosmetics don't affect the ff-merge artifact."},
{"id": 3, "subject": "Wire registry resolver into the production writer in GalaxyDriver", "classification": "small", "status": "completed", "commit": "3ffe45db", "review": "Inline (3-line wiring) to avoid another shared-tree race; passes _subscriptions.TryResolveItemHandle as the writer's 4th ctor arg at GalaxyDriver.cs:255. Build clean; full Galaxy suite green."},
{"id": 4, "subject": "Live-gw borrow smoke + build/test + live run + finish", "classification": "small", "status": "completed", "commit": "15922d84", "review": "Inline test (keeps secret-handling + gate interpretation with the parent). New skip-gated [Fact] subscribes WriteRef, registers its real gateway handle, writes via the registry-wired writer.",
"live": "LIVE GATE PASS — sourced GALAXY_MXGW_API_KEY from container otopcua-dev-central-1-1 WITHOUT echoing; ran filter GatewayGalaxyLiveReopenAndWrite vs MXGW_ENDPOINT=http://10.100.0.48:5120 -> 3/3 passed (59s): the 2 existing reopen/write smokes + the new borrow smoke. The borrow smoke's own assertions (borrowed write Good 0 + AddItemCallCount==0; control AddItemCallCount==1) passed, proving BOTH the load-bearing premise (a subscription handle is usable for a committing no-login supervisory write) AND the optimization (zero AddItem on the borrow path)."}
],
"executionState": "COMPLETE — Driver.Galaxy 294/294 unit green; full solution build 0 errors; live gate 3/3 PASS. Pending merge to master + push.",
"reviewFollowUps": [
"PROCESS: parallel implementers on a SHARED (non-worktree) working tree race on the git index + build even when their target FILES are disjoint — T1's build saw T2's half-applied edit (transient CS0649) and T1's `git add` snapshotted T2's in-progress writer code into the wrong commit. For future parallel dispatch of disjoint-file tasks, use isolation:'worktree' OR dispatch serially. Final tree was verified coherent here, but the commit boundaries are misattributed.",
"Deferred (design): reverse direction (subscriber borrowing the writer's AddItem handles) — not needed; subscriber handles come from SubscribeBulk."
],
"executionState": "PENDING — subagent-driven execution, this session.",
"lastUpdated": "2026-06-18"
}