diff --git a/docs/plans/2026-11-10-opcua-sdk-2-evidence.md b/docs/plans/2026-11-10-opcua-sdk-2-evidence.md index 43537f84..5648321b 100644 --- a/docs/plans/2026-11-10-opcua-sdk-2-evidence.md +++ b/docs/plans/2026-11-10-opcua-sdk-2-evidence.md @@ -520,3 +520,32 @@ G4 resource/performance acceptance remain unresolved.** #799, #800, #801 and ScadaBridge#121 stay open. Neither an SDK version substitution, production crypto/ session-factory workaround, resource-cap waiver nor warmed acceptance baseline was approved. SDK2 remains on draft PR#802; it is not merged to master or deployed. + +## Follow-on #799 close ownership and native attribution + +The [candidate bounded close control](evidence/2026-11-10-opcua2/close-ownership-candidate.md) +at `564f1091` passed with one abandoned browse and six abandoned history points. +Old authentication returns exactly BadSessionIdInvalid; old continuation tokens +are rejected without a history-backend read while fresh-session positives work. +All 23 old-object weak targets collect with the same host still running; all 13 +application/server/manager/core/store targets collect after normal shutdown. +SDK2's stronger `(0,0)` closed-list check, two manager-disposal checks, empty +caches and zero PKI descriptors remain enforced. Astra verified the actual TRX. +Six affected history tests also pass; their original launcher mistakenly expected +seven, and the retained false guard receipt has a separate independently reviewed +six-test source/TRX correction. No failed test was relabelled or rerun for that fix. + +The [fixed macOS store-versus-registry control](../../scripts/validation/opcua-lifecycle-memory/native-retention/README.md) +completed its execution/ownership checks, **not native-retention acceptance**. +Two hundred configured-store acquisitions leave AppleDatabase inventory 3→203; +registry AddRefs remain 3→3. After normal disposal and five seconds idle, both +arms have zero SDK certificate owners, runtime-tracked temporary keychains, +temporary-keychain files, keychain descriptors and PKI descriptors. The installed +runtime calls CFRelease after native deletion; a missing managed release is not +indicated. Native ownership/delete status, complete RSS attribution and a supported +mitigation remain unresolved. Registry substitution would change deliberate +configured-store replacement semantics and was not adopted. + +These results leave the original cold RSS failures and #799/G4 unchanged. The +[prospective resolution procedure](../../scripts/validation/opcua-lifecycle-memory/RESOLUTION.md) +is explicitly a design draft, not approval to launch a warmed acceptance run. diff --git a/docs/plans/evidence/2026-11-10-opcua2/close-ownership-candidate.json b/docs/plans/evidence/2026-11-10-opcua2/close-ownership-candidate.json new file mode 100644 index 00000000..cbee8c99 --- /dev/null +++ b/docs/plans/evidence/2026-11-10-opcua2/close-ownership-candidate.json @@ -0,0 +1,1561 @@ +{ + "scope": "Bounded candidate wire-close and weak-root diagnostic only; not process-memory parity or G4 acceptance.", + "acceptance": false, + "platform": "macOS ARM64; installed Microsoft.NETCore.App 10.0.14", + "source": "564f10914357fc34db303b2faf030907663e6779", + "build": { + "warnings": 0, + "errors": 0, + "rawLogSha256": "6e3f82bfd84125c74dd59635dd3027b588e9ca307eb5437428af0e6105b2b14f" + }, + "resolvedSdkPackages": [ + "OPCFoundation.NetStandard.Opc.Ua.Client/2.0.1", + "OPCFoundation.NetStandard.Opc.Ua.Configuration/2.0.1", + "OPCFoundation.NetStandard.Opc.Ua.Core/2.0.1", + "OPCFoundation.NetStandard.Opc.Ua.Core.Schema/2.0.1", + "OPCFoundation.NetStandard.Opc.Ua.Core.Types/2.0.1", + "OPCFoundation.NetStandard.Opc.Ua.Security.Certificates/2.0.1", + "OPCFoundation.NetStandard.Opc.Ua.Server/2.0.1", + "OPCFoundation.NetStandard.Opc.Ua.Types/2.0.1" + ], + "currentBuildHashes": { + "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.dll": "90ba3aec2829db3461feec7f09b1dea842033ca15661b026e4aad1f1ec3286cd", + "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.deps.json": "0a2d8fe68bdd599e7670a6e12aec0d51820a3707e32cd49242811f9e79f9a7c1", + "Opc.Ua.Client.dll": "620da406fabdbc75d11f9827ea7e39d2d3c762471bd2264b0d11f1d6cd9247cd", + "Opc.Ua.Configuration.dll": "6ed6a594c93c3ff35d1a16539a9fe87c1e2640549cc2f48ed6bae333dc8bf0e7", + "Opc.Ua.Core.Schema.dll": "51cfad48657d95d38074bb88be29aea6f5b361a07397247d58838d066b99772e", + "Opc.Ua.Core.Types.dll": "a7dd141b8dabe8848ff28c2fb8e16a85a0508e6a49e6b1a1c1e267175b99af96", + "Opc.Ua.Core.dll": "9d0857aa6b7f3c49037d4ea557b4da8edf07e146069464481783e66c5c9cd35a", + "Opc.Ua.Security.Certificates.dll": "7f4969aceb2f0db5328c6882cb4b117342f3b18905c38acdba600683860c4fd0", + "Opc.Ua.Server.dll": "930e714a2f6e15d393840bcdc95e1afa8012bc740c3738a655f958142721864e", + "Opc.Ua.Types.dll": "c542f69882f4e8a4ebd5ccc28a3881d6967c7ffb6dcc3c56dc6c776f39c2ede1" + }, + "runs": [ + { + "source": "b5986c61d9671cb8144b8c601e13af450384f9f4", + "rawDirectory": "artifacts/opcua2/b5986c61/close-control1", + "command": [ + "dotnet", + "test", + "tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj", + "-c", + "Release", + "--no-build", + "--no-restore", + "--filter", + "FullyQualifiedName~Closed_tokens_are_rejected_and_ownership_is_observed_without_harness_roots", + "--logger", + "trx;LogFileName=close.trx", + "--results-directory", + "artifacts/opcua2/b5986c61/close-control1" + ], + "runnerSeconds": 10.09532391699031, + "testExit": 0, + "originalLauncherGuardPassed": true, + "counters": { + "total": "1", + "executed": "1", + "passed": "1", + "failed": "0", + "error": "0", + "timeout": "0", + "aborted": "0", + "inconclusive": "0", + "passedButRunAborted": "0", + "notRunnable": "0", + "notExecuted": "0", + "disconnected": "0", + "warning": "0", + "completed": "0", + "inProgress": "0", + "pending": "0" + }, + "tests": [ + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Closed_tokens_are_rejected_and_ownership_is_observed_without_harness_roots", + "outcome": "Passed", + "duration": "00:00:08.6625135" + } + ], + "observations": [ + { + "phase": "observer-controls", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + } + ], + "acceptance": false + }, + { + "phase": "wire-contract", + "observation": { + "oldAuthStatus": 2149908480, + "oldBrowseRejected": true, + "oldHistoryRejected": true, + "freshPositiveRounds": 2 + }, + "acceptance": false + }, + { + "phase": "closed-objects-same-host-live", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + } + ], + "acceptance": false + }, + { + "phase": "sdk2-disposal-proofs", + "observation": { + "managersDisposed": 2, + "cachedStores": 0, + "pkiDescriptors": 0 + }, + "acceptance": false + }, + { + "phase": "after-normal-host-stop", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + } + ], + "acceptance": false + } + ], + "rawHashes": { + "close.trx": "63fe3d0cc3e1cb7864d50b1e9a1228d475311fe5193f20e754e6c869e7fd6dda", + "run.log": "fd583e9a5e0b865ebed57453d0c50bd7270f928040c7cd2411ef1ad2ef640054", + "receipt.json": "d9b6edbe199e5d228fb8bf71bad4343865dc8140d232f50100e1558f97bbe71a" + } + }, + { + "source": "6737e367b4de14bc90db36537a60de6cf76f9e56", + "rawDirectory": "artifacts/opcua2/6737e367/close-control1", + "command": [ + "dotnet", + "test", + "tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj", + "-c", + "Release", + "--no-build", + "--no-restore", + "--filter", + "FullyQualifiedName~Closed_tokens_are_rejected_and_ownership_is_observed_without_harness_roots", + "--logger", + "trx;LogFileName=close.trx", + "--results-directory", + "artifacts/opcua2/6737e367/close-control1" + ], + "runnerSeconds": 10.09567029203754, + "testExit": 0, + "originalLauncherGuardPassed": true, + "counters": { + "total": "1", + "executed": "1", + "passed": "1", + "failed": "0", + "error": "0", + "timeout": "0", + "aborted": "0", + "inconclusive": "0", + "passedButRunAborted": "0", + "notRunnable": "0", + "notExecuted": "0", + "disconnected": "0", + "warning": "0", + "completed": "0", + "inProgress": "0", + "pending": "0" + }, + "tests": [ + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Closed_tokens_are_rejected_and_ownership_is_observed_without_harness_roots", + "outcome": "Passed", + "duration": "00:00:08.6956271" + } + ], + "observations": [ + { + "phase": "observer-controls", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + } + ], + "acceptance": false + }, + { + "phase": "wire-contract", + "observation": { + "oldAuthStatus": 2149908480, + "oldBrowseRejected": true, + "oldHistoryRejected": true, + "freshPositiveRounds": 2 + }, + "acceptance": false + }, + { + "phase": "closed-objects-same-host-live", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false + ] + } + ], + "acceptance": false + }, + { + "phase": "sdk2-disposal-proofs", + "observation": { + "managersDisposed": 2, + "cachedStores": 0, + "pkiDescriptors": 0 + }, + "acceptance": false + }, + { + "phase": "after-normal-host-stop", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + } + ], + "acceptance": false + } + ], + "rawHashes": { + "close.trx": "b39e2021457c6c8ac63ebfaa977a91140dda81e063ad9c5417d506f575f3fccb", + "run.log": "7a56d93d2b3fc970f528dfbe87084c3070253039e63d5151884c2079d3404281", + "receipt.json": "72dbe62639a676ea49d759f77324b867287539d019b17e81d13231961b25529b" + } + }, + { + "source": "6737e367b4de14bc90db36537a60de6cf76f9e56", + "rawDirectory": "artifacts/opcua2/6737e367/history-controls1", + "command": [ + "dotnet", + "test", + "tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj", + "-c", + "Release", + "--no-build", + "--no-restore", + "--filter", + "FullyQualifiedName~SessionHistoryContinuationLifecycleTests|FullyQualifiedName~EventHistoryPagingOverTheWireTests", + "--logger", + "trx;LogFileName=close.trx", + "--results-directory", + "artifacts/opcua2/6737e367/history-controls1" + ], + "runnerSeconds": 4.582723709056154, + "testExit": 0, + "originalLauncherGuardPassed": false, + "counters": { + "total": "6", + "executed": "6", + "passed": "6", + "failed": "0", + "error": "0", + "timeout": "0", + "aborted": "0", + "inconclusive": "0", + "passedButRunAborted": "0", + "notRunnable": "0", + "notExecuted": "0", + "disconnected": "0", + "warning": "0", + "completed": "0", + "inProgress": "0", + "pending": "0" + }, + "tests": [ + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.SessionHistoryContinuationLifecycleTests.Tokens_are_single_use_and_cannot_cross_sessions", + "outcome": "Passed", + "duration": "00:00:00.5485700" + }, + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.SessionHistoryContinuationLifecycleTests.Session_capacity_evicts_the_oldest_point_and_keeps_the_newest", + "outcome": "Passed", + "duration": "00:00:00.5558951" + }, + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.EventHistoryPagingOverTheWireTests.A_capped_event_read_pages_through_the_session_store_exactly_once", + "outcome": "Passed", + "duration": "00:00:01.9770131" + }, + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.SessionHistoryContinuationLifecycleTests.Release_consumes_a_token_and_malformed_tokens_are_rejected", + "outcome": "Passed", + "duration": "00:00:00.4246960" + }, + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.EventHistoryPagingOverTheWireTests.A_capped_REVERSE_event_read_pages_newest_first_through_the_session_store_exactly_once", + "outcome": "Passed", + "duration": "00:00:00.4611169" + }, + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.SessionHistoryContinuationLifecycleTests.Closed_session_tokens_do_not_resume_on_a_new_session", + "outcome": "Passed", + "duration": "00:00:01.9770142" + } + ], + "observations": [], + "rawHashes": { + "close.trx": "835e2afc887d0825851768a2cf360daa6cacdcb2ca22ccb1ef2ef0364d60b07f", + "run.log": "660484a5a3a4dda183ca7be2b02badedcede1ac2e387902a108c78fc9fa8f1d7", + "receipt.json": "20465a767bc65b746df6c886bc5b2e7bd225447886a2289d555fb109f3f46f16", + "guard-review.json": "f6d2dd14d77a017cd4f4b8cc827977fdf0c6bda8588f43bc5ccf7872d88258f1" + }, + "guardReview": { + "correction": "Launcher mistakenly expected 7 tests; source inventory is 4 + 2 = 6. Original receipt retained; tests not rerun.", + "expectedExecuted": 6, + "actualExecuted": 6, + "passed": 6, + "testExit": 0, + "guardReviewPassed": true, + "trxSha256": "835e2afc887d0825851768a2cf360daa6cacdcb2ca22ccb1ef2ef0364d60b07f", + "originalReceiptSha256": "20465a767bc65b746df6c886bc5b2e7bd225447886a2289d555fb109f3f46f16" + } + }, + { + "source": "564f10914357fc34db303b2faf030907663e6779", + "rawDirectory": "artifacts/opcua2/564f1091/close-control1", + "command": [ + "dotnet", + "test", + "tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj", + "-c", + "Release", + "--no-build", + "--no-restore", + "--filter", + "FullyQualifiedName~Closed_tokens_are_rejected_and_ownership_is_observed_without_harness_roots", + "--logger", + "trx;LogFileName=close.trx", + "--results-directory", + "artifacts/opcua2/564f1091/close-control1" + ], + "runnerSeconds": 10.082330790930428, + "testExit": 0, + "originalLauncherGuardPassed": true, + "counters": { + "total": "1", + "executed": "1", + "passed": "1", + "failed": "0", + "error": "0", + "timeout": "0", + "aborted": "0", + "inconclusive": "0", + "passedButRunAborted": "0", + "notRunnable": "0", + "notExecuted": "0", + "disconnected": "0", + "warning": "0", + "completed": "0", + "inProgress": "0", + "pending": "0" + }, + "tests": [ + { + "name": "ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Closed_tokens_are_rejected_and_ownership_is_observed_without_harness_roots", + "outcome": "Passed", + "duration": "00:00:08.6284002" + } + ], + "observations": [ + { + "phase": "observer-controls", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "retained-control", + "collectible-control" + ], + "Alive": [ + true, + false + ] + } + ], + "acceptance": false + }, + { + "phase": "wire-contract", + "observation": { + "oldAuthStatus": 2149908480, + "oldBrowseRejected": true, + "oldHistoryRejected": true, + "abandonedBrowse": 1, + "abandonedHistory": 6, + "freshPositiveRounds": 2 + }, + "acceptance": false + }, + { + "phase": "closed-objects-same-host-live", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "closed-client-session", + "closed-server-session", + "closed-point-owner", + "m_browse", + "browse-data", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state", + "m_history", + "history-value", + "history-state" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + } + ], + "acceptance": false + }, + { + "phase": "sdk2-disposal-proofs", + "observation": { + "managersDisposed": 2, + "cachedStores": 0, + "pkiDescriptors": 0 + }, + "acceptance": false + }, + { + "phase": "after-normal-host-stop", + "observation": [ + { + "Collection": 1, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 2, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 3, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 4, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + }, + { + "Collection": 5, + "Kinds": [ + "client-application", + "client-config", + "client-manager", + "server-manager", + "server-application", + "server-rig", + "server", + "node-manager", + "event-source", + "certificate-validation-core", + "cached-store", + "certificate-validation-core", + "cached-store" + ], + "Alive": [ + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false, + false + ] + } + ], + "acceptance": false + } + ], + "rawHashes": { + "close.trx": "f06be545f11b45ae5b7bebaeb5e02dae7eda5c78b9ce48714400bb79e54694a4", + "run.log": "f5a11e31fe051355cd62c2c7e38398b9290971ce4bcfb9e52aefe4bdf0a3d293", + "receipt.json": "92a61306c81506b3a48a08e8650e2e87dc64fe8a5796eac7b1bf6437d3194c66" + } + } + ], + "review": "Astra reviewed each design/code gate before execution and independently verified all three close-control TRX files, the aligned 23/13 weak-target results and the corrected six-test history inventory.", + "limitations": [ + "First source permitted BadSessionIdInvalid or BadSessionClosed; final source requires observed exact BadSessionIdInvalid.", + "Original-SDK close list equality is not used as a common cross-version contract.", + "xUnit host memory is not comparable with the standalone original adapter.", + "Managed weak collectibility does not resolve persistent native AppleDatabase inventory." + ] +} diff --git a/docs/plans/evidence/2026-11-10-opcua2/close-ownership-candidate.md b/docs/plans/evidence/2026-11-10-opcua2/close-ownership-candidate.md new file mode 100644 index 00000000..a40ec592 --- /dev/null +++ b/docs/plans/evidence/2026-11-10-opcua2/close-ownership-candidate.md @@ -0,0 +1,41 @@ +# Candidate close and weak-root control + +The final bounded control at `564f10914357fc34db303b2faf030907663e6779` +passed: one test executed, one passed, no skips; runner elapsed 10.082 seconds. +It creates one abandoned browse point and six abandoned history points through +the same encrypted canonical fixture helpers. Before close, the retained server +session has exactly `(1,6)` points; SDK2's stronger post-close `(0,0)` check remains. + +The old authentication token returns exactly `BadSessionIdInvalid` (`0x80250000`). +A fresh session rejects both old continuation tokens with +`BadContinuationPointInvalid`; invalid history does not call the historian. +Fresh reads and the session's own browse/history roundtrips succeed around the +denials, so a generally broken channel cannot satisfy this control. + +After the session helper and its completed async state machine leave the isolated +boundary, **all 23 old client/session/point/value/state targets are collectible +while the same server is still running**, in each of five fixed GC observations. +After normal host/application disposal and the fixture boundary, all 13 observed +application/configuration/manager/validation-core/store/server/node-manager/ +backend targets are collectible in every round. Independent retained/collectible +observer controls behave as expected. Both SDK2 certificate managers are disposed, +cached stores are empty and actual PKI descriptors are zero. + +Earlier one-history-point control receipts remain recorded: `b5986c61` passed +with the original two-status auth whitelist; `6737e367` passed after narrowing to +the observed exact status. Six affected history tests also passed at `6737e367`. +Their launcher mistakenly expected seven tests. The original false guard receipt +is retained; a separate source inventory and TRX review confirms four session +history tests plus two event-paging tests, all executed/passed. No seventh source +test is missing and the tests were not rerun to correct that bookkeeping error. + +[Machine-readable observations, commands and raw hashes](close-ownership-candidate.json) +retain all four executions. The current build has zero warnings/errors. Astra +reviewed the design and actual code before each diagnostic execution; it verified +all three close-control TRX files, the aligned 23/13 weak-target result and the +six-test inventory correction independently. + +This establishes bounded candidate close semantics and managed collectibility. +It does **not** establish full canonical operation/host parity with the original +standalone adapter, a steady RSS denominator, a resource-budget waiver, macOS +native-retention resolution or G4 acceptance. No production code changed.