Compare commits

...

19 Commits

Author SHA1 Message Date
Joseph Doherty 38098ce142 test: add isolated Linux server lifecycle soak launcher 2026-11-10 13:08:44 -05:00
Joseph Doherty 74c938f37c Merge commit '642aefe3' into codex/opcua2-client-lifecycle 2026-11-10 13:01:14 -05:00
Joseph Doherty c25561c64d test: add production client lifecycle soak harness 2026-11-10 12:41:51 -05:00
Joseph Doherty 642aefe35a test: bound and canonicalize lifecycle descriptor probes 2026-11-10 12:40:41 -05:00
Joseph Doherty 7b353d7bae test: record cross-version wire compatibility and warmed metrics 2026-11-10 12:26:54 -05:00
Joseph Doherty bd3143b7d7 fix(client): use default certificate lifetime without rotating persisted keys 2026-11-10 12:26:54 -05:00
Joseph Doherty 2d75cecbb9 test: add isolated cross-version application compatibility harness 2026-11-10 12:18:46 -05:00
Joseph Doherty 41e65f6a22 fix(opcua): restore alarm component reference after SDK creation 2026-11-10 12:14:35 -05:00
Joseph Doherty 8be3bb1734 test(opcua): measure soak observation after startup 2026-11-10 12:14:35 -05:00
Joseph Doherty a456d598ab test(opcua): retain manager references across soak restart 2026-11-10 12:14:35 -05:00
Joseph Doherty 73ee3ef20d test(opcua): add opt-in lifecycle and resource soak harness 2026-11-10 12:14:35 -05:00
Joseph Doherty 1840b5ccf6 test: verify live history authority and secure peer reactivation 2026-11-10 11:53:34 -05:00
Joseph Doherty da50123a2c test: start service-level fixtures with authenticated SDK server 2026-11-10 11:52:09 -05:00
Joseph Doherty a76fca09f6 test: converge historian and runtime fixtures on SDK 2.0 2026-11-10 11:52:09 -05:00
Joseph Doherty 780f363f16 docs: document OPC UA 2.0 compatibility and rollout 2026-11-10 11:48:19 -05:00
Joseph Doherty 2541ef39f7 test: exercise baseline aggregate vectors through runtime registration 2026-11-10 11:46:29 -05:00
Joseph Doherty 6562022966 build: remove temporary OPC UA migration analyzer 2026-11-10 11:43:59 -05:00
Joseph Doherty dc9e777bff test: prove trusted channels PKI and scoped audit compatibility 2026-11-10 11:43:59 -05:00
Joseph Doherty ab25bd5318 test: preserve historian baseline oracles under SDK 2.0 2026-11-10 11:43:59 -05:00
135 changed files with 22314 additions and 4417 deletions
-1
View File
@@ -126,7 +126,6 @@
provider that breaks the "managed only" rule, which is why it is opt-in per instance. -->
<PackageVersion Include="System.Data.Odbc" Version="10.0.14" />
<PackageVersion Include="Novell.Directory.Ldap.NETStandard" Version="3.6.0" />
<PackageVersion Include="OPCFoundation.NetStandard.Opc.Ua.MigrationAnalyzer" Version="2.0.1" />
<PackageVersion Include="OPCFoundation.NetStandard.Opc.Ua.Client" Version="2.0.1" />
<!-- Core carries Opc.Ua.StatusCodes, the oracle StatusCodeParityTests checks the drivers'
hard-coded uint constants against. Referenced by that TEST project only — the drivers
+31
View File
@@ -22,6 +22,37 @@ Design references: [docs/plans/2026-06-14-galaxy-phase-c-historian-design.md](pl
---
## SDK 2.0.1 compatibility (#782)
The server targets exact OPC Foundation SDK **2.0.1**, replacing **1.5.378.182**.
The upgrade preserves existing application results, including the SQL backends'
documented divergences from the old SDK below. Live `AggregateFilter` calculations
use an application-private source port of the **37 legacy aggregate factories**,
registered through the public SDK aggregate manager; they do not adopt SDK 2's new
algorithms. Runtime and advertised aggregate defaults retain
`TreatUncertainAsBad=false`. History backend capability sets remain separate from
the live aggregate set; no backend gains aggregates or history operations through
this upgrade.
The isolated [original-SDK oracle](../scripts/validation/opcua-aggregate-baseline/README.md)
generates **6,144 vectors** using the published 1.5.378.182 package, covering value
kinds, statuses, timestamps/picoseconds, reverse reads and edge configurations.
These are expected-output fixtures, not a claim that release validation passed.
The candidate never loads the old SDK binary. Older references below to "the SDK"
as an aggregate oracle mean that preserved baseline, rather than SDK 2's algorithms.
SDK FILETIME-zero timestamps are translated back to the application's existing CLR
unset-time sentinel at history boundaries. Opaque history continuation points remain
session-owned, node/topology-bound and subject to current authorization; reconnect or
rollback requires a fresh read. Request cancellation flows to the backend. No
ConfigDb migration is planned; actual schema and serialization effects must be
recorded at the [rollout gate](plans/2026-11-10-opcua-sdk-2-rollout.md).
`HistorianGateway.Client` and `HistorianGateway.Contracts` are already **0.4.0**
(on gateway master `16111a5e`, historiangw#119 closed). This package alignment is
separate from the real gateway validation tracked by historiangw#78; it is not
live AVEVA or backend-conformance evidence for SDK 2.
## Historized TagConfig schema
A tag is historized by setting the **Historize this tag** checkbox and optional **Historian
+70 -167
View File
@@ -1,185 +1,88 @@
# OPC UA Client test fixture
Coverage map + gap inventory for the OPC UA Client (gateway / aggregation)
driver.
This is the fixture and command map for the driver/browser upgrade from SDK
**1.5.378.182** to exact **2.0.1** (#782). It describes available tests; execution,
counts, skips and release decisions belong in [#782](https://gitea.dohertylan.com/dohertj2/lmxopcua/issues/782)
and the linked [execution evidence](../plans/2026-11-10-opcua-sdk-2-evidence.md).
A listed test or historical run is not candidate release evidence.
**TL;DR:** Wire-level coverage now exists via
[opc-plc](https://github.com/Azure-Samples/iot-edge-opc-plc) — Microsoft
Industrial IoT's OPC UA PLC simulator running in Docker (task #215). Real
Secure Channel, real Session, real MonitoredItem exchange against an
independent server implementation. Unit tests still carry the exhaustive
capability matrix (cert auth / security policies / reconnect / failover /
attribute mapping). Gaps remaining: upstream-server-specific quirks
(historian aggregates, typed ConditionType events, SDK-publish-queue edge
behavior under load) — opc-plc uses the same OPCFoundation stack internally
so fully-independent-stack coverage needs `open62541/open62541` as a second
image (follow-up).
## Fixture layers
## What the fixture is
| Layer | Repository location | Scope and limitation |
|---|---|---|
| Driver unit | `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests/` | Faked session contracts: lifecycle/generations, value conversion, per-item errors, policy selection, credentials, namespace remapping, subscription cleanup, discovery, alarms and host-owned reinitialization. No real secure channel. |
| Browser unit | `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/` | Browse attributes/pagination and certificate-identity ownership, including failure cleanup. No external server. |
| In-process wire | `tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/` | Real driver against OtOpcUa: `OpcUaClientDriverWireTests`, `OpcUaClientDriverStallWireTests`, `OpcUaClientDriverReconnectWireTests`. Real channels but both sides use this repository's SDK. |
| External simulator | `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/` | `OpcUaClientSmokeTests`: real read, varied-type batch read and subscription against opc-plc. Does not prove all upstream products, secured authentication, write or alarm compatibility. |
| Browser integration | `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.IntegrationTests/` | Separate fixture-backed browser tests; inspect fixture availability and individual results. |
**Integration layer** (task #215):
`tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/` stands up
`mcr.microsoft.com/iotedge/opc-plc:2.14.10` via `Docker/docker-compose.yml`
on `opc.tcp://10.100.0.35:50000` (the shared Docker host; override via
`OPCUA_SIM_ENDPOINT`). `OpcPlcFixture` probes the port at
collection init + skips tests with a clear message when the container's
not running (matches the Modbus/pymodbus + S7/python-snap7 skip pattern).
Docker is the launcher — no PowerShell wrapper needed because opc-plc
ships pre-containerized. Compose-file flags: `--ut` (unsecured transport
advertised), `--aa` (auto-accept client certs — opc-plc's cert trust store
resets on each spin-up), `--alm` (alarm simulation for IAlarmSource
follow-up coverage), `--pn=50000` (port).
The SDK 2 unit boundary cases include `OpcUaClientSdkValueBoundaryTests` and
`OpcUaClientContinuationPointReleaseTests`. They preserve CLR value types and
null/empty buffers, reject unsupported matrix items without shifting batch results,
and release abandoned browse points. Certificate tests cover lifetime through
session close; unit mocks alone do not establish trust-chain interoperability.
**Unit layer**:
`tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests/` is still the primary
coverage. Tests inject fakes through the driver's construction path; the
OPCFoundation.NetStandard `Session` surface is wrapped behind an interface
the tests mock.
The in-process stall proxy holds bytes without closing the session, then resumes;
its hard-close case refuses connections. These exercise stale notification rejection,
quality transitions and explicit host reinitialization. The driver does not use
`SessionReconnectHandler` or `TransferSubscriptions`; historical transfer-based
coverage descriptions do not apply to the current lifecycle (#670/#676).
## What it actually covers
The driver has **no upstream HistoryRead capability** (#655). Its tags can be
recorded into the local server-wide historian; backend conformance and aggregate
oracles are documented in [Historian.md](../Historian.md).
### Integration (opc-plc Docker, task #215)
## Running locally
- `OpcUaClientSmokeTests.Client_connects_and_reads_StepUp_node_through_real_OPC_UA_stack` —
full Secure Channel + Session + `ns=3;s=StepUp` Read round-trip
- `OpcUaClientSmokeTests.Client_reads_batch_of_varied_types_from_live_simulator` —
batch Read of UInt32 / Int32 / Boolean; asserts `bool`-specific Variant
decoding to catch a common attribute-mapping regression
- `OpcUaClientSmokeTests.Client_subscribe_receives_StepUp_data_changes_from_live_server` —
real `MonitoredItem` subscription against `ns=3;s=FastUInt1` (ticks every
100 ms); asserts `OnDataChange` fires within 3 s of subscribe
Run from the repository root. Build first and use a fresh result directory for
**each** project. The [runbook](../plans/2026-11-10-opcua-sdk-2-rollout.md#verification-commands)
provides the result helper that preserves test exit status and rejects all-skipped
runs. For example, after defining that helper:
Wire-level surfaces verified: `IDriver` + `IReadable` + `ISubscribable` +
`IHostConnectivityProbe` (via the Secure Channel exchange).
```bash
opc_test tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests.csproj
opc_test tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.Tests.csproj
opc_test tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj
```
### In-process wire tests (no opc-plc)
The simulator compose file is
`tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/docker-compose.yml`.
It launches `mcr.microsoft.com/iotedge/opc-plc:2.14.10` with `--ut --aa --alm --pn=50000`.
Use the shared-host procedure in [infra/README.md](../../infra/README.md); coordinate
shared fixture use before restarting containers. These dev flags do not establish
production trust or secure-policy coverage.
`tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/OpcUaClientDriverWireTests` drives the real driver
against the in-process OtOpcUa server (`ServerEventRig`, authenticating with the rig's API-key credential):
read (+ missing node), write through the node-write gateway (+ read-only refusal, + failed-write revert),
subscribe/unsubscribe, host-status Running -> not-Running when the server stops, and discovery. These need
no Docker. There is no HistoryRead leg: the driver has no history capability (#655).
`OpcPlcFixture` probes `OPCUA_SIM_ENDPOINT` (default `opc.tcp://10.100.0.35:50000`)
and skips when unavailable. With an available, reserved fixture:
### Unit
```bash
export OPCUA_SIM_ENDPOINT=opc.tcp://10.100.0.35:50000
opc_test tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests.csproj
```
The surface is broad because `OpcUaClientDriver` is the richest-capability
driver in the fleet (it's a gateway for another OPC UA server, so it
mirrors the full capability matrix):
A nonzero suite count does not prove every required scenario ran: inspect individual
TRX results and record required skips separately. No tests were run by preparing
this documentation.
- `OpcUaClientDriverScaffoldTests` — `IDriver` lifecycle
- `OpcUaClientReadWriteTests` — read + write lifecycle
- `OpcUaClientSubscribeAndProbeTests` — monitored-item subscription + probe
state transitions
- `OpcUaClientDiscoveryTests` — `GetEndpoints` + endpoint selection
- `OpcUaClientAttributeMappingTests` — OPC UA node attribute → driver value
mapping
- `OpcUaClientSecurityPolicyTests` — `SignAndEncrypt` / `Sign` / `None`
policy negotiation contract
- `OpcUaClientCertAuthTests` — cert store paths, revocation-list config
- `OpcUaClientReconnectTests` — SDK reconnect hook + `TransferSubscriptions`
across the disconnect boundary
- `OpcUaClientFailoverTests` — primary → secondary session fallback per
driver config
- `OpcUaClientAlarmTests` — A&E severity bucket (1–1000 → Low / Medium /
High / Critical), subscribe / unsubscribe / ack contract
## Required compatibility evidence
Capability surfaces whose contract is verified: `IDriver`, `ITagDiscovery`,
`IReadable`, `IWritable`, `ISubscribable`, `IHostConnectivityProbe`,
`IAlarmSource`.
Release validation must identify both application builds and SDK versions, endpoint
policy, token kind, certificate chain, configuration and executed capabilities.
Use the baseline client against the candidate server and candidate client against
the baseline server, plus the actual ScadaBridge adapter and external upstreams.
For secured paths include trusted SignAndEncrypt, API-key allow/deny/revocation,
certificate rejection and restart/rebind. Apply only operations the peer implements;
a simulator need not implement OtOpcUa's API-key or historian contract.
## What it does NOT cover
For alarms verify typed EventFilter select clauses, result-field indexes, actual
ConditionType/SourceNode/EventId identity, refresh, acknowledgements and no replay
after an ambiguous transport failure. For all supported paths preserve existing
operation statuses, locale behavior and null/empty filter meaning. Constructing an
empty SDK 2 `ContentFilter` is an API adaptation, not evidence of a changed filter
contract. Record any stricter protocol response and consumer impact before acceptance.
### 1. Full real-stack exchange (unit tests only)
The **unit** suite mocks `Session.ReadAsync`, `Session.CreateSubscription`,
`Session.AddItem`, etc. — no UA Secure Channel is opened. The **integration**
suite (`OpcUaClientSmokeTests`, task #215) does open a real Secure Channel
against opc-plc and exercises Read + Subscribe end-to-end. What remains
untested even in the integration suite: certificate validation under
non-anonymous security policies, signing/encryption, nonce handling, chunk
assembly, keep-alive cadence — all SDK-internal.
### 2. Subscription transfer across reconnect
Contract test: "after a simulated reconnect, `TransferSubscriptions` is
called with the right handles." Real behavior: SDK re-publishes against the
new channel and some events can be lost depending on publish-queue state.
The lossy window is not characterized.
### 3. Large-scale subscription stress
100+ monitored items with heterogeneous publish intervals under a single
session — the shape that breaks publish-queue-size tuning in the wild — is
not exercised.
### 4. Real A&E events
Alarm subscription is mocked via filtered monitored items; the actual
`EventFilter` select-clause behavior against a server that exposes typed
ConditionType events (non-base `BaseEventType`) is not verified.
### 6. Authentication variants
- Anonymous, UserName/Password, X509 cert tokens — each is contract-tested
but not exchanged against a server that actually enforces each.
- LDAP-backed `UserName` (matching this repo's server-side
`LdapOpcUaUserAuthenticator`) requires a live LDAP round-trip; not tested.
## When to trust OpcUaClient tests, when to reach for a server
| Question | Unit tests | Integration (opc-plc) | Real upstream server |
| --- | --- | --- | --- |
| "Does severity 750 bucket as High?" | yes | - | yes |
| "Does the driver call `TransferSubscriptions` after reconnect?" | yes | - | yes |
| "Does a real OPC UA read round-trip work?" | no | yes | yes |
| "Does a real OPC UA subscribe deliver changes?" | no | yes | yes |
| "Does write round-trip work against a live server?" | no | no (not yet exercised) | yes (required) |
| "Does event-filter-based alarm subscription return ConditionType events?" | no | no | yes (required) |
| "Does history read from AVEVA Historian return correct aggregates?" | no | no | yes (required) |
| "Does the SDK's publish queue lose notifications under load?" | no | no | yes (stress) |
## Follow-up candidates
The easiest win here is to **wire the client driver tests against this
repo's own server**. The v2 integration test project
`tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/DualEndpointTests.cs`
(the v2 replacement for the retired v1 `OpcUaServerIntegrationTests`) already
stands up a real OPC UA server on a non-default port with a seeded
FakeDriver. An `OpcUaClientLiveLoopbackTests` that connects the client
driver to that server would give:
- Real Secure Channel negotiation
- Real Session / Subscription / MonitoredItem exchange
- Real read/write round-trip
- Real certificate validation (the integration test already sets up PKI)
It wouldn't cover upstream-server-specific quirks (AVEVA Historian, Kepware,
Prosys), but it would cover 80% of the SDK surface the driver sits on top
of.
Beyond that:
1. **Prosys OPC UA Simulation Server** — free, Windows-available, scriptable.
2. **UaExpert Server-Side Simulator** — Unified Automation's sample server;
good coverage of typed ConditionType events.
3. **Dedicated historian integration lab** — only path for
historian-specific coverage.
## Key fixture / config files
- `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests/` — unit tests with
mocked `Session`
- `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcPlcFixture.cs`
— collection fixture; parses `OPCUA_SIM_ENDPOINT` (default
`opc.tcp://10.100.0.35:50000`), TCP-probes at collection init, records
`SkipReason` when unreachable
- `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/OpcUaClientSmokeTests.cs`
— wire-level test suite (3 `[Fact]` methods: read, batch read, subscribe)
- `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.IntegrationTests/Docker/docker-compose.yml`
— `mcr.microsoft.com/iotedge/opc-plc:2.14.10` with `--ut --aa --alm --pn=50000`
- `src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient/OpcUaClientDriver.cs` — ctor +
session-factory seam tests mock through; implements `IAlarmSource`;
does NOT implement `IRediscoverable`
- `tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/DualEndpointTests.cs` —
the v2 dual-endpoint integration harness a future loopback client test could
piggyback on (v1 `OpcUaServerIntegrationTests.cs` retired with the v1 server project)
opc-plc uses the OPC Foundation stack too. Independent upstream behavior, secured
authentication variants, large publish queues, real alarm products, packet-loss
windows and performance require separate evidence. The rollout runbook links the
pending gates; no simulator run substitutes for ScadaBridge, live gateway, Windows,
Linux or mixed-version cluster validation.
+29 -3
View File
@@ -9,8 +9,9 @@ and for the test-harness map read [OpcUaClient-Test-Fixture.md](OpcUaClient-Test
A **remote OPC UA server**. This driver runs the *opposite* direction from the
usual "server exposes PLC data" flow: it acts as an OPC UA **client**, opens a
`Session` against an upstream server, and re-exposes that server's address space
through the local OtOpcUa server. Browse, read, write, subscribe, alarm, and
history calls are passed through to the upstream endpoint.
through the local OtOpcUa server. Browse, read, write, subscribe and alarm
operations use the upstream endpoint. HistoryRead uses the local server-wide
historian instead; see [History](#history-not-supported-gitea-655).
It is built on the OPC Foundation UA .NET Standard reference SDK and runs
in-process in the OtOpcUa server's .NET 10 AnyCPU host — pure managed, no
@@ -20,6 +21,31 @@ out-of-process isolation.
> a remote OPC UA endpoint by hand, point the general-purpose
> [Client CLI](../Client.CLI.md) at it directly.
## SDK 2.0.1 compatibility (#782)
The driver, shared session layer and AdminUI browser target exact SDK **2.0.1**
(previous **1.5.378.182**). Their existing abstractions and host-owned reconnect
lifecycle remain in place. SDK immutable values are detached at the boundary into
existing CLR scalars and one-dimensional arrays, preserving null/empty ByteStrings,
UTC timestamps, Guid values, numeric widths, item order and per-item status. Matrix
payloads remain unsupported and fail per item; this upgrade adds no matrix or
upstream-history capability.
Certificate-based identities retain their loaded certificate until their owning
session closes, including failure cleanup. The browser releases abandoned browse
continuation points. Endpoint policy selection, namespace-URI remapping, old-session
notification rejection and the existing refusal to replay non-idempotent writes or
alarm acknowledgements remain compatibility requirements.
No application status-code, locale-selection or event-filter semantic change is
approved by this upgrade. SDK value wrappers and empty-filter construction are API
adaptations; callers must continue to inspect operation and select-clause results
by index. Confirm actual client/server combinations with the
[fixture map](OpcUaClient-Test-Fixture.md) and
[rollout gates](../plans/2026-11-10-opcua-sdk-2-rollout.md) before deployment.
Historical SDK 1.5 observations elsewhere on this page describe their original
measurements; they are not fresh SDK 2.0.1 interoperability evidence.
## Project split
| Project | Target | Role |
@@ -365,7 +391,7 @@ They are not part of `DriverHealth` or the
## Testing
- **Unit tests** — `tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Tests/`
cover the session lifecycle, namespace remapping, alarm/history passthrough,
cover the session lifecycle, namespace remapping, alarm dispatch,
and config binding against a faked SDK session.
- **Integration fixture** — exercises the driver against a reference OPC UA
server (opc-plc) on the shared docker host; see
@@ -0,0 +1,284 @@
# OPC UA SDK 2.0.1 rollout and rollback
This operator runbook accompanies [#782](https://gitea.dohertylan.com/dohertj2/lmxopcua/issues/782),
the [implementation plan](2026-11-10-opcua-sdk-2-upgrade.md) and
[execution evidence](2026-11-10-opcua-sdk-2-evidence.md). Gitea is the single
status system. This draft was checked against source `a21104d2`; it does not
approve an artifact or record a deployment. The coordinator must attach final
commit-specific evidence in #782 before advancing a gate. All placeholders below
are **pending evidence**, not passing results.
The target is exact OPC Foundation SDK **2.0.1**; the known-good SDK baseline is
**1.5.378.182** (application baseline `83ed880e4471344deaf008da9bd028c7e170bdc7`).
Restore the actual archived known-good application as a unit during rollback.
Package downgrades alone cannot reverse the application/API migration.
## Operating constraints
**The remote-execution hold on wonder boxes vd03/vq03/vq04 remains binding.**
No WinRM, psbridge or replacement remote-exec channel may be used until the user
clears a channel. UNC/SMB file copying and permitted SQL access do not authorize
service control, PowerShell execution or deployment on those hosts. Steps requiring
a command on a held host remain pending. No deployment was performed for this draft.
Run the service commands below only from an approved local operator session on an
authorized Windows node. Record the node, account, channel and maintenance window
in #782 first. Linux runtime/service handling requires its own approved environment
and smoke record; this runbook supplies no invented Linux service-unit name.
Do not use `scripts/install/Refresh-Services.ps1` as a blanket upgrade action: it
also touches gateway/retired sidecar paths outside this SDK rollout.
## Preserved contract
- Existing raw/UNS namespace URIs, identifier forms, endpoint profiles, API-key/anonymous
admission, ACL flag behavior, role and key revocation gates remain the contract.
Source uses public transport peer evidence for miss budgets, not an IP admission rule.
- Scalar leniency, checked numeric-array conversion and pass-through driver behavior
stay as before. SDK immutable values are detached at boundaries; no new matrix support.
- No application status-code, locale or event-filter semantic change is approved.
SDK status wrappers and explicit empty `ContentFilter` construction are API changes,
not evidence of changed protocol values. Record any stricter response, field-level
filter error or localization difference with a consumer-impact decision before go.
- Auditing stays opt-in. Ordinary SDK automatic audit delivery retains its type
restrictions. Only the application's rejected-write audit gets a private, temporary
receive-permission context after current source `Read` ACL and audit/encryption checks;
no shared role metadata or general audit access is widened. See [security](../security.md).
- The private source port retains the **37 legacy aggregate factories** and existing
application results rather than adopting SDK 2 algorithms. Original-SDK fixtures
contain **6,144 vectors**. `TreatUncertainAsBad=false` stays explicit; historian
backend aggregate sets and existing documented differences remain unchanged.
SDK FILETIME-zero maps to the existing CLR unset-time sentinel at history boundaries.
- No new historian backend, companion specification, PubSub, ManagedSession, AOT or
cluster rolling-upgrade capability is claimed. HistorianGateway Client/Contracts
**0.4.0** is already on gateway master `16111a5e` (historiangw#119 closed);
the real gateway gate historiangw#78 remains separate from package alignment.
## Release record and preflight
Fill this record in #782 with links to immutable logs/manifests; do not paste keys,
passwords, connection strings, private certificates or unredacted environment dumps.
| Required evidence | Record to supply before release |
|---|---|
| Candidate source and graph | Pending: full commit, clean/dirty state, SDK/runtime/OS, resolved package graph showing exact 2.0.1 |
| Known-good recovery set | Pending: deployed application version, full binary/config archive SHA-256, protected PKI backup location and permission record |
| Candidate artifacts | Pending: Windows and Linux publish directories/archives, RID/self-contained choice, SHA-256 manifest, dependencies and script-worker contents |
| G2 compilation | Pending: restore/build logs and warning/error counts at the final SHA |
| G3 behavior/security | Pending: project TRX/counts, required case results, positive and negative authorization, audit privacy, CP lifecycle and 6,144-vector comparison |
| Interoperability | Pending: baseline/candidate client-server pairs, actual ScadaBridge adapter, upstream driver/browser products and mixed-version cluster gate |
| Historian | Pending: configured SqlServer/QuestDB/Gateway capability-specific results; historiangw#78 link/evidence for live gateway |
| G4 resources/performance | Pending: baseline comparison, at least three measured runs, two-hour soak, Windows/Linux start-stop-twice smoke with preserved PKI |
| Review/operations | Pending: independent security/release review, authorized channel/window, named operator, canary/rollback results and decision |
Before staging:
1. Inventory actual service executable/arguments, roles, endpoints, advertised host,
application URI, raw/UNS namespace identities, certificate thumbprints, active/standby
state and connected client builds. Record configured queues, request/transport quotas,
history caps and expected load. Establish performance budgets and stop thresholds.
2. Archive complete known-good binaries and node configuration, preserving access controls.
Securely back up PKI own/private keys, peer/issuer chains, CRLs and their permissions.
Verify recovery access under the service identity, private-key presence, expiry,
application URI/hostname match and CA/key-usage suitability. Retain existing certificates.
3. Inventory ConfigDb, LocalDb, historian/outbox and secret-provider state/locations. No
ConfigDb migration is planned. Record the actual schema/serialization diff, including
Akka/deployment contracts; if persistence changes appear, reopen the design gate and
define data rollback before deployment. Never overwrite live historian/outbox data
with an old binary backup or rewrite persisted sessions/subscriptions.
4. Publish into fresh directories, hash artifacts, stage separately from the live install
and validate graph contents. Keep baseline and candidate ports, PKI, config and stores
separate in the isolated rig; never run both against the same mutable fixture.
5. Confirm required positive/negative checks, reviewers and recovery artifact access.
Missing evidence, inaccessible environments or an uncleared command channel means hold.
## Verification commands
These commands are recipes, not execution results. Run from the repository root in
Bash with .NET 10. Record the final SHA and logs in a fresh evidence directory; inspect
exit status before continuing. Do not pipe a failing build/test into a successful logger.
```bash
git rev-parse HEAD
git status --short
dotnet --info
dotnet restore ZB.MOM.WW.OtOpcUa.slnx
dotnet build ZB.MOM.WW.OtOpcUa.slnx -c Release --no-restore
```
Define the helper once after a successful build. Each invocation creates its own
fresh TRX directory. It preserves both test failure and zero-executed-test failure.
A successful guard still requires inspection of required cases and skips.
```bash
opc_test() {
local opc_project="$1"
local opc_results
opc_results=$(mktemp -d "${TMPDIR:-/tmp}/opcua2-test.XXXXXXXX") || return
local opc_test_status=0
dotnet test "$opc_project" -c Release --no-build --logger trx \
--results-directory "$opc_results" || opc_test_status=$?
local opc_count_status=0
MIN_EXECUTED=1 bash scripts/ci/assert-not-all-skipped.sh "$opc_results"/*.trx \
|| opc_count_status=$?
printf 'TRX directory: %s\n' "$opc_results"
if [ "$opc_test_status" -ne 0 ]; then return "$opc_test_status"; fi
return "$opc_count_status"
}
opc_test tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests.csproj
opc_test tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj
opc_test tests/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.Tests/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.Tests.csproj
opc_test tests/Client/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests/ZB.MOM.WW.OtOpcUa.Client.Shared.Tests.csproj
opc_test tests/Client/ZB.MOM.WW.OtOpcUa.Client.CLI.Tests/ZB.MOM.WW.OtOpcUa.Client.CLI.Tests.csproj
```
Driver/browser and simulator commands are in the
[fixture map](../drivers/OpcUaClient-Test-Fixture.md#running-locally). Backend and
live historian prerequisites are in [Historian.md](../Historian.md) and
[infra/README.md](../../infra/README.md). Live tests can write sandbox data: use
only designated sandbox tags and approved credentials through the existing secret
provider/environment. A skipped live/DB fixture never satisfies its gate.
Generate original aggregate evidence only with the isolated
[oracle procedure](../../scripts/validation/opcua-aggregate-baseline/README.md),
a new output path and original 1.5.378.182 binary; never derive expectations from
the candidate's calculators.
Also run the full CI-equivalent test leg after integration; it does not replace
fixture-specific or live gates:
```bash
opc_solution_test() {
local opc_results
opc_results=$(mktemp -d "${TMPDIR:-/tmp}/opcua2-solution.XXXXXXXX") || return
local opc_test_status=0
dotnet test ZB.MOM.WW.OtOpcUa.slnx -c Release --no-build \
-m:1 -p:TestTfmsInParallel=false --settings scripts/ci/ci.runsettings \
--filter 'Category!=E2E&Category!=LiveIntegration' \
--logger trx --results-directory "$opc_results" || opc_test_status=$?
local opc_count_status=0
MIN_EXECUTED=12000 bash scripts/ci/assert-not-all-skipped.sh "$opc_results"/*.trx \
|| opc_count_status=$?
printf 'TRX directory: %s\n' "$opc_results"
if [ "$opc_test_status" -ne 0 ]; then return "$opc_test_status"; fi
return "$opc_count_status"
}
opc_solution_test
```
Publish the Host project to a fresh operator-selected `$OPC_PUBLISH_DIR` using the
approved `$OPC_RID` and deployment's self-contained choice. The Windows install
expects `OtOpcUa.Host.exe`; [ServiceHosting.md](../ServiceHosting.md) also describes
script-worker packaging. Example self-contained Windows artifact command:
```bash
dotnet publish src/Server/ZB.MOM.WW.OtOpcUa.Host/ZB.MOM.WW.OtOpcUa.Host.csproj \
-c Release -r win-x64 --self-contained true -o "$OPC_PUBLISH_DIR"
```
Repeat with the approved Linux RID/framework settings in its validation environment;
cross-publishing is not runtime/install evidence. Hash the complete staged artifact
and retain a manifest outside it (PowerShell 7, where `$Candidate` and `$Manifest`
are approved absolute local paths and the manifest is outside the candidate):
```powershell
Get-ChildItem -LiteralPath $Candidate -Recurse -File |
Get-FileHash -Algorithm SHA256 |
Export-Csv -LiteralPath $Manifest -NoTypeInformation
```
## Sequence and stop/go decision
Progress only after the preceding stage's recorded checks and explicit gate decision:
**isolated rig → ScadaBridge/upstream interoperability → DEV canary → QA pair →
production canary**. Attach source/artifact identity, start/end times, operator,
checks, observations and go/hold/rollback decision for each stage to #782.
A standby-first pair restart is allowed only after the application's mixed-version
Akka serialization, deployment/config and failover gate succeeds. Verify standby
health, security, data, history and events; exercise failover before upgrading its
peer. OPC UA wire interoperability alone does not prove cluster rolling safety.
Without that gate, arrange a maintenance window and coordinated pair restart;
record expected service interruption and recovery checks.
The following Windows commands are **local-session steps only**. Bind `$Install`
to the inspected current binary directory, `$Candidate` to the reviewed staged
artifact and `$Backup` to a new protected directory. Keep PKI/data stores outside
binary replacement; if they are inside the install tree, define exclusions and a
separate protected backup before using these commands. Save configuration outside
`$Candidate`, then apply the reviewed node configuration to the staging directory;
never overwrite it with publisher defaults or expose secrets in command output.
```powershell
Get-CimInstance Win32_Service -Filter "Name='OtOpcUaHost'" |
Select-Object Name, State, PathName, StartName
Stop-Service -Name OtOpcUaHost -ErrorAction Stop
(Get-Service -Name OtOpcUaHost).WaitForStatus('Stopped', [TimeSpan]::FromSeconds(60))
robocopy $Install $Backup /E /COPYALL /DCOPY:DAT /R:1 /W:1
if ($LASTEXITCODE -ge 8) { throw 'Known-good backup failed' }
# After checking the backup and candidate manifest, swap complete binary directories.
# Use sibling paths on the same volume; the service PathName must still resolve to $Install.
Move-Item -LiteralPath $Install -Destination $PreviousInstall -ErrorAction Stop
Move-Item -LiteralPath $Candidate -Destination $Install -ErrorAction Stop
Start-Service -Name OtOpcUaHost -ErrorAction Stop
(Get-Service -Name OtOpcUaHost).WaitForStatus('Running', [TimeSpan]::FromSeconds(60))
```
`$PreviousInstall` must be a fresh reviewed sibling path. Handle any failure between
moves by restoring that complete directory before starting. Service `Running` is
only a process check. Run the substantive checks below after every start and failover:
- Check `/healthz`, `/health/ready` and role-appropriate `/health/active` at the
recorded HTTP base URL; compare ServiceLevel and active/standby state to baseline.
- Confirm certificate thumbprints, trust/issuer chains, endpoint policies/application
URI and namespace-URI/NodeId identity. Prove trusted SignAndEncrypt works and
untrusted/revoked/inappropriate certificates and wrong keys fail without downgrade.
- Exercise raw and UNS browse/read, scalar/array writes on sandbox nodes, subscriptions,
quality and source/server timestamps. Verify current legitimate ACL allows as well
as denies, key expiry/revocation and audience-specific event/audit filtering.
- Verify alarms/refresh/ack and no missing or duplicate events; verify configured raw,
modified, processed and event history, paging/release/reauthentication and expected
unsupported operations. Verify recorder/outbox progress without duplicate replay.
- Observe reconnects, stale values, legitimate-call denials, continuation-point errors,
session/item/certificate-handle growth, shutdown, queue depths and latency.
Use [Client.CLI.md](../Client.CLI.md) for exact connect/browse/read/subscribe/history
and alarm syntax. Supply credentials through the approved operator mechanism; do
not record command lines containing API-key passwords in release evidence.
Stop promotion and restore the known-good application for any authorization regression,
missing/duplicate alarm or history data, changed identifiers, insecure fallback,
restart failure or sustained performance-budget miss. Compare like hardware/config/load:
at least three warmed measurements, provisional limits ≤10% median throughput loss
and ≤15% p95 latency/allocation/RSS growth, plus at least two hours of lifecycle soak.
Any deviation needs investigation and a recorded acceptance decision. Do not lower
thresholds or count absent environments as passed.
## Rollback
1. Freeze promotion; record the trigger and affected nodes/clients in #782. Preserve
candidate logs and manifests with secrets redacted. Stop the candidate through the
approved local channel; the remote-exec hold still applies during rollback.
2. With the service stopped, move the candidate install to a fresh quarantine path,
restore the complete `$PreviousInstall` (or verified `$Backup`) to the inspected
service path, and restore the matching node configuration and preserved PKI with
original permissions. Check hashes/thumbprints before starting. Do not delete or
roll back live historian, outbox or ConfigDb data without a reviewed data strategy.
3. Start `OtOpcUaHost` locally with the same `Start-Service`/wait commands above.
On Linux, use only the environment's approved recorded supervisor procedure.
Verify health, endpoint/namespace/certificate identity and active/standby state.
4. Reconnect clients as needed. In-memory sessions, subscriptions and continuation
points do not survive process rollback; discard old points and begin new reads.
Rebind namespaces by URI. Never replay ambiguous non-idempotent writes or alarm
acknowledgements. Confirm API-key writes/ack, subscriptions, alarm counts and history
continuity with the same positive and negative checks used at rollout.
5. Record recovery time, checks, data reconciliation and final hold/go decision.
If rolling source back, revert package and application commits together; never
mix old package binaries with SDK 2 application assemblies. Keep candidate evidence
for diagnosis and link follow-up issues from #782.
## Results handoff
Pending: coordinator to attach the final SHA, artifact hashes, TRX counts/skips,
interoperability/performance/runtime evidence, reviews and per-environment operator
records in #782. This document makes no claim of a passing build, test, ScadaBridge,
Windows/Linux smoke, live backend, soak or deployment. Required inaccessible steps
remain open gates unless formally separated into linked issues with accurate scope.
+31
View File
@@ -36,6 +36,37 @@ Transport security and OPC UA authentication are per-node concerns configured in
## Transport Security
### SDK 2.0.1 compatibility (#782)
The application targets exact OPC Foundation SDK **2.0.1**, replacing **1.5.378.182**.
The upgrade retains the existing host, security profiles, anonymous-admission setting,
API-key authentication and ACL flag semantics. It adds no companion-specification or
PubSub capability. Release evidence and operator gates are linked from the
[rollout runbook](plans/2026-11-10-opcua-sdk-2-rollout.md); source changes alone do not establish release approval.
SDK role augmentation preserves the application's principal, API-key id and application
roles. A rejected API key must remain rejected rather than falling through to another
identity provider. Per-IP authentication miss accounting uses the public transport-observed
`SecureChannelContext.PeerAddress` during activation; an unknown peer retains the existing
process-wide budget fallback. This is accounting evidence, not a client-supplied address or
a new IP admission policy.
SDK event receive checks compose with application ACL filtering. For the application's
rejected-write `AuditWriteUpdateEvent` only, a temporary validation context supplies
`ReceiveEvents` to the recipient's SDK roles after the current source variable, effective
identity, source `Read` grant and audit/encryption guard are checked. It expires before
queueing; shared role-permission metadata is not widened. Prior permission callback
errors veto delivery. SDK-generated audits retain SDK defaults. This does not enable
auditing or grant a general audit feed.
Certificate configuration uses the SDK certificate manager, and certificate ownership
lasts through the owning host/session's lifetime. Preserve the existing application
certificate, private key, issuer/peer stores and filesystem permissions during rollout;
verify key access and CA usage under the service identity. Do not rotate certificates,
enable auto-accept, add `None`, or relax revocation checks to get the candidate running.
Continuation points remain session-owned and bound to node/topology and current authority;
restart requires fresh sessions and fresh points.
### Overview
The OtOpcUa Server supports configurable OPC UA transport security profiles that control how data is protected on the wire between OPC UA clients and the server.
@@ -0,0 +1,22 @@
#Requires -Version 7.0
<#
.SYNOPSIS
Runs the production application SDK compatibility matrix in isolated processes.
.DESCRIPTION
Uses exact baseline host/client publish artifacts and builds the candidate from a
separate checkout. Both SDK versions remain in separate processes. Evidence,
artifact SHA-256 hashes, negotiated policies and individual results are retained.
The output directory must not exist. No fleet endpoint or store is used.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$BaselineRoot,
[Parameter(Mandatory)][string]$BaselineArtifacts,
[Parameter(Mandatory)][string]$CandidateRoot,
[Parameter(Mandatory)][string]$OutputDirectory,
[string]$ContainerImage = 'mcr.microsoft.com/dotnet/sdk:10.0.103-noble'
)
$ErrorActionPreference = 'Stop'
$runner = Join-Path $PSScriptRoot '../validation/opcua-sdk-compatibility/run.py'
& python3 $runner --baseline-root $BaselineRoot --baseline-artifacts $BaselineArtifacts --candidate-root $CandidateRoot --output $OutputDirectory --container-image $ContainerImage
exit $LASTEXITCODE
@@ -0,0 +1 @@
__pycache__/
@@ -0,0 +1,249 @@
#pragma warning disable OTOPCUA0001
using System.Collections;
using System.Collections.Concurrent;
using System.Diagnostics;
using System.Reflection;
using System.Security.Cryptography;
using System.Text.Json;
using Opc.Ua;
using Opc.Ua.Configuration;
using ZB.MOM.WW.OtOpcUa.Client.Shared;
using ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient;
using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser;
using ZB.MOM.WW.OtOpcUa.OpcUaServer;
using WriteRequest = ZB.MOM.WW.OtOpcUa.Core.Abstractions.WriteRequest;
using SharedSecurityMode = ZB.MOM.WW.OtOpcUa.Client.Shared.Models.SecurityMode;
internal static partial class ProcessHost
{
static object ServerCounts(OtOpcUaSdkServer server)
{
var sessions = server.CurrentInstance.SessionManager.GetSessions();
var subs = server.CurrentInstance.SubscriptionManager.GetSubscriptions();
return new { utc = DateTime.UtcNow, sessions = sessions.Count, subscriptions = subs.Count,
items = subs.Sum(s => s.MonitoredItemCount), serverProcess = Environment.ProcessId };
}
}
internal static class Lifecycle
{
static string Root = "";
static string Password => Environment.GetEnvironmentVariable("OPCUA_MATRIX_PASSWORD") ?? throw new InvalidOperationException("Missing fixture credential");
static readonly JsonSerializerOptions Json = new() { WriteIndented = true };
static int managerChecks, sharedPasses, driverPasses, browserPasses;
static readonly List<WeakReference> Weak = [];
static void Require(bool pass, string message) { if (!pass) throw new InvalidOperationException(message); }
static object? FieldOrNull(object owner, string name)
{
var field = owner.GetType().GetField(name, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
?? throw new InvalidOperationException("Diagnostic layout changed: " + owner.GetType().FullName + "." + name);
return field.GetValue(owner);
}
static object Field(object owner, string name) => FieldOrNull(owner, name) ?? throw new InvalidOperationException("Diagnostic owner null: " + name);
static void Empty(object owner, string name) => Require(Field(owner, name) is ICollection items && items.Count == 0, "Retained collection: " + name);
static bool Disposed(object manager)
{
Require(manager.GetType().FullName == "Opc.Ua.CertificateManager", "Unexpected SDK certificate manager type");
Require(manager.GetType().Assembly.GetName().Version?.ToString() == "2.0.1.0", "Diagnostic requires SDK 2.0.1.0");
var field = manager.GetType().GetField("m_disposed", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly);
Require(field?.FieldType == typeof(bool), "SDK 2.0.1 CertificateManager.m_disposed bool layout changed");
return (bool)field!.GetValue(manager)!;
}
static object SharedManager(OpcUaClientService shared) => Field(Field(shared, "_session"), "_certificateManager");
static object AppManager(object owner) => ((ApplicationInstance)Field(owner, "_ownedApplication")).ApplicationConfiguration!.CertificateManager;
static void CheckManager(object manager, bool disposed)
{
Require(Disposed(manager) == disposed, "Certificate manager disposal observation mismatch");
if (disposed) managerChecks++;
}
static ConnectionSettings Settings(string endpoint, string? password = null) => new()
{
EndpointUrl = endpoint, Username = "apikey", Password = password ?? Password,
SecurityMode = SharedSecurityMode.SignAndEncrypt, AutoAcceptCertificates = false,
CertificateStorePath = Path.Combine(Root, "data", "shared-pki"), SessionTimeoutSeconds = 30
};
static OpcUaClientDriverOptions Options(string endpoint) => new()
{
EndpointUrl = endpoint, SecurityPolicy = OpcUaSecurityPolicy.Basic256Sha256,
SecurityMode = OpcUaSecurityMode.SignAndEncrypt, AuthType = OpcUaAuthType.Username,
Username = "apikey", Password = Password, AutoAcceptCertificates = false,
SessionName = "ClientLifecycle", ApplicationUri = "urn:localhost:ClientLifecycle",
RawTags = [new("scalar", "{\"nodeId\":\"nsu=https://zb.com/otopcua/raw;s=Matrix/dev/Scalar\"}", true),
new("vector", "{\"nodeId\":\"nsu=https://zb.com/otopcua/raw;s=Matrix/dev/Vector\"}", true)]
};
static async Task Wait(Func<bool> condition, CancellationToken ct)
{
while (!condition()) await Task.Delay(25, ct);
}
static object? Clr(DataValue value) => ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers.ValueConverter.ToClrObject(value.WrappedValue);
static async Task Prepare()
{
// Public connection failures create and release the same production applications as a live attempt.
// No production private method is invoked and no SDK state is written by diagnostics.
using var ct = new CancellationTokenSource(TimeSpan.FromSeconds(15));
using (var shared = new OpcUaClientService())
{ try { await shared.ConnectAsync(Settings("opc.tcp://127.0.0.1:1"), ct.Token); } catch { } }
await using (var driver = new OpcUaClientDriver(Options("opc.tcp://127.0.0.1:1"), "lifecycle"))
{ try { await driver.InitializeAsync("{}", ct.Token); } catch { } }
var browser = new OpcUaClientDriverBrowser();
try { await using var session = await browser.OpenAsync(JsonSerializer.Serialize(Options("opc.tcp://127.0.0.1:1")), ct.Token); } catch { }
foreach (var folder in new[] { "data/shared-pki", "data/OtOpcUa/pki", "data/OtOpcUa/adminui-browse-pki" })
Require(Directory.GetFiles(Path.Combine(Root, folder, "own", "certs")).Length == 1, "Expected one reusable application DER certificate: " + folder);
}
static async Task Cycle(string endpoint, int cycle)
{
using var budget = new CancellationTokenSource(TimeSpan.FromSeconds(30));
var ct = budget.Token;
using var shared = new OpcUaClientService(); Weak.Add(new(shared));
await using var driver = new OpcUaClientDriver(Options(endpoint), "lifecycle"); Weak.Add(new(driver));
var browser = new OpcUaClientDriverBrowser(); Weak.Add(new(browser));
// Two connections on the same Shared service and two initializations on the same driver.
for (var pass = 0; pass < 2; pass++)
{
var seen = new ConcurrentQueue<int>();
EventHandler<DataChangedEventArgs> handler = (_, e) => { if (Clr(e.Value) is int n) seen.Enqueue(n); };
shared.DataChanged += handler;
var info = await shared.ConnectAsync(Settings(endpoint), ct);
Require(info.SecurityMode == "SignAndEncrypt" && info.SecurityPolicyUri == SecurityPolicies.Basic256Sha256, "Shared policy downgrade");
object? manager = SharedManager(shared); CheckManager(manager, false);
var nss = (string[])Clr(await shared.ReadValueAsync(VariableIds.Server_NamespaceArray, ct))!;
var ns = (ushort)Array.IndexOf(nss, "https://zb.com/otopcua/raw"); Require(ns > 0, "Raw namespace missing");
var scalar = new NodeId("Matrix/dev/Scalar", ns); var vector = new NodeId("Matrix/dev/Vector", ns);
await shared.SubscribeAsync(scalar, 100, ct); await shared.SubscribeAsync(vector, 100, ct);
var target = cycle * 10 + pass;
Require(StatusCode.IsGood(await shared.WriteValueAsync(scalar, target, ct)), "Shared scalar write failed");
Require(StatusCode.IsGood(await shared.WriteValueAsync(vector, new[] { target, 2, 3 }, ct)), "Shared vector write failed");
await Wait(() => seen.Contains(target), ct);
Require(Equals(Clr(await shared.ReadValueAsync(scalar, ct)), target), "Shared scalar roundtrip mismatch");
Require(((int[])Clr(await shared.ReadValueAsync(vector, ct))!).SequenceEqual(new[] { target, 2, 3 }), "Shared vector mismatch");
Require((await shared.BrowseAsync(new NodeId("Matrix/dev", ns), ct)).Count > 0, "Shared browse empty");
await shared.UnsubscribeAsync(scalar, ct); await shared.UnsubscribeAsync(vector, ct);
await shared.DisconnectAsync(ct);
Require(!shared.IsConnected && shared.CurrentConnectionInfo is null, "Shared public connection state retained");
Require(FieldOrNull(shared, "_session") is null, "Shared session retained"); Empty(shared, "_activeDataSubscriptions");
CheckManager(manager, true); manager = null; shared.DataChanged -= handler; sharedPasses++;
if (pass == 0) await driver.InitializeAsync("{}", ct);
else await driver.ReinitializeAsync("{}", ct);
Require(driver.GetHealth().State == DriverState.Healthy, "Driver initialize health");
manager = AppManager(driver); CheckManager(manager, false);
var values = new ConcurrentQueue<int>();
EventHandler<DataChangeEventArgs> driverHandler = (_, e) => { if (e.Snapshot.Value is int n) values.Enqueue(n); };
driver.OnDataChange += driverHandler;
var sub = await driver.SubscribeAsync(["scalar", "vector"], TimeSpan.FromMilliseconds(100), ct);
target++;
var writes = await driver.WriteAsync([new WriteRequest("scalar", target), new WriteRequest("vector", new[] { target, 4, 5 })], ct);
Require(writes.Count == 2 && writes.All(w => w.StatusCode == 0), "Driver write failed");
await Wait(() => values.Contains(target), ct);
var reads = await driver.ReadAsync(["scalar", "vector"], ct);
Require(reads.Count == 2 && reads.All(r => r.StatusCode == 0) && Equals(reads[0].Value, target)
&& ((int[])reads[1].Value!).SequenceEqual(new[] { target, 4, 5 }), "Driver roundtrip mismatch");
await driver.UnsubscribeAsync(sub, ct); sub = null!;
// Reinitialize a live connection with an active replacement subscription, as the watchdog does.
sub = await driver.SubscribeAsync(["scalar", "vector"], TimeSpan.FromMilliseconds(100), ct);
await driver.ReinitializeAsync("{}", ct); sub = null!;
CheckManager(manager, true); manager = null;
manager = AppManager(driver); CheckManager(manager, false);
Require(driver.GetHealth().State == DriverState.Healthy, "Live reinitialize failed");
var reinitialized = await driver.ReadAsync(["scalar"], ct);
Require(reinitialized.Count == 1 && reinitialized[0].StatusCode == 0 && Equals(reinitialized[0].Value, target), "Live reinitialize read failed");
await driver.ShutdownAsync(ct); driver.OnDataChange -= driverHandler;
Require(driver.GetHealth().State == DriverState.Unknown, "Driver shutdown public state retained");
Require(FieldOrNull(driver, "<Session>k__BackingField") is null, "Driver session retained");
Empty(driver, "_subscriptions"); Empty(driver, "_alarmSubscriptions");
CheckManager(manager, true); manager = null; driverPasses++;
var browse = await browser.OpenAsync(JsonSerializer.Serialize(Options(endpoint)), ct); Weak.Add(new(browse));
manager = AppManager(browse); CheckManager(manager, false);
Require((await browse.RootAsync(ct)).Count > 0, "Browser root empty");
await browse.DisposeAsync().AsTask().WaitAsync(ct); CheckManager(manager, true); manager = null; browserPasses++;
}
}
static object Resources(int cycle, double elapsed)
{
GC.Collect(); GC.WaitForPendingFinalizers(); GC.Collect();
var survivors = Weak.Count(w => w.IsAlive); Weak.RemoveAll(w => !w.IsAlive);
Require(survivors == 0, "Disposed production client/driver/browser object retained after full GC");
var fd = Directory.GetFiles("/proc/self/fd");
var owned = 0; var pki = 0;
foreach (var path in fd)
{
var target = new FileInfo(path).LinkTarget;
if (target is null || !Path.IsPathFullyQualified(target)) continue;
target = Path.GetFullPath(target);
if (target.StartsWith(Path.GetFullPath(Root) + Path.DirectorySeparatorChar, StringComparison.Ordinal)) owned++;
if (target.StartsWith(Path.Combine(Path.GetFullPath(Root), "data") + Path.DirectorySeparatorChar, StringComparison.Ordinal)) pki++;
}
using var p = Process.GetCurrentProcess();
return new { cycle, elapsedSeconds = elapsed, utc = DateTime.UtcNow, p.WorkingSet64, p.PrivateMemorySize64,
managedBytes = GC.GetTotalMemory(false), allocatedBytes = GC.GetTotalAllocatedBytes(),
gc = new[] { GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2) },
fdCount = fd.Length, ownedRootFdCount = owned, ownedPkiFdCount = pki, survivingProductionObjects = survivors,
managerDisposalsVerified = managerChecks, sharedPasses, driverPasses, browserPasses };
}
static async Task Run(string endpoint, int seconds, bool full)
{
Require(!full || seconds >= 7200, "Full soak requires >=7200 requested seconds");
// Deliberate owned-manager positive control proves the exact-tag read-only diagnostic sees both states.
var control = CertificateManagerFactory.Create(new SecurityConfiguration(), DefaultTelemetry.Create(_ => { }));
Require(!Disposed(control), "Disposal diagnostic control false-state failure");
await control.DisposeAsync(); Require(Disposed(control), "Disposal diagnostic control true-state failure");
control = null!;
var originalCerts = CertificateHashes();
var elapsed = Stopwatch.StartNew(); var cycle = 0;
File.AppendAllText(Path.Combine(Root, "resources.jsonl"), JsonSerializer.Serialize(Resources(0, 0)) + "\n");
while (elapsed.Elapsed.TotalSeconds < seconds)
{
await Cycle(endpoint, ++cycle).WaitAsync(TimeSpan.FromSeconds(65));
// The async cycle has returned, dropping its strong manager/session/item/event references.
await Task.Delay(300);
var serverPath = Path.Combine(Root, "server", "live-resources.json");
var settledOk = false;
for (var attempt = 0; attempt < 30; attempt++)
{
using var settled = JsonDocument.Parse(await File.ReadAllTextAsync(serverPath));
settledOk = new[] { "sessions", "subscriptions", "items" }.All(name => settled.RootElement.GetProperty(name).GetInt32() == 0);
if (settledOk) break;
await Task.Delay(100);
}
Require(settledOk, "Server sessions/subscriptions/items retained after bounded settling");
if (cycle % 10 == 0 || elapsed.Elapsed.TotalSeconds >= seconds)
File.AppendAllText(Path.Combine(Root, "resources.jsonl"), JsonSerializer.Serialize(Resources(cycle, elapsed.Elapsed.TotalSeconds)) + "\n");
}
Require(elapsed.Elapsed.TotalSeconds >= seconds && (!full || elapsed.Elapsed.TotalSeconds >= 7200), "Real elapsed duration gate failed");
Require(managerChecks == cycle * 8 && sharedPasses == cycle * 2 && driverPasses == cycle * 2 && browserPasses == cycle * 2, "Incomplete lifecycle accounting");
Require(CertificateHashes().SequenceEqual(originalCerts), "Application certificate unexpectedly rotated or PKI changed");
var summary = new { status = "passed", diagnosticPositiveControl = "exact SDK2 manager false-before/true-after DisposeAsync", applicationCertificateHashes = originalCerts, requestedSeconds = seconds, elapsedSeconds = elapsed.Elapsed.TotalSeconds,
fullTwoHourLifecycle = full && elapsed.Elapsed.TotalSeconds >= 7200, cycles = cycle, sharedPasses, driverPasses, browserPasses,
managerDisposalsVerified = managerChecks, finalResources = Resources(cycle, elapsed.Elapsed.TotalSeconds),
scope = "Production Shared connect/disconnect/reconnect; production driver Initialize/Reinitialize/Shutdown/dispose; production browser open/browse/dispose; scalar and Int32[3] read/write/subscribe/unsubscribe; strict mutual trusted DER/Basic256Sha256 SignAndEncrypt/API-key fixture. No network stalls, revocation, surgical edits/rebuild, CP abandonment or Windows/AVEVA/performance G4 claim." };
File.WriteAllText(Path.Combine(Root, "summary.json"), JsonSerializer.Serialize(summary, Json));
}
static string[] CertificateHashes() => Directory.GetFiles(Path.Combine(Root, "data"), "*.der", SearchOption.AllDirectories)
.Where(p => p.Contains(Path.DirectorySeparatorChar + "own" + Path.DirectorySeparatorChar + "certs" + Path.DirectorySeparatorChar, StringComparison.Ordinal))
.Order().Select(p => Path.GetRelativePath(Root, p) + ":" + Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(p))).ToLowerInvariant()).ToArray();
public static async Task<int> Main(string[] args)
{
if (args[0] == "server") return await ProcessHost.HelperMain(args);
Root = Path.GetFullPath(args[1]); Directory.CreateDirectory(Root);
try
{
var local = Path.GetFullPath(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
Require(local == Path.Combine(Root, "data"), "XDG task PKI isolation failed");
if (args[0] == "prepare") { await Prepare(); return 0; }
Require(args[0] == "run", "Unknown mode");
await Run(args[2], int.Parse(args[3]), args[4] == "full");
var sdk = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name!.StartsWith("Opc.Ua", StringComparison.Ordinal))
.Select(a => new { name = a.GetName().Name, version = a.GetName().Version?.ToString(), sha256 = Convert.ToHexString(SHA256.HashData(File.ReadAllBytes(a.Location))).ToLowerInvariant() });
File.WriteAllText(Path.Combine(Root, "sdk-assemblies.json"), JsonSerializer.Serialize(sdk, Json));
return 0;
}
catch (Exception error)
{
File.WriteAllText(Path.Combine(Root, "failure.txt"), error.ToString().Replace(Password, "<fixture-secret>"));
return 1;
}
}
}
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><OutputType>Exe</OutputType><StartupObject>Lifecycle</StartupObject><DefineConstants>SDK2</DefineConstants></PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<ProjectReference Include="../../../src/Server/ZB.MOM.WW.OtOpcUa.Host/ZB.MOM.WW.OtOpcUa.Host.csproj" />
<ProjectReference Include="../../../src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/ZB.MOM.WW.OtOpcUa.Client.Shared.csproj" />
<ProjectReference Include="../../../src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.csproj" />
<ProjectReference Include="../../../src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.csproj" />
</ItemGroup></Project>
@@ -0,0 +1,360 @@
// Copy of compatibility ProcessHost at 7b353d7b; lifecycle-owned changes only.
#pragma warning disable OTOPCUA0001 // This wire harness deliberately exercises public driver capabilities directly.
using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text.Json;
using Microsoft.Extensions.Logging.Abstractions;
using Opc.Ua;
using Opc.Ua.Client;
using ZB.MOM.WW.OtOpcUa.Client.Shared;
using ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
using ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
using ZB.MOM.WW.OtOpcUa.Configuration.Entities;
using ZB.MOM.WW.OtOpcUa.Configuration.Enums;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Core.Authorization;
using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient;
using ZB.MOM.WW.OtOpcUa.OpcUaServer;
using ZB.MOM.WW.OtOpcUa.OpcUaServer.Security;
using AlarmEventArgs = ZB.MOM.WW.OtOpcUa.Client.Shared.Models.AlarmEventArgs;
using WriteRequest = ZB.MOM.WW.OtOpcUa.Core.Abstractions.WriteRequest;
using SharedSecurityMode = ZB.MOM.WW.OtOpcUa.Client.Shared.Models.SecurityMode;
using CoreHistory = ZB.MOM.WW.OtOpcUa.Core.Abstractions.HistoryReadResult;
internal static partial class ProcessHost
{
static readonly DateTime Epoch = new(2026, 10, 1, 0, 0, 0, DateTimeKind.Utc);
const string RawUri = "https://zb.com/otopcua/raw", UnsUri = "https://zb.com/otopcua/uns";
const string Folder = "Matrix/dev", Scalar = Folder + "/Scalar", Vector = Folder + "/Vector", Alarm = Folder + "/Alarm";
static readonly CancellationToken Ct = new CancellationTokenSource(TimeSpan.FromSeconds(int.Parse(Environment.GetEnvironmentVariable("OPCUA_LIFECYCLE_SERVER_SECONDS") ?? "240"))).Token;
static string Password => Environment.GetEnvironmentVariable("OPCUA_MATRIX_PASSWORD") ?? throw new InvalidOperationException("Missing ephemeral credential");
static readonly List<object> Cases = [];
static readonly List<object> Observations = [];
static int Failures;
static string Root = "";
static object? Clr(DataValue v)
{
#if SDK2
return ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers.ValueConverter.ToClrObject(v.WrappedValue);
#else
return v.Value;
#endif
}
static DateTime SourceTime(DataValue value)
{
#if SDK2
return value.SourceTimestamp.ToDateTime();
#else
return value.SourceTimestamp;
#endif
}
static DateTime ServerTime(DataValue value)
{
#if SDK2
return value.ServerTimestamp.ToDateTime();
#else
return value.ServerTimestamp;
#endif
}
static void Require(bool yes, string message) { if (!yes) throw new InvalidOperationException(message); }
static async Task Case(string name, Func<Task> action)
{
try { await action(); Cases.Add(new { name, status = "passed" }); }
catch (Exception e) { Failures++; Cases.Add(new { name, status = "failed", error = e.ToString() }); }
}
static async Task Wait(Func<bool> predicate)
{
for (int i = 0; i < 200; i++) { if (predicate()) return; await Task.Delay(50, Ct); }
Require(false, "Notification deadline exceeded");
}
static ConnectionSettings Settings(string endpoint) => new()
{
EndpointUrl = endpoint,
Username = "apikey",
Password = Password,
SecurityMode = SharedSecurityMode.SignAndEncrypt,
AutoAcceptCertificates = false,
CertificateStorePath = Environment.GetEnvironmentVariable("OPCUA_MATRIX_CLIENT_PKI") ?? Path.Combine(Root, "client-pki")
};
public static async Task<int> HelperMain(string[] args)
{
Root = Path.GetFullPath(args[1]); Directory.CreateDirectory(Root);
try
{
switch (args[0])
{
case "local-data-path": Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)); return 0;
case "driver": await Driver(args[2]); break;
case "server": await Serve(); return 0;
case "client": await Client(args[2]); break;
case "performance": await Performance(args[2]); break;
default: throw new ArgumentException("Expected prepare/server/client");
}
}
catch (Exception e) { Failures++; Cases.Add(new { name = "process", status = "failed", error = e.ToString() }); }
File.WriteAllText(Path.Combine(Root, "result.json"), JsonSerializer.Serialize(new { sdk = typeof(NodeId).Assembly.GetName().Version?.ToString(), process = Environment.ProcessId, cases = Cases, observations = Observations, failures = Failures, loadedSdkAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name!.StartsWith("Opc.Ua", StringComparison.Ordinal)).Select(a => new { name = a.GetName().Name, version = a.GetName().Version?.ToString(), path = a.Location }) }, new JsonSerializerOptions { WriteIndented = true }));
return Failures == 0 ? 0 : 1;
}
static async Task Serve()
{
var options = new OpcUaApplicationHostOptions
{
ApplicationName = "OtOpcUa.Matrix",
ApplicationUri = "urn:OtOpcUa.Matrix.ClientLifecycle",
PublicHostname = "127.0.0.1",
PkiStoreRoot = Path.Combine(Root, "server-pki"),
AllowAnonymous = false,
AutoAcceptUntrustedClientCertificates = false,
EnabledSecurityProfiles = Environment.GetEnvironmentVariable("OPCUA_MATRIX_SERVER_SECURITY") == "none"
? [OpcUaSecurityProfile.None] : [OpcUaSecurityProfile.Basic256Sha256SignAndEncrypt]
};
using (var listener = new TcpListener(IPAddress.Loopback, 0)) { listener.Start(); options.OpcUaPort = ((IPEndPoint)listener.LocalEndpoint).Port; }
var server = new OtOpcUaSdkServer();
await using var host = new OpcUaApplicationHost(options, NullLogger<OpcUaApplicationHost>.Instance, new Auth());
await host.StartAsync(server, Ct);
var nm = server.NodeManager!; var sink = new SdkAddressSpaceSink(nm);
var authority = new DataPlaneAuthorityState();
authority.Apply("matrix", "rev1", [new ApiKey { ApiKeyId = "matrix", Name = "matrix", SecretHash = "fixture", Principal = "matrix", Enabled = true, CreatedUtc = DateTime.UtcNow.AddDays(-1) }],
[new NodeAcl { NodeAclId = "all", ClusterId = "matrix", Principal = "matrix", ScopeKind = NodeAclScopeKind.Cluster, PermissionFlags = (NodePermissions)int.MaxValue }], new Dictionary<AclScopeRef, IReadOnlyList<NodeAclPath>>());
nm.DataPlaneAuthority = authority;
nm.Authorizer = new DataPlaneAuthorizer(authority, new TriePermissionEvaluator(authority.Tries), true, NullLogger.Instance, TimeProvider.System);
var history = new Source(Root); nm.HistorianDataSource = history;
sink.EnsureFolder(Folder, null, "dev", AddressSpaceRealm.Raw);
sink.EnsureFolder("Eq", null, "Eq", AddressSpaceRealm.Uns);
foreach (var realm in new[] { AddressSpaceRealm.Raw, AddressSpaceRealm.Uns })
{
var scalar = realm == AddressSpaceRealm.Raw ? Scalar : "Eq/Scalar";
var vector = realm == AddressSpaceRealm.Raw ? Vector : "Eq/Vector";
var parent = realm == AddressSpaceRealm.Raw ? Folder : "Eq";
sink.EnsureVariable(scalar, parent, "Scalar", "Int32", true, realm, "matrix.scalar");
sink.EnsureVariable(vector, parent, "Vector", "Int32", true, realm, isArray: true, arrayLength: 3);
sink.WriteValue(scalar, 17, 0, Epoch, realm); sink.WriteValue(vector, new[] { 1, 2, 3 }, 0, Epoch, realm);
}
sink.AddReference("Eq/Scalar", AddressSpaceRealm.Uns, Scalar, AddressSpaceRealm.Raw);
sink.MaterialiseAlarmCondition(Alarm, Folder, "Alarm", "OffNormalAlarm", 800, AddressSpaceRealm.Raw, isNative: true);
sink.WireAlarmNotifiers(Alarm, AddressSpaceRealm.Raw, ["Eq"], AddressSpaceRealm.Uns);
sink.EnsureVariable(Folder + "/UnsetTimestamp", Folder, "UnsetTimestamp", "Int32", false, AddressSpaceRealm.Raw);
sink.WriteValue(Folder + "/UnsetTimestamp", 3, 0, DateTime.MinValue, AddressSpaceRealm.Raw);
nm.NodeWriteGateway = new Gateway();
var state = new AlarmConditionSnapshot(true, false, true, true, AlarmShelvingKind.Unshelved, 800, "matrix-alarm");
nm.NativeAlarmAckRouter = _ => Task.Run(() => { state = state with { Acknowledged = true }; sink.WriteAlarmCondition(Alarm, state, DateTime.UtcNow, AddressSpaceRealm.Raw); });
File.WriteAllText(Path.Combine(Root, "endpoint.txt"), $"opc.tcp://127.0.0.1:{options.OpcUaPort}/OtOpcUa");
File.WriteAllText(Path.Combine(Root, "ready.json"), JsonSerializer.Serialize(new { endpoint = $"opc.tcp://127.0.0.1:{options.OpcUaPort}/OtOpcUa", process = Environment.ProcessId, sdk = typeof(NodeId).Assembly.GetName().Version?.ToString(), rawUri = RawUri, unsUri = UnsUri }));
int tick = 0;
while (!File.Exists(Path.Combine(Root, "stop")))
{
sink.WriteAlarmCondition(Alarm, state with { Message = ++tick % 2 == 0 ? "matrix-alarm" : "matrix-tick" }, DateTime.UtcNow, AddressSpaceRealm.Raw);
var counts = ServerCounts(server);
File.WriteAllText(Path.Combine(Root, "live-resources.tmp"), JsonSerializer.Serialize(counts));
File.Move(Path.Combine(Root, "live-resources.tmp"), Path.Combine(Root, "live-resources.json"), true);
await Task.Delay(250, Ct);
}
using var process = System.Diagnostics.Process.GetCurrentProcess();
File.WriteAllText(Path.Combine(Root, "server-resources.json"), JsonSerializer.Serialize(new { process.WorkingSet64, process.PrivateMemorySize64, process.HandleCount, threads=process.Threads.Count, cpuMilliseconds=process.TotalProcessorTime.TotalMilliseconds, allocatedBytes=GC.GetTotalAllocatedBytes(), collections=new[]{GC.CollectionCount(0),GC.CollectionCount(1),GC.CollectionCount(2)} }, new JsonSerializerOptions {WriteIndented=true}));
}
static async Task Client(string endpoint)
{
using var client = new OpcUaClientService();
await Case("trusted-SignAndEncrypt-API-key", async () => { var info = await client.ConnectAsync(Settings(endpoint), Ct); Require(info.SecurityMode == "SignAndEncrypt" && info.SecurityPolicyUri == SecurityPolicies.Basic256Sha256, "Unexpected negotiated policy"); Observations.Add(new { info.SecurityMode, info.SecurityPolicyUri }); });
if (!client.IsConnected) return;
var namespaces = (string[])Clr(await client.ReadValueAsync(VariableIds.Server_NamespaceArray, Ct))!;
var raw = (ushort)Array.IndexOf(namespaces, RawUri); var uns = (ushort)Array.IndexOf(namespaces, UnsUri);
NodeId ScalarId(ushort ns) => new(ns == raw ? Scalar : "Eq/Scalar", ns);
NodeId VectorId(ushort ns) => new(ns == raw ? Vector : "Eq/Vector", ns);
await Case("raw-UNS-URI-browse", async () =>
{
Require(raw > 0 && uns > 0, "Missing namespace URI");
var rawChildren = await client.BrowseAsync(new NodeId(Folder, raw), Ct);
var unsChildren = await client.BrowseAsync(new NodeId("Eq", uns), Ct);
Observations.Add(new { rawChildren, unsChildren });
// Supplement the production Shared results with unfiltered wire-reference metadata.
var adapter = typeof(OpcUaClientService).GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic)!.GetValue(client)!;
var sdkSession = (Opc.Ua.Client.Session)adapter.GetType().GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic)!.GetValue(adapter)!;
var (_, _, rawReferences) = await sdkSession.BrowseAsync(null, null, new NodeId(Folder, raw), 0u,
BrowseDirection.Forward, ReferenceTypeIds.References, true, 0u);
Observations.Add(new { rawReferences = (rawReferences.ToArray() ?? []).Select(reference => new { nodeId = reference.NodeId.ToString(), browseName = reference.BrowseName.ToString(), nodeClass = reference.NodeClass.ToString(), typeDefinition = reference.TypeDefinition.ToString(), referenceType = reference.ReferenceTypeId.ToString(), reference.IsForward }).ToArray() });
var expectedRaw = new[] { Scalar, Vector, Alarm, Folder + "/UnsetTimestamp" }.Select(id => new NodeId(id, raw).ToString());
Require(expectedRaw.All(id => rawChildren.Any(child => child.NodeId == id)), "Missing raw children: " + string.Join(",", expectedRaw.Where(id => !rawChildren.Any(child => child.NodeId == id))));
Require(new[] { "Eq/Scalar", "Eq/Vector" }.Select(id => new NodeId(id, uns).ToString()).All(id => unsChildren.Any(child => child.NodeId == id)), "Missing UNS scalar/array children");
});
await Case("initial-quality-explicit-source-and-server-timestamps", async () => { var initial = await client.ReadValueAsync(ScalarId(raw), Ct); Require(StatusCode.IsGood(initial.StatusCode), "Bad initial quality"); Require(SourceTime(initial) == Epoch && ServerTime(initial) > Epoch, "Lost explicit initial timestamps"); Observations.Add(new { sourceTimestamp = SourceTime(initial).ToString("O"), serverTimestamp = ServerTime(initial).ToString("O"), contract = "Source supplied as 2026-10-01T00:00:00Z; server timestamp observed without normalization or historian algorithm changes" }); });
foreach (var ns in new[] { raw, uns })
{
await Case($"scalar-read-write-ns-{ns}", async () => { Require(Clr(await client.ReadValueAsync(ScalarId(ns), Ct)) is int, "Scalar lost Int32 type"); Require(StatusCode.IsGood(await client.WriteValueAsync(ScalarId(ns), 42, Ct)), "Scalar write failed"); Require((int)Clr(await client.ReadValueAsync(ScalarId(ns), Ct))! == 42, "Scalar round trip failed"); });
await Case($"typed-array-read-write-ns-{ns}", async () => { Require(Clr(await client.ReadValueAsync(VectorId(ns), Ct)) is int[], "Array lost Int32[] type"); Require(StatusCode.IsGood(await client.WriteValueAsync(VectorId(ns), new[] { 7, 8, 9 }, Ct)), "Array write failed"); Require(((int[])Clr(await client.ReadValueAsync(VectorId(ns), Ct))!).SequenceEqual(new[] { 7, 8, 9 }), "Array round trip failed"); });
}
await Case("monitor-quality-timestamps", async () => { var seen = new ConcurrentQueue<DataValue>(); client.DataChanged += (_, e) => seen.Enqueue(e.Value); await client.SubscribeAsync(ScalarId(raw), 100, Ct); await client.WriteValueAsync(ScalarId(raw), 73, Ct); await Wait(() => seen.Any(v => Equals(Clr(v), 73))); var v = seen.Last(v => Equals(Clr(v), 73)); Require(StatusCode.IsGood(v.StatusCode) && SourceTime(v) > Epoch && ServerTime(v) > Epoch, "Bad monitor quality or missing timestamps"); Observations.Add(new { sourceTimestamp = SourceTime(v).ToString("O"), serverTimestamp = ServerTime(v).ToString("O"), status = v.StatusCode.ToString() }); await client.UnsubscribeAsync(ScalarId(raw), Ct); });
await Case("event-filter-and-native-ack", async () => { var alarms = new ConcurrentQueue<AlarmEventArgs>(); client.AlarmEvent += (_, a) => alarms.Enqueue(a); await client.SubscribeAlarmsAsync(ObjectIds.Server, 100, Ct); await Wait(() => alarms.Any(a => a.Message == "matrix-alarm" && a.ActiveState && a.Severity == 800)); var alarm = alarms.Last(a => a.Message == "matrix-alarm"); Require(alarm.EventId?.Length > 0, "Missing event ID"); Require(StatusCode.IsGood(await client.AcknowledgeAlarmAsync(new NodeId(Alarm, raw).ToString(), alarm.EventId!, "matrix-ack", Ct)), "Ack refused"); await Wait(() => alarms.Any(a => a.Message == "matrix-alarm" && a.AckedState)); await client.UnsubscribeAlarmsAsync(Ct); });
await Case("raw-history-CP-paging", async () => { var values = await client.HistoryReadRawAsync(ScalarId(raw), Epoch, Epoch.AddMinutes(1), 100, Ct); Require(values.Count == 25, "Expected 25 raw samples, got " + values.Count); Require(values.Select(v => Convert.ToInt32(Clr(v))).SequenceEqual(Enumerable.Range(0, 25)), "Raw page loss/duplicates/order"); });
await Case("event-history-CP-paging", async () =>
{
var filter = new EventFilter();
#if SDK2
filter.SelectClauses += new SimpleAttributeOperand(ObjectTypeIds.BaseEventType, new QualifiedName("EventId")) { AttributeId = Attributes.Value };
#else
filter.SelectClauses.Add(new SimpleAttributeOperand {TypeDefinitionId=ObjectTypeIds.BaseEventType,BrowsePath=new QualifiedNameCollection {new QualifiedName("EventId")},AttributeId=Attributes.Value});
#endif
var events = await client.HistoryReadEventsAsync(new NodeId(Folder, raw), Epoch, Epoch.AddMinutes(1), filter, 100, Ct); Require(events.Count == 25, "Expected 25 event samples, got " + events.Count);
#if SDK2
var ids = events.Select(e => System.Text.Encoding.UTF8.GetString((byte[])ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers.ValueConverter.ToClrObject(e.Fields[0])!));
#else
var ids=events.Select(e=>System.Text.Encoding.UTF8.GetString((byte[])e.Fields[0].Value));
#endif
Require(ids.SequenceEqual(Enumerable.Range(0, 25).Select(i => $"e{i:00}")), "Event history loss/duplicates/order across timestamp ties");
});
await Case("event-history-where-filter-positive-and-negative", async () =>
{
foreach (var type in new[] { ObjectTypeIds.BaseEventType, ObjectTypeIds.AuditEventType })
{
var filter = new EventFilter();
#if SDK2
filter.SelectClauses += new SimpleAttributeOperand(ObjectTypeIds.BaseEventType, new QualifiedName("EventId")) { AttributeId = Attributes.Value };
filter.WhereClause.Push(FilterOperator.OfType, Variant.From(type));
#else
filter.SelectClauses.Add(new SimpleAttributeOperand(ObjectTypeIds.BaseEventType,new QualifiedName("EventId")){AttributeId=Attributes.Value});
filter.WhereClause.Push(FilterOperator.OfType,new LiteralOperand(new Variant(type)));
#endif
var events = await client.HistoryReadEventsAsync(new NodeId(Folder, raw), Epoch, Epoch.AddMinutes(1), filter, 100, Ct);
Require(events.Count == (type == ObjectTypeIds.BaseEventType ? 25 : 0), $"Where filter for {type} expected {(type == ObjectTypeIds.BaseEventType ? 25 : 0)} got {events.Count}");
}
});
var unset = await client.ReadValueAsync(new NodeId(Folder + "/UnsetTimestamp", raw), Ct);
Observations.Add(new { sourceTimestamp = SourceTime(unset).ToString("O"), serverTimestamp = ServerTime(unset).ToString("O"), timestampObservation = "Fixture source supplied DateTime.MinValue (unset). These are unmodified application/SDK wire observations; no historian algorithm or expected timestamp was changed." });
await Benchmark(client, ScalarId(raw), VectorId(raw));
await client.DisconnectAsync(Ct);
}
static OpcUaClientDriverOptions DriverOptions(string endpoint) => new()
{
EndpointUrl = endpoint,
SecurityPolicy = OpcUaSecurityPolicy.Basic256Sha256,
SecurityMode = OpcUaSecurityMode.SignAndEncrypt,
AuthType = OpcUaAuthType.Username,
Username = "apikey",
Password = Password,
AutoAcceptCertificates = false,
RawTags = [new("scalar",JsonSerializer.Serialize(new {nodeId=$"nsu={RawUri};s={Scalar}"}),true),
new("vector",JsonSerializer.Serialize(new {nodeId=$"nsu={RawUri};s={Vector}"}),true),
new("uns",JsonSerializer.Serialize(new {nodeId=$"nsu={UnsUri};s=Eq/Scalar"}),true)],
SessionName = "MatrixDriver",
ApplicationUri = "urn:localhost:MatrixDriver"
};
static string IsolatedLocalData()
{
var local = Path.GetFullPath(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
Require(local.StartsWith(Path.GetFullPath(Root) + Path.DirectorySeparatorChar, StringComparison.Ordinal), "Driver/CLI canonical PKI must be in task-owned root: " + local);
return local;
}
static async Task Driver(string endpoint)
{
IsolatedLocalData();
await using var driver = new OpcUaClientDriver(DriverOptions(endpoint), "matrix");
await Case("driver-trusted-encrypted-API-key-connect", () => driver.InitializeAsync("{}", Ct));
await Case("driver-raw-UNS-URI-scalar-and-array-read", async () =>
{
var values = await driver.ReadAsync(["scalar", "vector", "uns"], Ct);
Require(values.Count == 3 && values.All(x => x.StatusCode == 0), "Read failure");
Require(values[0].Value is int && values[1].Value is int[] && values[2].Value is int, "Lost scalar/array type");
});
await Case("driver-scalar-array-write-roundtrip", async () =>
{
var writes = await driver.WriteAsync([new WriteRequest("scalar", 91), new WriteRequest("vector", new[] { 11, 12, 13 })], Ct);
Require(writes.All(x => x.StatusCode == 0), "Write failed");
var values = await driver.ReadAsync(["scalar", "vector"], Ct);
Require(Equals(values[0].Value, 91) && ((int[])values[1].Value!).SequenceEqual(new[] { 11, 12, 13 }), "Write round trip mismatch");
});
await Case("driver-monitor-quality-timestamps", async () =>
{
var seen = new ConcurrentQueue<DataValueSnapshot>();
driver.OnDataChange += (_, e) => seen.Enqueue(e.Snapshot);
var subscription = await driver.SubscribeAsync(["scalar"], TimeSpan.FromMilliseconds(100), Ct);
await driver.WriteAsync([new WriteRequest("scalar", 92)], Ct);
await Wait(() => seen.Any(x => Equals(x.Value, 92)));
var value = seen.Last(x => Equals(x.Value, 92));
Require(value.StatusCode == 0 && value.SourceTimestampUtc.HasValue && value.ServerTimestampUtc > Epoch, "Missing monitor quality/timestamps");
Observations.Add(new { value.SourceTimestampUtc, value.ServerTimestampUtc, value.StatusCode });
await driver.UnsubscribeAsync(subscription, Ct);
});
Observations.Add(new { capability = "driver-history", status = "not-applicable", evidence = "Driver has no IHistoryProvider/HistoryRead capability; .claude/rules/drivers.md #655. Shared/CLI own history." });
await driver.ShutdownAsync(Ct);
}
static async Task Performance(string endpoint)
{
using var client = new OpcUaClientService();
var info = await client.ConnectAsync(Settings(endpoint), Ct);
Require(info.SecurityMode == "SignAndEncrypt" && info.SecurityPolicyUri == SecurityPolicies.Basic256Sha256, "Unexpected benchmark endpoint policy");
var namespaces = (string[])Clr(await client.ReadValueAsync(VariableIds.Server_NamespaceArray, Ct))!;
var raw = (ushort)Array.IndexOf(namespaces, RawUri);
Require(raw > 0, "Missing benchmark raw namespace");
Observations.Add(new {info.SecurityMode, info.SecurityPolicyUri, tieredCompilation=Environment.GetEnvironmentVariable("DOTNET_TieredCompilation"), scope="Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"});
await Case("warmed-production-client-read-write-measurement", () => Benchmark(client, new NodeId(Scalar, raw), new NodeId(Vector, raw)));
await client.DisconnectAsync(Ct);
}
static async Task Benchmark(OpcUaClientService client, NodeId scalar, NodeId vector)
{
// Local diagnostic subset; excludes reconnect, history and load.
var rounds = int.Parse(Environment.GetEnvironmentVariable("OPCUA_MATRIX_PERF_ROUNDS") ?? "3");
var warmups = int.Parse(Environment.GetEnvironmentVariable("OPCUA_MATRIX_PERF_WARMUPS") ?? "10");
var measured = int.Parse(Environment.GetEnvironmentVariable("OPCUA_MATRIX_PERF_MEASURED") ?? "50");
Require(rounds > 0 && warmups >= 0 && measured > 0, "Invalid performance sample counts");
for (int round = 1; round <= rounds; round++)
{
for (int warmup = 0; warmup < warmups; warmup++)
{
await client.ReadValueAsync(scalar, Ct); await client.WriteValueAsync(scalar, warmup, Ct);
await client.ReadValueAsync(vector, Ct); await client.WriteValueAsync(vector, new[] { warmup, warmup + 1, warmup + 2 }, Ct);
}
var samples = new Dictionary<string, List<double>>();
var before = System.Diagnostics.Process.GetCurrentProcess(); var cpu = before.TotalProcessorTime;
var allocated = GC.GetTotalAllocatedBytes(); var gc = new[] { GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2) };
foreach (var operation in new[] { "scalar-read", "scalar-write", "array-read", "array-write" })
{
var times = new List<double>();
for (int i = 0; i < measured; i++)
{
var start = System.Diagnostics.Stopwatch.GetTimestamp();
if (operation == "scalar-read") await client.ReadValueAsync(scalar, Ct);
else if (operation == "scalar-write") Require(StatusCode.IsGood(await client.WriteValueAsync(scalar, i, Ct)), "Benchmark scalar write");
else if (operation == "array-read") await client.ReadValueAsync(vector, Ct);
else Require(StatusCode.IsGood(await client.WriteValueAsync(vector, new[] { i, i + 1, i + 2 }, Ct)), "Benchmark array write");
times.Add(System.Diagnostics.Stopwatch.GetElapsedTime(start).TotalMilliseconds);
}
samples[operation] = times;
}
before.Refresh();
Observations.Add(new
{
benchmarkRound = round,
warmupOperationsPerKind = 10,
operationsPerKind = 50,
latencyMilliseconds = samples.ToDictionary(x => x.Key, x => new { p50 = x.Value.Order().ElementAt((int)Math.Ceiling(measured * 0.50) - 1), p95 = x.Value.Order().ElementAt((int)Math.Ceiling(measured * 0.95) - 1), p99 = x.Value.Order().ElementAt((int)Math.Ceiling(measured * 0.99) - 1), throughputOperationsPerSecond = measured * 1000.0 / x.Value.Sum() }),
clientCpuMilliseconds = (before.TotalProcessorTime - cpu).TotalMilliseconds,
clientAllocatedBytes = GC.GetTotalAllocatedBytes() - allocated, clientAllocatedBytesPerOperation = (GC.GetTotalAllocatedBytes() - allocated) / (4.0 * measured),
clientWorkingSetBytes = before.WorkingSet64,
clientPrivateBytes = before.PrivateMemorySize64,
clientThreads = before.Threads.Count,
clientHandles = before.HandleCount,
collections = new[] { GC.CollectionCount(0) - gc[0], GC.CollectionCount(1) - gc[1], GC.CollectionCount(2) - gc[2] }
});
}
}
sealed class Auth : IOpcUaUserAuthenticator
{
public Task<OpcUaUserAuthResult> AuthenticateUserNameAsync(string username, string password, CancellationToken ct) => Task.FromResult(username == "apikey" && password == Password ? OpcUaUserAuthResult.AllowKey("matrix", [OpcUaDataPlaneRoles.WriteOperate, OpcUaDataPlaneRoles.AlarmAck], "matrix") : OpcUaUserAuthResult.Deny("Invalid ephemeral fixture key"));
}
sealed class Gateway : IOpcUaNodeWriteGateway { public Task<NodeWriteOutcome> WriteAsync(string id, object? value, AddressSpaceRealm realm, CancellationToken ct) => Task.FromResult(new NodeWriteOutcome(true, null)); }
sealed class Source(string root) : IHistorianDataSource
{
void Log(string operation, int rows) => File.AppendAllText(Path.Combine(root, "history-requests.jsonl"), JsonSerializer.Serialize(new { operation, rows }) + "\n");
public int MaxRawValuesPerRead => 7;
public Task<CoreHistory> ReadRawAsync(string r, DateTime s, DateTime e, uint m, CancellationToken ct)
{ var all = Enumerable.Range(0, 25).Select(i => new DataValueSnapshot(i, 0, Epoch.AddSeconds(i), Epoch.AddSeconds(i))).Where(v => v.SourceTimestampUtc >= s && v.SourceTimestampUtc < e).ToList(); var rows = all.Take((int)(m == 0 ? 7 : m)).ToArray(); Log("raw", rows.Length); return Task.FromResult(new CoreHistory(rows, all.Count > rows.Length ? [1] : null)); }
public Task<HistoricalEventsResult> ReadEventsAsync(string? source, DateTime s, DateTime e, int max, CancellationToken ct)
{ var all = Enumerable.Range(0, 25).Select(i => new HistoricalEvent($"e{i:00}", "matrix", Epoch.AddSeconds(i / 2), Epoch, "matrix-history", 500)).Where(v => v.EventTimeUtc >= s && v.EventTimeUtc < e).ToList(); var rows = all.Take(Math.Min(7, max <= 0 ? 7 : max)).ToArray(); Log("events", rows.Length); return Task.FromResult(new HistoricalEventsResult(rows, all.Count > rows.Length ? [1] : null)); }
public Task<CoreHistory> ReadProcessedAsync(string r, DateTime s, DateTime e, TimeSpan i, HistoryAggregateType a, CancellationToken ct) => NullHistorianDataSource.Instance.ReadProcessedAsync(r, s, e, i, a, ct);
public Task<CoreHistory> ReadAtTimeAsync(string r, IReadOnlyList<DateTime> t, CancellationToken ct) => NullHistorianDataSource.Instance.ReadAtTimeAsync(r, t, ct);
public HistorianHealthSnapshot GetHealthSnapshot() => NullHistorianDataSource.Instance.GetHealthSnapshot();
public void Dispose() { }
}
}
@@ -0,0 +1,96 @@
# Production OPC UA client lifecycle diagnostic
This standalone harness runs the unchanged production `OpcUaClientService`,
`OpcUaClientDriver`, and `OpcUaClientDriverBrowser` in one persistent Linux client
process against a separate process using the production SDK server and node
manager. Both processes load OPC Foundation SDK 2.0.1. The server fixture is a
local copy of the compatibility harness at commit `7b353d7b`; only this directory's
copy has configurable lifetime and atomic public resource snapshots.
Run a short diagnostic from a checkout containing the SDK 2.0.1 changes:
```sh
python3 scripts/validation/opcua-client-lifecycle/run.py \
--duration 90 --output /tmp/otopcua-client-lifecycle-diagnostic-unique
```
The coordinator must launch and own the full process separately:
```sh
python3 scripts/validation/opcua-client-lifecycle/run.py \
--full --duration 7200 --output /tmp/otopcua-client-lifecycle-full-unique
```
The output path must not exist. `--full` rejects a duration below 7200 seconds;
`fullTwoHourLifecycle` is true only after the client monotonic clock has actually
elapsed at least 7200 seconds and every final check completes. A diagnostic pass
cannot satisfy that gate. The outer process also has a duration plus 300-second
hard deadline and forcibly removes its own container on timeout.
The launcher publishes this standalone project, then uses the locally cached
official `mcr.microsoft.com/dotnet/sdk:10.0.103-noble` Linux arm64 image with
`--network none`, no host ports and fresh task-owned PKI. `XDG_DATA_HOME` is the
only storage environment override; it never changes `HOME`. A generated
credential stays in the child process environment. The output root is mode 0700
and contains generated private keys: **never commit the entire output directory**.
Commit only the selected redacted JSON/log receipts under `evidence/`.
Preparation invokes bounded failing connections through each product's public
API to create its own application certificate. It does not reflectively invoke
configuration builders or replace the store. Before the live session, public DER
certificates are exchanged explicitly among the three clients and server.
Autoaccept is disabled on both ends. Negotiation must be Basic256Sha256
SignAndEncrypt and API-key-shaped credentials must pass the fixture authenticator
and production authority/ACL path. Existing own DER hashes must remain unchanged
across all loop iterations.
Every cycle performs two Shared connect/read/write/subscribe/unsubscribe/
disconnect rounds on the same object. It performs two driver initialize/read/
write/subscribe/unsubscribe rounds, each followed by a live reinitialize with an
active subscription, then shutdown. It opens, browses and disposes two production
AdminUI browser sessions. Scalar Int32 and Int32[3] writes must roundtrip exactly,
and both Shared and driver scalar data notifications must arrive.
The external harness reads ownership fields for diagnostics only. Fields are
looked up by exact name, with missing/null layouts failing the run. It does not
write reflected fields or change SDK state. For SDK 2.0.1.0 only, each captured
`CertificateManager.m_disposed` boolean must be false while connected and true
after release. An independently created, deliberately disposed SDK manager proves
the before/after probe. All strong manager references are dropped each pass.
Eight released managers are checked per cycle: two Shared, four driver (including
live reinitialization), and two browser. Production session and data subscription
collections must clear, and public Shared connection information and driver health
must return to disconnected/Unknown. Collected weak references to disposed client,
driver, browser and browse-session objects must have no survivors at samples.
After every cycle the server's public session/subscription/monitored-item counts
must return to zero within a bounded settle period. Resource samples capture GC,
managed allocation/retained bytes, RSS/private bytes, global FDs and task/PKI FDs.
Owned-path FD matching canonicalizes absolute paths and uses a path-separator
boundary. Sampling starts cold, then every ten cycles and at completion. RSS and
FD observations require interpretation after warmup; they are not performance
budgets or an automatic G4 acceptance decision.
Artifacts are `result.json`, `source.json`, `command.json`, `build.log`,
`container.log`, and `task/{summary.json,resources.jsonl,sdk-assemblies.json,
client.log,server.log,prepare.log,server/live-resources.json}`. A failure additionally
writes a redacted `task/failure.txt`. The server uses a fixed application URI and
the three client certificate stores are reused for the entire process lifetime.
This is a small local lifecycle gate, not the entire Task 12 gate. It does not
cover certificate revocation, network stalls, node surgical edits/rebuild,
continuation-point abandonment/churn, representative driver fanout/load,
Windows install/publish, ScadaBridge or AVEVA interoperability. It makes no
baseline/candidate performance or full G4 claim. The coordinator's separate server
lifecycle harness supplies complementary SDK session/CP/server mutation coverage.
The checked-in 2026-11-10 diagnostic completed **91.104 seconds**, 68 cycles,
136 Shared rounds, 136 driver rounds (plus 136 live driver reinitializations),
136 browser sessions, and 544 verified released certificate managers. The final
sample had zero surviving weak product objects and zero owned PKI FDs; server
sessions/subscriptions/items returned to zero after every cycle. Warm samples
showed 146–148 total FDs; the final managed heap was 4,737,536 bytes and RSS was
181,018,624 bytes. The deliberate manager before/after control passed and
`--full --duration 90` exited 2 before creating artifacts. This is diagnostic
coverage only; the two-hour gate remains pending until a coordinator-owned full
run completes. Receipts are under `evidence/2026-11-10-diagnostic/`.
+35
View File
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Disposable network-isolated container only. All PKI is owned by this fresh task root.
set -euo pipefail
mkdir -p /task/data /task/server
export XDG_DATA_HOME=/task/data
export OPCUA_LIFECYCLE_SERVER_SECONDS=$((LIFECYCLE_SECONDS + 300))
dotnet /app/Lifecycle.dll prepare /task > /task/prepare.log 2>&1
mkdir -p /task/server/server-pki/trusted/certs
for pki in /task/data/shared-pki /task/data/OtOpcUa/pki /task/data/OtOpcUa/adminui-browse-pki; do
cp "$pki"/own/certs/* /task/server/server-pki/trusted/certs/
done
dotnet /app/Lifecycle.dll server /task/server > /task/server.log 2>&1 &
server_pid=$!
cleanup() {
touch /task/server/stop
for attempt in $(seq 1 150); do
kill -0 "$server_pid" 2>/dev/null || break
sleep 0.1
done
kill "$server_pid" 2>/dev/null || true
wait "$server_pid" || true
}
trap cleanup EXIT
for attempt in $(seq 1 600); do
test ! -f /task/server/ready.json || break
kill -0 "$server_pid" || exit 1
sleep 0.1
done
test -f /task/server/ready.json
for pki in /task/data/shared-pki /task/data/OtOpcUa/pki /task/data/OtOpcUa/adminui-browse-pki; do
mkdir -p "$pki/trusted/certs"
cp /task/server/server-pki/own/certs/* "$pki/trusted/certs/"
done
endpoint=$(cat /task/server/endpoint.txt)
dotnet /app/Lifecycle.dll run /task "$endpoint" "$LIFECYCLE_SECONDS" "$LIFECYCLE_MODE" > /task/client.log 2>&1
@@ -0,0 +1,63 @@
Determining projects to restore...
All projects are up-to-date for restore.
ZB.MOM.WW.OtOpcUa.Analyzers -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Tooling/ZB.MOM.WW.OtOpcUa.Analyzers/bin/Release/netstandard2.0/ZB.MOM.WW.OtOpcUa.Analyzers.dll
ZB.MOM.WW.OtOpcUa.Core.Abstractions -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Abstractions/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll
ZB.MOM.WW.OtOpcUa.Commons -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Commons/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Commons.dll
ZB.MOM.WW.OtOpcUa.Cluster -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Cluster.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll
ZB.MOM.WW.OtOpcUa.Core.VirtualTags -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.VirtualTags/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll
ZB.MOM.WW.OtOpcUa.Configuration -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Configuration.dll
ZB.MOM.WW.OtOpcUa.Core -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll
ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll
ZB.MOM.WW.OtOpcUa.Security -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.Security/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Security.dll
ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll
ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll
ZB.MOM.WW.OtOpcUa.ControlPlane -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.ControlPlane/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.ControlPlane.dll
ZB.MOM.WW.OtOpcUa.OpcUaServer -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll
ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll
ZB.MOM.WW.OtOpcUa.Runtime -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Runtime.dll
ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll
ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll
ZB.MOM.WW.OtOpcUa.AdminUI -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.AdminUI.dll
ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll
ZB.MOM.WW.OtOpcUa.Driver.AbCip -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll
ZB.MOM.WW.OtOpcUa.Driver.AbLegacy -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll
ZB.MOM.WW.OtOpcUa.Driver.Calculation -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Calculation/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll
ZB.MOM.WW.OtOpcUa.Driver.FOCAS -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll
ZB.MOM.WW.OtOpcUa.Driver.Galaxy -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll
ZB.MOM.WW.OtOpcUa.Driver.Modbus -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll
ZB.MOM.WW.OtOpcUa.Driver.MTConnect -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll
ZB.MOM.WW.OtOpcUa.Driver.S7 -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll
ZB.MOM.WW.OtOpcUa.Driver.TwinCAT -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll
ZB.MOM.WW.OtOpcUa.ScriptWorker -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.ScriptWorker/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.ScriptWorker.dll
ZB.MOM.WW.OtOpcUa.Host -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.Host/bin/Release/net10.0/OtOpcUa.Host.dll
ZB.MOM.WW.OtOpcUa.Client.Shared -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Client.Shared.dll
Lifecycle -> /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/scripts/validation/opcua-client-lifecycle/bin/Release/net10.0/Lifecycle.dll
Lifecycle -> /private/tmp/opcua2-production-client-diagnostic-20261110c/app/
@@ -0,0 +1,25 @@
{
"argv": [
"docker",
"run",
"--rm",
"--name",
"otopcua-client-lifecycle-a2c271bbeb54",
"--network",
"none",
"-e",
"OPCUA_MATRIX_PASSWORD",
"-e",
"LIFECYCLE_SECONDS",
"-e",
"LIFECYCLE_MODE",
"-v",
"/private/tmp/opcua2-production-client-diagnostic-20261110c/app:/app:ro",
"-v",
"/private/tmp/opcua2-production-client-diagnostic-20261110c/task:/task",
"mcr.microsoft.com/dotnet/sdk:10.0.103-noble",
"bash",
"/task/container.sh"
],
"timeoutSeconds": 390
}
@@ -0,0 +1,3 @@
usage: run.py [-h] --output OUTPUT [--duration DURATION] [--full]
[--image IMAGE]
run.py: error: --full requires duration >=7200; diagnostic duration must be positive
@@ -0,0 +1,8 @@
{"cycle":0,"elapsedSeconds":0,"utc":"2026-11-10T17:39:34.5140163Z","WorkingSet64":50884608,"PrivateMemorySize64":87019520,"managedBytes":243384,"allocatedBytes":307688,"gc":[2,2,2],"fdCount":66,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":0,"sharedPasses":0,"driverPasses":0,"browserPasses":0}
{"cycle":10,"elapsedSeconds":13.7816334,"utc":"2026-11-10T17:39:48.307566Z","WorkingSet64":168873984,"PrivateMemorySize64":210952192,"managedBytes":4622440,"allocatedBytes":53385048,"gc":[5,4,4],"fdCount":146,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":80,"sharedPasses":20,"driverPasses":20,"browserPasses":20}
{"cycle":20,"elapsedSeconds":26.955914,"utc":"2026-11-10T17:40:01.4729188Z","WorkingSet64":181080064,"PrivateMemorySize64":230060032,"managedBytes":4716120,"allocatedBytes":100286768,"gc":[8,6,6],"fdCount":146,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":160,"sharedPasses":40,"driverPasses":40,"browserPasses":40}
{"cycle":30,"elapsedSeconds":40.3288294,"utc":"2026-11-10T17:40:14.8512936Z","WorkingSet64":181923840,"PrivateMemorySize64":230674432,"managedBytes":4624608,"allocatedBytes":146998480,"gc":[11,8,8],"fdCount":146,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":240,"sharedPasses":60,"driverPasses":60,"browserPasses":60}
{"cycle":40,"elapsedSeconds":53.6437668,"utc":"2026-11-10T17:40:28.1646671Z","WorkingSet64":183074816,"PrivateMemorySize64":232931328,"managedBytes":4503968,"allocatedBytes":193703712,"gc":[14,10,10],"fdCount":148,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":320,"sharedPasses":80,"driverPasses":80,"browserPasses":80}
{"cycle":50,"elapsedSeconds":66.9338459,"utc":"2026-11-10T17:40:41.4571518Z","WorkingSet64":184758272,"PrivateMemorySize64":232972288,"managedBytes":4503736,"allocatedBytes":240424880,"gc":[17,12,12],"fdCount":148,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":400,"sharedPasses":100,"driverPasses":100,"browserPasses":100}
{"cycle":60,"elapsedSeconds":80.254683,"utc":"2026-11-10T17:40:54.7806201Z","WorkingSet64":180539392,"PrivateMemorySize64":233132032,"managedBytes":4504072,"allocatedBytes":287112440,"gc":[20,14,14],"fdCount":148,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":480,"sharedPasses":120,"driverPasses":120,"browserPasses":120}
{"cycle":68,"elapsedSeconds":91.0947059,"utc":"2026-11-10T17:41:05.614513Z","WorkingSet64":180760576,"PrivateMemorySize64":233250816,"managedBytes":4739896,"allocatedBytes":324761520,"gc":[23,16,16],"fdCount":148,"ownedRootFdCount":4,"ownedPkiFdCount":0,"survivingProductionObjects":0,"managerDisposalsVerified":544,"sharedPasses":136,"driverPasses":136,"browserPasses":136}
@@ -0,0 +1,50 @@
{
"exitCode": 0,
"containerElapsedSeconds": 93.73282008292153,
"summary": {
"status": "passed",
"diagnosticPositiveControl": "exact SDK2 manager false-before/true-after DisposeAsync",
"applicationCertificateHashes": [
"data/OtOpcUa/adminui-browse-pki/own/certs/OtOpcUa AdminUI Browse [14579B861300836A2A96549E307DB4123778B0C5].der:89e21ac01a5582dd04df77add2fad19495c695b69f4a48a05d2c71283325503b",
"data/OtOpcUa/pki/own/certs/ClientLifecycle [AF2D40052FCDDC9A8C09686E6E8E0F17CFF5A979].der:e9bdc63bc2cc0b7901389f958b2fd6bfaf5369f439dc996e152668a3fa3c381c",
"data/shared-pki/own/certs/OtOpcUaClient [91C87A8D0AC11919E0AFD44457BF932F3587F1B0].der:b4f2018a43f161e18d25f7b8bb80590ccec13afcf7b9189f6d97e10a68b55602"
],
"requestedSeconds": 90,
"elapsedSeconds": 91.1041217,
"fullTwoHourLifecycle": false,
"cycles": 68,
"sharedPasses": 136,
"driverPasses": 136,
"browserPasses": 136,
"managerDisposalsVerified": 544,
"finalResources": {
"cycle": 68,
"elapsedSeconds": 91.1041218,
"utc": "2026-11-10T17:41:05.6187359Z",
"WorkingSet64": 181018624,
"PrivateMemorySize64": 233250816,
"managedBytes": 4737536,
"allocatedBytes": 324891240,
"gc": [
25,
18,
18
],
"fdCount": 148,
"ownedRootFdCount": 4,
"ownedPkiFdCount": 0,
"survivingProductionObjects": 0,
"managerDisposalsVerified": 544,
"sharedPasses": 136,
"driverPasses": 136,
"browserPasses": 136
},
"scope": "Production Shared connect/disconnect/reconnect; production driver Initialize/Reinitialize/Shutdown/dispose; production browser open/browse/dispose; scalar and Int32[3] read/write/subscribe/unsubscribe; strict mutual trusted DER/Basic256Sha256 SignAndEncrypt/API-key fixture. No network stalls, revocation, surgical edits/rebuild, CP abandonment or Windows/AVEVA/performance G4 claim."
},
"applicationCertificates": {
"data/OtOpcUa/adminui-browse-pki/own/certs/OtOpcUa AdminUI Browse [14579B861300836A2A96549E307DB4123778B0C5].der": "89e21ac01a5582dd04df77add2fad19495c695b69f4a48a05d2c71283325503b",
"data/OtOpcUa/pki/own/certs/ClientLifecycle [AF2D40052FCDDC9A8C09686E6E8E0F17CFF5A979].der": "e9bdc63bc2cc0b7901389f958b2fd6bfaf5369f439dc996e152668a3fa3c381c",
"data/shared-pki/own/certs/OtOpcUaClient [91C87A8D0AC11919E0AFD44457BF932F3587F1B0].der": "b4f2018a43f161e18d25f7b8bb80590ccec13afcf7b9189f6d97e10a68b55602",
"server/server-pki/own/certs/OtOpcUa.Matrix [29412ADF65A3E370B5CDCABE9386217B43E1C1C1].der": "c3beb0f1c0536635c7ceb0dcfc42c6220d78d4a38c00ef199c137a6ba36bb04c"
}
}
@@ -0,0 +1,32 @@
[
{
"name": "Opc.Ua.Core",
"version": "2.0.1.0",
"sha256": "9d0857aa6b7f3c49037d4ea557b4da8edf07e146069464481783e66c5c9cd35a"
},
{
"name": "Opc.Ua.Types",
"version": "2.0.1.0",
"sha256": "c542f69882f4e8a4ebd5ccc28a3881d6967c7ffb6dcc3c56dc6c776f39c2ede1"
},
{
"name": "Opc.Ua.Security.Certificates",
"version": "2.0.1.0",
"sha256": "7f4969aceb2f0db5328c6882cb4b117342f3b18905c38acdba600683860c4fd0"
},
{
"name": "Opc.Ua.Core.Types",
"version": "2.0.1.0",
"sha256": "a7dd141b8dabe8848ff28c2fb8e16a85a0508e6a49e6b1a1c1e267175b99af96"
},
{
"name": "Opc.Ua.Client",
"version": "2.0.1.0",
"sha256": "620da406fabdbc75d11f9827ea7e39d2d3c762471bd2264b0d11f1d6cd9247cd"
},
{
"name": "Opc.Ua.Configuration",
"version": "2.0.1.0",
"sha256": "6ed6a594c93c3ff35d1a16539a9fe87c1e2640549cc2f48ed6bae333dc8bf0e7"
}
]
@@ -0,0 +1 @@
{"utc":"2026-11-10T17:41:05.3943073Z","sessions":0,"subscriptions":0,"items":0,"serverProcess":26}
@@ -0,0 +1 @@
{"endpoint":"opc.tcp://127.0.0.1:36237/OtOpcUa","process":26,"sdk":"2.0.1.0","rawUri":"https://zb.com/otopcua/raw","unsUri":"https://zb.com/otopcua/uns"}
@@ -0,0 +1,13 @@
{
"WorkingSet64": 232546304,
"PrivateMemorySize64": 263188480,
"HandleCount": 151,
"threads": 17,
"cpuMilliseconds": 11661.139,
"allocatedBytes": 334834272,
"collections": [
9,
1,
0
]
}
@@ -0,0 +1,17 @@
{
"commit": "7b353d7bae5311a2f0a33c0a82c88d2c5b49d76f",
"root": "/Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa",
"durationSeconds": 90,
"mode": "diagnostic",
"image": {
"Id": "sha256:b04611ee9e1b7d36797012ed921962c57189cb4dbb3dff12afb8e158110f293b",
"RepoDigests": [
"mcr.microsoft.com/dotnet/sdk@sha256:e362a8dbcd691522456da26a5198b8f3ca1d7641c95624fadc5e3e82678bd08a"
],
"Architecture": "arm64",
"Os": "linux"
},
"network": "none",
"startedUtc": "2026-11-10T17:39:26Z",
"scope": "actual unchanged production Shared/OpcUaClientDriver/AdminUI browser in a repeated same-process loop; SDK 2.0.1 only"
}
@@ -0,0 +1,40 @@
{
"status": "passed",
"diagnosticPositiveControl": "exact SDK2 manager false-before/true-after DisposeAsync",
"applicationCertificateHashes": [
"data/OtOpcUa/adminui-browse-pki/own/certs/OtOpcUa AdminUI Browse [14579B861300836A2A96549E307DB4123778B0C5].der:89e21ac01a5582dd04df77add2fad19495c695b69f4a48a05d2c71283325503b",
"data/OtOpcUa/pki/own/certs/ClientLifecycle [AF2D40052FCDDC9A8C09686E6E8E0F17CFF5A979].der:e9bdc63bc2cc0b7901389f958b2fd6bfaf5369f439dc996e152668a3fa3c381c",
"data/shared-pki/own/certs/OtOpcUaClient [91C87A8D0AC11919E0AFD44457BF932F3587F1B0].der:b4f2018a43f161e18d25f7b8bb80590ccec13afcf7b9189f6d97e10a68b55602"
],
"requestedSeconds": 90,
"elapsedSeconds": 91.1041217,
"fullTwoHourLifecycle": false,
"cycles": 68,
"sharedPasses": 136,
"driverPasses": 136,
"browserPasses": 136,
"managerDisposalsVerified": 544,
"finalResources": {
"cycle": 68,
"elapsedSeconds": 91.1041218,
"utc": "2026-11-10T17:41:05.6187359Z",
"WorkingSet64": 181018624,
"PrivateMemorySize64": 233250816,
"managedBytes": 4737536,
"allocatedBytes": 324891240,
"gc": [
25,
18,
18
],
"fdCount": 148,
"ownedRootFdCount": 4,
"ownedPkiFdCount": 0,
"survivingProductionObjects": 0,
"managerDisposalsVerified": 544,
"sharedPasses": 136,
"driverPasses": 136,
"browserPasses": 136
},
"scope": "Production Shared connect/disconnect/reconnect; production driver Initialize/Reinitialize/Shutdown/dispose; production browser open/browse/dispose; scalar and Int32[3] read/write/subscribe/unsubscribe; strict mutual trusted DER/Basic256Sha256 SignAndEncrypt/API-key fixture. No network stalls, revocation, surgical edits/rebuild, CP abandonment or Windows/AVEVA/performance G4 claim."
}
@@ -0,0 +1,36 @@
{
"diagnosticExitCode": 0,
"fullDurationGuardExitCode": 2,
"rawArtifactRoot": "/private/tmp/opcua2-production-client-diagnostic-20261110c",
"shortRunDoesNotMeetTwoHourGate": true,
"harnessFiles": [
{
"path": "scripts/validation/opcua-client-lifecycle/.gitignore",
"sha256": "32dae3052f331ee34d628ef535709b301259a45df7c7522c4d35dcf49873f00b"
},
{
"path": "scripts/validation/opcua-client-lifecycle/Lifecycle.cs",
"sha256": "609b73b55c4ad2ed7dcd70f42dbc702cc233cd2f9ace8c686f8fe1cbb8471f3a"
},
{
"path": "scripts/validation/opcua-client-lifecycle/Lifecycle.csproj",
"sha256": "379ce48ae014f4a52c9e9096a3fce5046689475a08408f279e430463f5f19085"
},
{
"path": "scripts/validation/opcua-client-lifecycle/ProcessHost.cs",
"sha256": "89b6f518c9706753e7f62bda4f8312e3390cf8d0ced99d847e8df52d935720d6"
},
{
"path": "scripts/validation/opcua-client-lifecycle/README.md",
"sha256": "05cc5b39f58abd7381b3eec51e0fe18bc6de6f525430810ef21b4679fe1e5d20"
},
{
"path": "scripts/validation/opcua-client-lifecycle/container.sh",
"sha256": "899cea38d6a7e21448308dea8931a3d2fe0986d736eaf96e4769ef1637ed5aae"
},
{
"path": "scripts/validation/opcua-client-lifecycle/run.py",
"sha256": "8da86e2215fcaa883a9212b6dde0e897795efd5d75307af6318345b61c965ad8"
}
]
}
+76
View File
@@ -0,0 +1,76 @@
#!/usr/bin/env python3
"""Build and run isolated actual production Shared/driver/browser lifecycle loops."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import secrets
import shutil
import subprocess
import time
import uuid
HERE = Path(__file__).resolve().parent
ROOT = HERE.parents[2]
def write(path, value):
path.write_text(json.dumps(value, indent=2) + '\n')
def certs(root):
return {str(p.relative_to(root)): hashlib.sha256(p.read_bytes()).hexdigest()
for p in sorted(root.rglob('*.der')) if '/own/certs/' in str(p)}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--output', required=True, type=Path, help='Fresh nonexistent task evidence root, includes private PKI; never commit entire output')
parser.add_argument('--duration', type=int, default=90)
parser.add_argument('--full', action='store_true', help='Requires >=7200 seconds of real completed client runtime')
parser.add_argument('--image', default='mcr.microsoft.com/dotnet/sdk:10.0.103-noble')
args = parser.parse_args()
if args.duration <= 0 or (args.full and args.duration < 7200):
parser.error('--full requires duration >=7200; diagnostic duration must be positive')
output = args.output.resolve()
output.mkdir(parents=True, exist_ok=False)
os.chmod(output, 0o700)
build = output / 'app'
task = output / 'task'
task.mkdir()
image = json.loads(subprocess.check_output(['docker', 'image', 'inspect', args.image, '--format', '{{json .}}'], text=True))
if image['Architecture'] != 'arm64' or image['Os'] != 'linux':
raise RuntimeError('Expected cached official Linux arm64 SDK image')
write(output / 'source.json', {'commit': subprocess.check_output(['git', '-C', str(ROOT), 'rev-parse', 'HEAD'], text=True).strip(),
'root': str(ROOT), 'durationSeconds': args.duration, 'mode': 'full' if args.full else 'diagnostic',
'image': {k: image.get(k) for k in ('Id', 'RepoDigests', 'Architecture', 'Os')}, 'network': 'none',
'startedUtc': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
'scope': 'actual unchanged production Shared/OpcUaClientDriver/AdminUI browser in a repeated same-process loop; SDK 2.0.1 only'})
with (output / 'build.log').open('w') as log:
subprocess.run(['dotnet', 'publish', str(HERE / 'Lifecycle.csproj'), '-c', 'Release', '-m:1', '--nologo', '-o', str(build)], stdout=log, stderr=subprocess.STDOUT, check=True, timeout=300)
shutil.copy2(HERE / 'container.sh', task / 'container.sh')
name = 'otopcua-client-lifecycle-' + uuid.uuid4().hex[:12]
env = dict(os.environ, OPCUA_MATRIX_PASSWORD='otua_lifecycle_' + secrets.token_urlsafe(32),
LIFECYCLE_SECONDS=str(args.duration), LIFECYCLE_MODE='full' if args.full else 'diagnostic')
command = ['docker', 'run', '--rm', '--name', name, '--network', 'none',
'-e', 'OPCUA_MATRIX_PASSWORD', '-e', 'LIFECYCLE_SECONDS', '-e', 'LIFECYCLE_MODE',
'-v', str(build) + ':/app:ro', '-v', str(task) + ':/task', args.image, 'bash', '/task/container.sh']
write(output / 'command.json', {'argv': command, 'timeoutSeconds': args.duration + 300})
started = time.monotonic()
try:
with (output / 'container.log').open('w') as log:
result = subprocess.run(command, stdout=log, stderr=subprocess.STDOUT, env=env, timeout=args.duration + 300)
except BaseException:
subprocess.run(['docker', 'rm', '-f', name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=20)
raise
summary = json.loads((task / 'summary.json').read_text()) if (task / 'summary.json').exists() else None
write(output / 'result.json', {'exitCode': result.returncode, 'containerElapsedSeconds': time.monotonic() - started,
'summary': summary, 'applicationCertificates': certs(task)})
if result.returncode or not summary or (args.full and not summary['fullTwoHourLifecycle']):
raise RuntimeError('Lifecycle run failed; inspect task/failure.txt, client.log and server.log: ' + str(output))
print(json.dumps({'output': str(output), 'summary': summary}, indent=2))
if __name__ == '__main__':
main()
@@ -0,0 +1,374 @@
#pragma warning disable OTOPCUA0001 // This wire harness deliberately exercises public driver capabilities directly.
using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Text.Json;
using Microsoft.Extensions.Logging.Abstractions;
using Opc.Ua;
using Opc.Ua.Client;
using ZB.MOM.WW.OtOpcUa.Client.Shared;
using ZB.MOM.WW.OtOpcUa.Client.Shared.Models;
using ZB.MOM.WW.OtOpcUa.Commons.OpcUa;
using ZB.MOM.WW.OtOpcUa.Configuration.Entities;
using ZB.MOM.WW.OtOpcUa.Configuration.Enums;
using ZB.MOM.WW.OtOpcUa.Core.Abstractions;
using ZB.MOM.WW.OtOpcUa.Core.Authorization;
using ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient;
using ZB.MOM.WW.OtOpcUa.OpcUaServer;
using ZB.MOM.WW.OtOpcUa.OpcUaServer.Security;
using AlarmEventArgs = ZB.MOM.WW.OtOpcUa.Client.Shared.Models.AlarmEventArgs;
using WriteRequest = ZB.MOM.WW.OtOpcUa.Core.Abstractions.WriteRequest;
using SharedSecurityMode = ZB.MOM.WW.OtOpcUa.Client.Shared.Models.SecurityMode;
using CoreHistory = ZB.MOM.WW.OtOpcUa.Core.Abstractions.HistoryReadResult;
internal static class ProcessHost
{
static readonly DateTime Epoch = new(2026, 10, 1, 0, 0, 0, DateTimeKind.Utc);
const string RawUri = "https://zb.com/otopcua/raw", UnsUri = "https://zb.com/otopcua/uns";
const string Folder = "Matrix/dev", Scalar = Folder + "/Scalar", Vector = Folder + "/Vector", Alarm = Folder + "/Alarm";
static readonly CancellationToken Ct = new CancellationTokenSource(TimeSpan.FromMinutes(4)).Token;
static string Password => Environment.GetEnvironmentVariable("OPCUA_MATRIX_PASSWORD") ?? throw new InvalidOperationException("Missing ephemeral credential");
static readonly List<object> Cases = [];
static readonly List<object> Observations = [];
static int Failures;
static string Root = "";
static object? Clr(DataValue v)
{
#if SDK2
return ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers.ValueConverter.ToClrObject(v.WrappedValue);
#else
return v.Value;
#endif
}
static DateTime SourceTime(DataValue value)
{
#if SDK2
return value.SourceTimestamp.ToDateTime();
#else
return value.SourceTimestamp;
#endif
}
static DateTime ServerTime(DataValue value)
{
#if SDK2
return value.ServerTimestamp.ToDateTime();
#else
return value.ServerTimestamp;
#endif
}
static void Require(bool yes, string message) { if (!yes) throw new InvalidOperationException(message); }
static async Task Case(string name, Func<Task> action)
{
try { await action(); Cases.Add(new { name, status = "passed" }); }
catch (Exception e) { Failures++; Cases.Add(new { name, status = "failed", error = e.ToString() }); }
}
static async Task Wait(Func<bool> predicate)
{
for (int i = 0; i < 200; i++) { if (predicate()) return; await Task.Delay(50, Ct); }
Require(false, "Notification deadline exceeded");
}
static ConnectionSettings Settings(string endpoint) => new()
{
EndpointUrl = endpoint,
Username = "apikey",
Password = Password,
SecurityMode = SharedSecurityMode.SignAndEncrypt,
AutoAcceptCertificates = false,
CertificateStorePath = Environment.GetEnvironmentVariable("OPCUA_MATRIX_CLIENT_PKI") ?? Path.Combine(Root, "client-pki")
};
public static async Task<int> Main(string[] args)
{
Root = Path.GetFullPath(args[1]); Directory.CreateDirectory(Root);
try
{
switch (args[0])
{
case "local-data-path": Console.WriteLine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData)); return 0;
case "prepare":
var type = typeof(OpcUaClientService).Assembly.GetType("ZB.MOM.WW.OtOpcUa.Client.Shared.Adapters.DefaultApplicationConfigurationFactory")!;
var factory = Activator.CreateInstance(type, true)!;
await (Task<ApplicationConfiguration>)type.GetMethod("CreateAsync")!.Invoke(factory, [Settings("opc.tcp://127.0.0.1:1"), Ct])!;
Console.WriteLine("PREPARED"); return 0;
case "prepare-driver": await PrepareDriver(); return 0;
case "driver": await Driver(args[2]); break;
case "server": await Serve(); return 0;
case "client": await Client(args[2]); break;
case "performance": await Performance(args[2]); break;
default: throw new ArgumentException("Expected prepare/server/client");
}
}
catch (Exception e) { Failures++; Cases.Add(new { name = "process", status = "failed", error = e.ToString() }); }
File.WriteAllText(Path.Combine(Root, "result.json"), JsonSerializer.Serialize(new { sdk = typeof(NodeId).Assembly.GetName().Version?.ToString(), process = Environment.ProcessId, cases = Cases, observations = Observations, failures = Failures, loadedSdkAssemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => a.GetName().Name!.StartsWith("Opc.Ua", StringComparison.Ordinal)).Select(a => new { name = a.GetName().Name, version = a.GetName().Version?.ToString(), path = a.Location }) }, new JsonSerializerOptions { WriteIndented = true }));
return Failures == 0 ? 0 : 1;
}
static async Task Serve()
{
var options = new OpcUaApplicationHostOptions
{
ApplicationName = "OtOpcUa.Matrix",
ApplicationUri = $"urn:OtOpcUa.Matrix.{Guid.NewGuid():N}",
PublicHostname = "127.0.0.1",
PkiStoreRoot = Path.Combine(Root, "server-pki"),
AllowAnonymous = false,
AutoAcceptUntrustedClientCertificates = false,
EnabledSecurityProfiles = Environment.GetEnvironmentVariable("OPCUA_MATRIX_SERVER_SECURITY") == "none"
? [OpcUaSecurityProfile.None] : [OpcUaSecurityProfile.Basic256Sha256SignAndEncrypt]
};
using (var listener = new TcpListener(IPAddress.Loopback, 0)) { listener.Start(); options.OpcUaPort = ((IPEndPoint)listener.LocalEndpoint).Port; }
var server = new OtOpcUaSdkServer();
await using var host = new OpcUaApplicationHost(options, NullLogger<OpcUaApplicationHost>.Instance, new Auth());
await host.StartAsync(server, Ct);
var nm = server.NodeManager!; var sink = new SdkAddressSpaceSink(nm);
var authority = new DataPlaneAuthorityState();
authority.Apply("matrix", "rev1", [new ApiKey { ApiKeyId = "matrix", Name = "matrix", SecretHash = "fixture", Principal = "matrix", Enabled = true, CreatedUtc = DateTime.UtcNow.AddDays(-1) }],
[new NodeAcl { NodeAclId = "all", ClusterId = "matrix", Principal = "matrix", ScopeKind = NodeAclScopeKind.Cluster, PermissionFlags = (NodePermissions)int.MaxValue }], new Dictionary<AclScopeRef, IReadOnlyList<NodeAclPath>>());
nm.DataPlaneAuthority = authority;
nm.Authorizer = new DataPlaneAuthorizer(authority, new TriePermissionEvaluator(authority.Tries), true, NullLogger.Instance, TimeProvider.System);
var history = new Source(Root); nm.HistorianDataSource = history;
sink.EnsureFolder(Folder, null, "dev", AddressSpaceRealm.Raw);
sink.EnsureFolder("Eq", null, "Eq", AddressSpaceRealm.Uns);
foreach (var realm in new[] { AddressSpaceRealm.Raw, AddressSpaceRealm.Uns })
{
var scalar = realm == AddressSpaceRealm.Raw ? Scalar : "Eq/Scalar";
var vector = realm == AddressSpaceRealm.Raw ? Vector : "Eq/Vector";
var parent = realm == AddressSpaceRealm.Raw ? Folder : "Eq";
sink.EnsureVariable(scalar, parent, "Scalar", "Int32", true, realm, "matrix.scalar");
sink.EnsureVariable(vector, parent, "Vector", "Int32", true, realm, isArray: true, arrayLength: 3);
sink.WriteValue(scalar, 17, 0, Epoch, realm); sink.WriteValue(vector, new[] { 1, 2, 3 }, 0, Epoch, realm);
}
sink.AddReference("Eq/Scalar", AddressSpaceRealm.Uns, Scalar, AddressSpaceRealm.Raw);
sink.MaterialiseAlarmCondition(Alarm, Folder, "Alarm", "OffNormalAlarm", 800, AddressSpaceRealm.Raw, isNative: true);
sink.WireAlarmNotifiers(Alarm, AddressSpaceRealm.Raw, ["Eq"], AddressSpaceRealm.Uns);
sink.EnsureVariable(Folder + "/UnsetTimestamp", Folder, "UnsetTimestamp", "Int32", false, AddressSpaceRealm.Raw);
sink.WriteValue(Folder + "/UnsetTimestamp", 3, 0, DateTime.MinValue, AddressSpaceRealm.Raw);
nm.NodeWriteGateway = new Gateway();
var state = new AlarmConditionSnapshot(true, false, true, true, AlarmShelvingKind.Unshelved, 800, "matrix-alarm");
nm.NativeAlarmAckRouter = _ => Task.Run(() => { state = state with { Acknowledged = true }; sink.WriteAlarmCondition(Alarm, state, DateTime.UtcNow, AddressSpaceRealm.Raw); });
File.WriteAllText(Path.Combine(Root, "endpoint.txt"), $"opc.tcp://127.0.0.1:{options.OpcUaPort}/OtOpcUa");
File.WriteAllText(Path.Combine(Root, "ready.json"), JsonSerializer.Serialize(new { endpoint = $"opc.tcp://127.0.0.1:{options.OpcUaPort}/OtOpcUa", process = Environment.ProcessId, sdk = typeof(NodeId).Assembly.GetName().Version?.ToString(), rawUri = RawUri, unsUri = UnsUri }));
int tick = 0;
while (!File.Exists(Path.Combine(Root, "stop")))
{
sink.WriteAlarmCondition(Alarm, state with { Message = ++tick % 2 == 0 ? "matrix-alarm" : "matrix-tick" }, DateTime.UtcNow, AddressSpaceRealm.Raw);
await Task.Delay(1000, Ct);
}
using var process = System.Diagnostics.Process.GetCurrentProcess();
File.WriteAllText(Path.Combine(Root, "server-resources.json"), JsonSerializer.Serialize(new { process.WorkingSet64, process.PrivateMemorySize64, process.HandleCount, threads=process.Threads.Count, cpuMilliseconds=process.TotalProcessorTime.TotalMilliseconds, allocatedBytes=GC.GetTotalAllocatedBytes(), collections=new[]{GC.CollectionCount(0),GC.CollectionCount(1),GC.CollectionCount(2)} }, new JsonSerializerOptions {WriteIndented=true}));
}
static async Task Client(string endpoint)
{
using var client = new OpcUaClientService();
await Case("trusted-SignAndEncrypt-API-key", async () => { var info = await client.ConnectAsync(Settings(endpoint), Ct); Require(info.SecurityMode == "SignAndEncrypt" && info.SecurityPolicyUri == SecurityPolicies.Basic256Sha256, "Unexpected negotiated policy"); Observations.Add(new { info.SecurityMode, info.SecurityPolicyUri }); });
if (!client.IsConnected) return;
var namespaces = (string[])Clr(await client.ReadValueAsync(VariableIds.Server_NamespaceArray, Ct))!;
var raw = (ushort)Array.IndexOf(namespaces, RawUri); var uns = (ushort)Array.IndexOf(namespaces, UnsUri);
NodeId ScalarId(ushort ns) => new(ns == raw ? Scalar : "Eq/Scalar", ns);
NodeId VectorId(ushort ns) => new(ns == raw ? Vector : "Eq/Vector", ns);
await Case("raw-UNS-URI-browse", async () =>
{
Require(raw > 0 && uns > 0, "Missing namespace URI");
var rawChildren = await client.BrowseAsync(new NodeId(Folder, raw), Ct);
var unsChildren = await client.BrowseAsync(new NodeId("Eq", uns), Ct);
Observations.Add(new { rawChildren, unsChildren });
// Supplement the production Shared results with unfiltered wire-reference metadata.
var adapter = typeof(OpcUaClientService).GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic)!.GetValue(client)!;
var sdkSession = (Opc.Ua.Client.Session)adapter.GetType().GetField("_session", BindingFlags.Instance | BindingFlags.NonPublic)!.GetValue(adapter)!;
var (_, _, rawReferences) = await sdkSession.BrowseAsync(null, null, new NodeId(Folder, raw), 0u,
BrowseDirection.Forward, ReferenceTypeIds.References, true, 0u);
Observations.Add(new { rawReferences = (rawReferences.ToArray() ?? []).Select(reference => new { nodeId = reference.NodeId.ToString(), browseName = reference.BrowseName.ToString(), nodeClass = reference.NodeClass.ToString(), typeDefinition = reference.TypeDefinition.ToString(), referenceType = reference.ReferenceTypeId.ToString(), reference.IsForward }).ToArray() });
var expectedRaw = new[] { Scalar, Vector, Alarm, Folder + "/UnsetTimestamp" }.Select(id => new NodeId(id, raw).ToString());
Require(expectedRaw.All(id => rawChildren.Any(child => child.NodeId == id)), "Missing raw children: " + string.Join(",", expectedRaw.Where(id => !rawChildren.Any(child => child.NodeId == id))));
Require(new[] { "Eq/Scalar", "Eq/Vector" }.Select(id => new NodeId(id, uns).ToString()).All(id => unsChildren.Any(child => child.NodeId == id)), "Missing UNS scalar/array children");
});
await Case("initial-quality-explicit-source-and-server-timestamps", async () => { var initial = await client.ReadValueAsync(ScalarId(raw), Ct); Require(StatusCode.IsGood(initial.StatusCode), "Bad initial quality"); Require(SourceTime(initial) == Epoch && ServerTime(initial) > Epoch, "Lost explicit initial timestamps"); Observations.Add(new { sourceTimestamp = SourceTime(initial).ToString("O"), serverTimestamp = ServerTime(initial).ToString("O"), contract = "Source supplied as 2026-10-01T00:00:00Z; server timestamp observed without normalization or historian algorithm changes" }); });
foreach (var ns in new[] { raw, uns })
{
await Case($"scalar-read-write-ns-{ns}", async () => { Require(Clr(await client.ReadValueAsync(ScalarId(ns), Ct)) is int, "Scalar lost Int32 type"); Require(StatusCode.IsGood(await client.WriteValueAsync(ScalarId(ns), 42, Ct)), "Scalar write failed"); Require((int)Clr(await client.ReadValueAsync(ScalarId(ns), Ct))! == 42, "Scalar round trip failed"); });
await Case($"typed-array-read-write-ns-{ns}", async () => { Require(Clr(await client.ReadValueAsync(VectorId(ns), Ct)) is int[], "Array lost Int32[] type"); Require(StatusCode.IsGood(await client.WriteValueAsync(VectorId(ns), new[] { 7, 8, 9 }, Ct)), "Array write failed"); Require(((int[])Clr(await client.ReadValueAsync(VectorId(ns), Ct))!).SequenceEqual(new[] { 7, 8, 9 }), "Array round trip failed"); });
}
await Case("monitor-quality-timestamps", async () => { var seen = new ConcurrentQueue<DataValue>(); client.DataChanged += (_, e) => seen.Enqueue(e.Value); await client.SubscribeAsync(ScalarId(raw), 100, Ct); await client.WriteValueAsync(ScalarId(raw), 73, Ct); await Wait(() => seen.Any(v => Equals(Clr(v), 73))); var v = seen.Last(v => Equals(Clr(v), 73)); Require(StatusCode.IsGood(v.StatusCode) && SourceTime(v) > Epoch && ServerTime(v) > Epoch, "Bad monitor quality or missing timestamps"); Observations.Add(new { sourceTimestamp = SourceTime(v).ToString("O"), serverTimestamp = ServerTime(v).ToString("O"), status = v.StatusCode.ToString() }); await client.UnsubscribeAsync(ScalarId(raw), Ct); });
await Case("event-filter-and-native-ack", async () => { var alarms = new ConcurrentQueue<AlarmEventArgs>(); client.AlarmEvent += (_, a) => alarms.Enqueue(a); await client.SubscribeAlarmsAsync(ObjectIds.Server, 100, Ct); await Wait(() => alarms.Any(a => a.Message == "matrix-alarm" && a.ActiveState && a.Severity == 800)); var alarm = alarms.Last(a => a.Message == "matrix-alarm"); Require(alarm.EventId?.Length > 0, "Missing event ID"); Require(StatusCode.IsGood(await client.AcknowledgeAlarmAsync(new NodeId(Alarm, raw).ToString(), alarm.EventId!, "matrix-ack", Ct)), "Ack refused"); await Wait(() => alarms.Any(a => a.Message == "matrix-alarm" && a.AckedState)); await client.UnsubscribeAlarmsAsync(Ct); });
await Case("raw-history-CP-paging", async () => { var values = await client.HistoryReadRawAsync(ScalarId(raw), Epoch, Epoch.AddMinutes(1), 100, Ct); Require(values.Count == 25, "Expected 25 raw samples, got " + values.Count); Require(values.Select(v => Convert.ToInt32(Clr(v))).SequenceEqual(Enumerable.Range(0, 25)), "Raw page loss/duplicates/order"); });
await Case("event-history-CP-paging", async () =>
{
var filter = new EventFilter();
#if SDK2
filter.SelectClauses += new SimpleAttributeOperand(ObjectTypeIds.BaseEventType, new QualifiedName("EventId")) { AttributeId = Attributes.Value };
#else
filter.SelectClauses.Add(new SimpleAttributeOperand {TypeDefinitionId=ObjectTypeIds.BaseEventType,BrowsePath=new QualifiedNameCollection {new QualifiedName("EventId")},AttributeId=Attributes.Value});
#endif
var events = await client.HistoryReadEventsAsync(new NodeId(Folder, raw), Epoch, Epoch.AddMinutes(1), filter, 100, Ct); Require(events.Count == 25, "Expected 25 event samples, got " + events.Count);
#if SDK2
var ids = events.Select(e => System.Text.Encoding.UTF8.GetString((byte[])ZB.MOM.WW.OtOpcUa.Client.Shared.Helpers.ValueConverter.ToClrObject(e.Fields[0])!));
#else
var ids=events.Select(e=>System.Text.Encoding.UTF8.GetString((byte[])e.Fields[0].Value));
#endif
Require(ids.SequenceEqual(Enumerable.Range(0, 25).Select(i => $"e{i:00}")), "Event history loss/duplicates/order across timestamp ties");
});
await Case("event-history-where-filter-positive-and-negative", async () =>
{
foreach (var type in new[] { ObjectTypeIds.BaseEventType, ObjectTypeIds.AuditEventType })
{
var filter = new EventFilter();
#if SDK2
filter.SelectClauses += new SimpleAttributeOperand(ObjectTypeIds.BaseEventType, new QualifiedName("EventId")) { AttributeId = Attributes.Value };
filter.WhereClause.Push(FilterOperator.OfType, Variant.From(type));
#else
filter.SelectClauses.Add(new SimpleAttributeOperand(ObjectTypeIds.BaseEventType,new QualifiedName("EventId")){AttributeId=Attributes.Value});
filter.WhereClause.Push(FilterOperator.OfType,new LiteralOperand(new Variant(type)));
#endif
var events = await client.HistoryReadEventsAsync(new NodeId(Folder, raw), Epoch, Epoch.AddMinutes(1), filter, 100, Ct);
Require(events.Count == (type == ObjectTypeIds.BaseEventType ? 25 : 0), $"Where filter for {type} expected {(type == ObjectTypeIds.BaseEventType ? 25 : 0)} got {events.Count}");
}
});
var unset = await client.ReadValueAsync(new NodeId(Folder + "/UnsetTimestamp", raw), Ct);
Observations.Add(new { sourceTimestamp = SourceTime(unset).ToString("O"), serverTimestamp = ServerTime(unset).ToString("O"), timestampObservation = "Fixture source supplied DateTime.MinValue (unset). These are unmodified application/SDK wire observations; no historian algorithm or expected timestamp was changed." });
await Benchmark(client, ScalarId(raw), VectorId(raw));
await client.DisconnectAsync(Ct);
}
static OpcUaClientDriverOptions DriverOptions(string endpoint) => new()
{
EndpointUrl = endpoint,
SecurityPolicy = OpcUaSecurityPolicy.Basic256Sha256,
SecurityMode = OpcUaSecurityMode.SignAndEncrypt,
AuthType = OpcUaAuthType.Username,
Username = "apikey",
Password = Password,
AutoAcceptCertificates = false,
RawTags = [new("scalar",JsonSerializer.Serialize(new {nodeId=$"nsu={RawUri};s={Scalar}"}),true),
new("vector",JsonSerializer.Serialize(new {nodeId=$"nsu={RawUri};s={Vector}"}),true),
new("uns",JsonSerializer.Serialize(new {nodeId=$"nsu={UnsUri};s=Eq/Scalar"}),true)],
SessionName = "MatrixDriver",
ApplicationUri = "urn:localhost:MatrixDriver"
};
static string IsolatedLocalData()
{
var local = Path.GetFullPath(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData));
Require(local.StartsWith(Path.GetFullPath(Root) + Path.DirectorySeparatorChar, StringComparison.Ordinal), "Driver/CLI canonical PKI must be in task-owned root: " + local);
return local;
}
static async Task PrepareDriver()
{
var local = IsolatedLocalData();
await using var driver = new OpcUaClientDriver(DriverOptions("opc.tcp://127.0.0.1:1"), "matrix");
// The production configuration method creates the application's own certificate without
// attempting a session. Reflection is confined to preparation; all wire operations below
// call the unchanged public driver API.
var type = typeof(OpcUaClientDriver);
var hook = Activator.CreateInstance(type.GetNestedType("CertValidationHook", BindingFlags.NonPublic)!, true)!;
await (Task<ApplicationConfiguration>)type.GetMethod("BuildApplicationConfigurationAsync", BindingFlags.Instance | BindingFlags.NonPublic)!.Invoke(driver, [hook, Ct])!;
File.WriteAllText(Path.Combine(Root, "driver-pki.txt"), Path.Combine(local, "OtOpcUa", "pki"));
}
static async Task Driver(string endpoint)
{
IsolatedLocalData();
await using var driver = new OpcUaClientDriver(DriverOptions(endpoint), "matrix");
await Case("driver-trusted-encrypted-API-key-connect", () => driver.InitializeAsync("{}", Ct));
await Case("driver-raw-UNS-URI-scalar-and-array-read", async () =>
{
var values = await driver.ReadAsync(["scalar", "vector", "uns"], Ct);
Require(values.Count == 3 && values.All(x => x.StatusCode == 0), "Read failure");
Require(values[0].Value is int && values[1].Value is int[] && values[2].Value is int, "Lost scalar/array type");
});
await Case("driver-scalar-array-write-roundtrip", async () =>
{
var writes = await driver.WriteAsync([new WriteRequest("scalar", 91), new WriteRequest("vector", new[] { 11, 12, 13 })], Ct);
Require(writes.All(x => x.StatusCode == 0), "Write failed");
var values = await driver.ReadAsync(["scalar", "vector"], Ct);
Require(Equals(values[0].Value, 91) && ((int[])values[1].Value!).SequenceEqual(new[] { 11, 12, 13 }), "Write round trip mismatch");
});
await Case("driver-monitor-quality-timestamps", async () =>
{
var seen = new ConcurrentQueue<DataValueSnapshot>();
driver.OnDataChange += (_, e) => seen.Enqueue(e.Snapshot);
var subscription = await driver.SubscribeAsync(["scalar"], TimeSpan.FromMilliseconds(100), Ct);
await driver.WriteAsync([new WriteRequest("scalar", 92)], Ct);
await Wait(() => seen.Any(x => Equals(x.Value, 92)));
var value = seen.Last(x => Equals(x.Value, 92));
Require(value.StatusCode == 0 && value.SourceTimestampUtc.HasValue && value.ServerTimestampUtc > Epoch, "Missing monitor quality/timestamps");
Observations.Add(new { value.SourceTimestampUtc, value.ServerTimestampUtc, value.StatusCode });
await driver.UnsubscribeAsync(subscription, Ct);
});
Observations.Add(new { capability = "driver-history", status = "not-applicable", evidence = "Driver has no IHistoryProvider/HistoryRead capability; .claude/rules/drivers.md #655. Shared/CLI own history." });
await driver.ShutdownAsync(Ct);
}
static async Task Performance(string endpoint)
{
using var client = new OpcUaClientService();
var info = await client.ConnectAsync(Settings(endpoint), Ct);
Require(info.SecurityMode == "SignAndEncrypt" && info.SecurityPolicyUri == SecurityPolicies.Basic256Sha256, "Unexpected benchmark endpoint policy");
var namespaces = (string[])Clr(await client.ReadValueAsync(VariableIds.Server_NamespaceArray, Ct))!;
var raw = (ushort)Array.IndexOf(namespaces, RawUri);
Require(raw > 0, "Missing benchmark raw namespace");
Observations.Add(new {info.SecurityMode, info.SecurityPolicyUri, tieredCompilation=Environment.GetEnvironmentVariable("DOTNET_TieredCompilation"), scope="Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"});
await Case("warmed-production-client-read-write-measurement", () => Benchmark(client, new NodeId(Scalar, raw), new NodeId(Vector, raw)));
await client.DisconnectAsync(Ct);
}
static async Task Benchmark(OpcUaClientService client, NodeId scalar, NodeId vector)
{
// Local diagnostic subset; excludes reconnect, history and load.
var rounds = int.Parse(Environment.GetEnvironmentVariable("OPCUA_MATRIX_PERF_ROUNDS") ?? "3");
var warmups = int.Parse(Environment.GetEnvironmentVariable("OPCUA_MATRIX_PERF_WARMUPS") ?? "10");
var measured = int.Parse(Environment.GetEnvironmentVariable("OPCUA_MATRIX_PERF_MEASURED") ?? "50");
Require(rounds > 0 && warmups >= 0 && measured > 0, "Invalid performance sample counts");
for (int round = 1; round <= rounds; round++)
{
for (int warmup = 0; warmup < warmups; warmup++)
{
await client.ReadValueAsync(scalar, Ct); await client.WriteValueAsync(scalar, warmup, Ct);
await client.ReadValueAsync(vector, Ct); await client.WriteValueAsync(vector, new[] { warmup, warmup + 1, warmup + 2 }, Ct);
}
var samples = new Dictionary<string, List<double>>();
var before = System.Diagnostics.Process.GetCurrentProcess(); var cpu = before.TotalProcessorTime;
var allocated = GC.GetTotalAllocatedBytes(); var gc = new[] { GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2) };
foreach (var operation in new[] { "scalar-read", "scalar-write", "array-read", "array-write" })
{
var times = new List<double>();
for (int i = 0; i < measured; i++)
{
var start = System.Diagnostics.Stopwatch.GetTimestamp();
if (operation == "scalar-read") await client.ReadValueAsync(scalar, Ct);
else if (operation == "scalar-write") Require(StatusCode.IsGood(await client.WriteValueAsync(scalar, i, Ct)), "Benchmark scalar write");
else if (operation == "array-read") await client.ReadValueAsync(vector, Ct);
else Require(StatusCode.IsGood(await client.WriteValueAsync(vector, new[] { i, i + 1, i + 2 }, Ct)), "Benchmark array write");
times.Add(System.Diagnostics.Stopwatch.GetElapsedTime(start).TotalMilliseconds);
}
samples[operation] = times;
}
before.Refresh();
Observations.Add(new
{
benchmarkRound = round,
warmupOperationsPerKind = 10,
operationsPerKind = 50,
latencyMilliseconds = samples.ToDictionary(x => x.Key, x => new { p50 = x.Value.Order().ElementAt((int)Math.Ceiling(measured * 0.50) - 1), p95 = x.Value.Order().ElementAt((int)Math.Ceiling(measured * 0.95) - 1), p99 = x.Value.Order().ElementAt((int)Math.Ceiling(measured * 0.99) - 1), throughputOperationsPerSecond = measured * 1000.0 / x.Value.Sum() }),
clientCpuMilliseconds = (before.TotalProcessorTime - cpu).TotalMilliseconds,
clientAllocatedBytes = GC.GetTotalAllocatedBytes() - allocated, clientAllocatedBytesPerOperation = (GC.GetTotalAllocatedBytes() - allocated) / (4.0 * measured),
clientWorkingSetBytes = before.WorkingSet64,
clientPrivateBytes = before.PrivateMemorySize64,
clientThreads = before.Threads.Count,
clientHandles = before.HandleCount,
collections = new[] { GC.CollectionCount(0) - gc[0], GC.CollectionCount(1) - gc[1], GC.CollectionCount(2) - gc[2] }
});
}
}
sealed class Auth : IOpcUaUserAuthenticator
{
public Task<OpcUaUserAuthResult> AuthenticateUserNameAsync(string username, string password, CancellationToken ct) => Task.FromResult(username == "apikey" && password == Password ? OpcUaUserAuthResult.AllowKey("matrix", [OpcUaDataPlaneRoles.WriteOperate, OpcUaDataPlaneRoles.AlarmAck], "matrix") : OpcUaUserAuthResult.Deny("Invalid ephemeral fixture key"));
}
sealed class Gateway : IOpcUaNodeWriteGateway { public Task<NodeWriteOutcome> WriteAsync(string id, object? value, AddressSpaceRealm realm, CancellationToken ct) => Task.FromResult(new NodeWriteOutcome(true, null)); }
sealed class Source(string root) : IHistorianDataSource
{
void Log(string operation, int rows) => File.AppendAllText(Path.Combine(root, "history-requests.jsonl"), JsonSerializer.Serialize(new { operation, rows }) + "\n");
public int MaxRawValuesPerRead => 7;
public Task<CoreHistory> ReadRawAsync(string r, DateTime s, DateTime e, uint m, CancellationToken ct)
{ var all = Enumerable.Range(0, 25).Select(i => new DataValueSnapshot(i, 0, Epoch.AddSeconds(i), Epoch.AddSeconds(i))).Where(v => v.SourceTimestampUtc >= s && v.SourceTimestampUtc < e).ToList(); var rows = all.Take((int)(m == 0 ? 7 : m)).ToArray(); Log("raw", rows.Length); return Task.FromResult(new CoreHistory(rows, all.Count > rows.Length ? [1] : null)); }
public Task<HistoricalEventsResult> ReadEventsAsync(string? source, DateTime s, DateTime e, int max, CancellationToken ct)
{ var all = Enumerable.Range(0, 25).Select(i => new HistoricalEvent($"e{i:00}", "matrix", Epoch.AddSeconds(i / 2), Epoch, "matrix-history", 500)).Where(v => v.EventTimeUtc >= s && v.EventTimeUtc < e).ToList(); var rows = all.Take(Math.Min(7, max <= 0 ? 7 : max)).ToArray(); Log("events", rows.Length); return Task.FromResult(new HistoricalEventsResult(rows, all.Count > rows.Length ? [1] : null)); }
public Task<CoreHistory> ReadProcessedAsync(string r, DateTime s, DateTime e, TimeSpan i, HistoryAggregateType a, CancellationToken ct) => NullHistorianDataSource.Instance.ReadProcessedAsync(r, s, e, i, a, ct);
public Task<CoreHistory> ReadAtTimeAsync(string r, IReadOnlyList<DateTime> t, CancellationToken ct) => NullHistorianDataSource.Instance.ReadAtTimeAsync(r, t, ct);
public HistorianHealthSnapshot GetHealthSnapshot() => NullHistorianDataSource.Instance.GetHealthSnapshot();
public void Dispose() { }
}
}
@@ -0,0 +1,96 @@
# OPC UA SDK process compatibility
Run from a dedicated candidate checkout with .NET 10, Python 3, PowerShell 7,
and Docker. Supply the unchanged original application's existing `host/` and
`client/` publish directories. The output directory must not already exist.
```powershell
./scripts/e2e/test-opcua-sdk-compatibility.ps1 `
-BaselineRoot /absolute/original-checkout `
-BaselineArtifacts /absolute/original-publishes `
-CandidateRoot /absolute/dedicated-candidate-checkout `
-OutputDirectory /absolute/fresh-evidence-directory
```
The baseline console references the exact published production assemblies;
it does not rebuild or edit the original application. The candidate console
references the production host, Client.Shared and OPC UA driver projects, and
the candidate CLI is separately published. Different SDK versions always run
in different processes. Source revisions, SDK assemblies, SHA-256 hashes,
commands, per-case results, actual namespace URIs, negotiated Shared security,
loaded client SDK assemblies, timestamps and backend request logs are retained.
The required Shared legs are original→candidate, candidate→original and
candidate→candidate. A fourth original→original leg provides a reference for
both the application contract and the small performance sample. Every Shared
leg checks the exact scalar, array and condition browse identities, both
namespaces by URI, typed scalar/Int32[3] read/write, monitored Good quality and
source/server timestamps, the production alarm event filter and native
acknowledgment, and complete raw/event history across continuation points.
Event-history results include timestamp ties, exact IDs/order and positive and
negative `OfType` predicates. The historian is a deterministic fixture behind
the production server's session-bound continuation store; these results do
not certify any SQL Server, QuestDB or AVEVA backend.
Server, Shared client and driver require trusted Basic256Sha256
SignAndEncrypt peers, with certificate autoaccept disabled. Public certificates
are exchanged before sessions open. The test authenticator accepts one exact,
random, API-key-shaped credential from the process environment; production
ACL, write and condition-method checks use the resulting key identity. This
fixture does not replace cryptographic API-key-authenticator coverage.
The driver and actual CLI run in a disposable `--network none` Linux container,
alongside a separate baseline or candidate server process. PKI lives only in
the mounted task directory; no host profile PKI or fleet endpoint is touched.
The driver hardcodes `LocalApplicationData/OtOpcUa/pki`, so Linux's task-local
`XDG_DATA_HOME` supplies isolation. The helper refuses a driver store outside
its task root. CLI uses its own task-local canonical store. CLI currently
forces `AutoAcceptCertificates=true` and exposes no strict-validation flag
(`CommandBase.CreateConnectionSettings`); the exchanged peers and encrypted
server remain in use, but CLI is not counted as strict client validation.
Driver history is N/A because the application removed that capability (#655);
Shared and CLI execute history reads instead.
Three measured rounds follow ten warmup operations per kind in each round:
50 scalar reads, scalar writes, array reads and array writes per kind. The
sample records nearest-rank p50/p95/p99, sequential throughput, client CPU,
allocated bytes, GC collections, working set, private bytes, threads and
handles. This is a small local diagnostic on a shared development host. It
has no production fan-out, reconnect, queue, backpressure, backend or soak
performance claim and does not establish Gate G4.
A separately published `server` helper can be used by other local consumer
checks. Supply a fresh directory and `OPCUA_MATRIX_PASSWORD` in the process
environment, then launch `dotnet ProcessHost.dll server <directory>`.
`ready.json`/`endpoint.txt` identify the ephemeral loopback port; touching
`<directory>/stop` shuts it down. Its default is strict SignAndEncrypt only.
`OPCUA_MATRIX_SERVER_SECURITY=none` is an explicit fixture-only override for
checking an existing unsecured consumer subset; the matrix runner clears that
override. Anonymous is disabled in either mode. Secure clients must place
their public certificates under `server-pki/trusted/certs` before server start
and trust the resulting `server-pki/own/certs` certificate.
Explicitly supplied timestamps are asserted. Unset source timestamps are
recorded separately as observations, with their original application/SDK wire
values. The harness does not change historian algorithms or normalize the
unset-timestamp sentinel to manufacture parity.
For the supplementary sustained warmup experiment, use the built consoles from
one completed matrix run:
```sh
python3 scripts/validation/opcua-sdk-compatibility/performance.py \
--baseline-harness /absolute/run/build-baseline/bin/Release/net10.0/ProcessHost.dll \
--candidate-harness /absolute/run/build-candidate/bin/Release/net10.0/ProcessHost.dll \
--output /absolute/fresh-performance-directory
```
This runs three fresh baseline/candidate process pairs serially, with 1,000
warmup and 2,000 measured operations per kind in each process. Both server and
client receive `DOTNET_TieredCompilation=0` for this experiment only; the
application's shipped configuration is unchanged. The recorded budget is a
15% increase in the median of the three p95 samples for any operation kind.
Exit code 2 means a diagnostic budget regression, while process failures
remain errors. Even an experiment within that budget does not certify the
complete production performance matrix. The allocation-per-operation field
is the average across all four operation kinds in a measured workload.
@@ -0,0 +1,34 @@
#!/usr/bin/env bash
# Runs only inside the disposable, network-isolated task container.
set -euo pipefail
mkdir -p /task/driver/data /task/cli/data /task/server
XDG_DATA_HOME=/task/driver/data dotnet /candidate/ProcessHost.dll prepare-driver /task/driver > /task/driver-prepare.log 2>&1
OPCUA_MATRIX_CLIENT_PKI=/task/cli/data/OtOpcUaClient/pki XDG_DATA_HOME=/task/cli/data dotnet /candidate/ProcessHost.dll prepare /task/cli > /task/cli-prepare.log 2>&1
mkdir -p /task/server/server-pki/trusted/certs
cp /task/driver/data/OtOpcUa/pki/own/certs/* /task/server/server-pki/trusted/certs/
cp /task/cli/data/OtOpcUaClient/pki/own/certs/* /task/server/server-pki/trusted/certs/
dotnet /server/ProcessHost.dll server /task/server > /task/server.log 2>&1 &
server_pid=$!
cleanup() {
touch /task/server/stop
wait "$server_pid" || true
}
trap cleanup EXIT
for attempt in $(seq 1 600); do
test ! -f /task/server/ready.json || break
kill -0 "$server_pid" || exit 1
sleep 0.1
done
test -f /task/server/ready.json
endpoint=$(cat /task/server/endpoint.txt)
mkdir -p /task/driver/data/OtOpcUa/pki/trusted/certs /task/cli/data/OtOpcUaClient/pki/trusted/certs
cp /task/server/server-pki/own/certs/* /task/driver/data/OtOpcUa/pki/trusted/certs/
cp /task/server/server-pki/own/certs/* /task/cli/data/OtOpcUaClient/pki/trusted/certs/
result=0
XDG_DATA_HOME=/task/driver/data dotnet /candidate/ProcessHost.dll driver /task/driver "$endpoint" > /task/driver.log 2>&1 || result=1
# CLI currently autoaccepts by product design; it has no strict-validation flag.
# Its public certificates are nevertheless explicitly exchanged in this fixture.
XDG_DATA_HOME=/task/cli/data dotnet /cli/ZB.MOM.WW.OtOpcUa.Client.CLI.dll read --url "$endpoint" --security signandencrypt --username apikey --password "$OPCUA_MATRIX_PASSWORD" --node 'ns=2;s=Matrix/dev/Scalar' > /task/cli-read.log 2>&1 || result=1
XDG_DATA_HOME=/task/cli/data dotnet /cli/ZB.MOM.WW.OtOpcUa.Client.CLI.dll historyread --url "$endpoint" --security signandencrypt --username apikey --password "$OPCUA_MATRIX_PASSWORD" --node 'ns=2;s=Matrix/dev/Scalar' --start 2026-10-01T00:00:00Z --end 2026-10-01T00:01:00Z --max 100 > /task/cli-raw-history.log 2>&1 || result=1
XDG_DATA_HOME=/task/cli/data dotnet /cli/ZB.MOM.WW.OtOpcUa.Client.CLI.dll historyread --url "$endpoint" --security signandencrypt --username apikey --password "$OPCUA_MATRIX_PASSWORD" --node 'ns=2;s=Matrix/dev' --start 2026-10-01T00:00:00Z --end 2026-10-01T00:01:00Z --max 100 --events --fields EventId,Message > /task/cli-event-history.log 2>&1 || result=1
exit "$result"
@@ -0,0 +1,8 @@
{
"Id": "sha256:b04611ee9e1b7d36797012ed921962c57189cb4dbb3dff12afb8e158110f293b",
"RepoDigests": [
"mcr.microsoft.com/dotnet/sdk@sha256:e362a8dbcd691522456da26a5198b8f3ca1d7641c95624fadc5e3e82678bd08a"
],
"Architecture": "arm64",
"Os": "linux"
}
@@ -0,0 +1,534 @@
{
"scope": "Early short3round,10warmup+50measured/kind, shared-host diagnostic only. This source run had insufficient alarm browse assertions and is superseded as functional evidence by run-10. Preserve these original timing observations without claiming the earlier functional matrix passed the full browse contract.",
"source": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-07/matrix.json",
"measurements": [
{
"name": "baseline-client-to-baseline-server",
"sdk": "1.5.378.0",
"observations": [
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1949,
"p95": 0.2802,
"p99": 0.3099,
"throughputOperationsPerSecond": 4941.39505465183
},
"scalar-write": {
"p50": 0.2127,
"p95": 0.2761,
"p99": 0.4201,
"throughputOperationsPerSecond": 4527.919149475669
},
"array-read": {
"p50": 0.1511,
"p95": 0.2183,
"p99": 0.3511,
"throughputOperationsPerSecond": 6323.190935073475
},
"array-write": {
"p50": 0.1346,
"p95": 0.2007,
"p99": 0.2762,
"throughputOperationsPerSecond": 6981.777560566919
}
},
"clientCpuMilliseconds": 51.315,
"clientAllocatedBytes": 1317880,
"clientWorkingSetBytes": 134643712,
"clientPrivateBytes": 0,
"clientThreads": 18,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 2,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1667,
"p95": 0.2128,
"p99": 0.2603,
"throughputOperationsPerSecond": 5854.595271828857
},
"scalar-write": {
"p50": 0.1705,
"p95": 0.2398,
"p99": 0.2455,
"throughputOperationsPerSecond": 5681.043494068992
},
"array-read": {
"p50": 0.1645,
"p95": 0.2415,
"p99": 7.8687,
"throughputOperationsPerSecond": 3070.70607815561
},
"array-write": {
"p50": 0.1646,
"p95": 0.2192,
"p99": 0.2517,
"throughputOperationsPerSecond": 5982.650314089142
}
},
"clientCpuMilliseconds": 45.783,
"clientAllocatedBytes": 1318464,
"clientWorkingSetBytes": 136298496,
"clientPrivateBytes": 0,
"clientThreads": 18,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 3,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1606,
"p95": 0.2057,
"p99": 0.2141,
"throughputOperationsPerSecond": 6152.7102688734385
},
"scalar-write": {
"p50": 0.1645,
"p95": 0.1888,
"p99": 0.1986,
"throughputOperationsPerSecond": 6050.338818973862
},
"array-read": {
"p50": 0.1262,
"p95": 0.1857,
"p99": 2.3447,
"throughputOperationsPerSecond": 5717.945199213212
},
"array-write": {
"p50": 0.1297,
"p95": 0.1718,
"p99": 0.1826,
"throughputOperationsPerSecond": 7597.05234369065
}
},
"clientCpuMilliseconds": 43.613,
"clientAllocatedBytes": 1296800,
"clientWorkingSetBytes": 137920512,
"clientPrivateBytes": 0,
"clientThreads": 18,
"clientHandles": 0,
"collections": [
1,
0,
0
]
}
]
},
{
"name": "baseline-client-to-candidate-server",
"sdk": "1.5.378.0",
"observations": [
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.2427,
"p95": 0.2798,
"p99": 0.3337,
"throughputOperationsPerSecond": 4066.528404700906
},
"scalar-write": {
"p50": 0.2384,
"p95": 0.2922,
"p99": 0.2955,
"throughputOperationsPerSecond": 4237.647258242225
},
"array-read": {
"p50": 0.2082,
"p95": 0.2556,
"p99": 0.3692,
"throughputOperationsPerSecond": 4715.602040912563
},
"array-write": {
"p50": 0.1895,
"p95": 0.295,
"p99": 0.3612,
"throughputOperationsPerSecond": 4881.811347282295
}
},
"clientCpuMilliseconds": 55.468,
"clientAllocatedBytes": 1325592,
"clientWorkingSetBytes": 134545408,
"clientPrivateBytes": 0,
"clientThreads": 19,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 2,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.2064,
"p95": 0.293,
"p99": 0.3812,
"throughputOperationsPerSecond": 4710.004992605292
},
"scalar-write": {
"p50": 0.2025,
"p95": 0.3077,
"p99": 0.4019,
"throughputOperationsPerSecond": 4707.1671326762125
},
"array-read": {
"p50": 0.1626,
"p95": 0.2309,
"p99": 0.2487,
"throughputOperationsPerSecond": 5908.2100486836525
},
"array-write": {
"p50": 0.1752,
"p95": 0.243,
"p99": 0.2937,
"throughputOperationsPerSecond": 5501.336824848437
}
},
"clientCpuMilliseconds": 45.733,
"clientAllocatedBytes": 1326672,
"clientWorkingSetBytes": 136249344,
"clientPrivateBytes": 0,
"clientThreads": 19,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 3,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1973,
"p95": 0.2547,
"p99": 0.2738,
"throughputOperationsPerSecond": 4988.62593287305
},
"scalar-write": {
"p50": 0.2038,
"p95": 0.2312,
"p99": 0.2664,
"throughputOperationsPerSecond": 4974.035534509858
},
"array-read": {
"p50": 0.16,
"p95": 0.1892,
"p99": 2.4703,
"throughputOperationsPerSecond": 4757.46446174047
},
"array-write": {
"p50": 0.195,
"p95": 0.2245,
"p99": 0.2277,
"throughputOperationsPerSecond": 5199.775369704029
}
},
"clientCpuMilliseconds": 46.975,
"clientAllocatedBytes": 1286632,
"clientWorkingSetBytes": 137936896,
"clientPrivateBytes": 0,
"clientThreads": 19,
"clientHandles": 0,
"collections": [
1,
0,
0
]
}
]
},
{
"name": "candidate-client-to-baseline-server",
"sdk": "2.0.1.0",
"observations": [
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.2241,
"p95": 0.2949,
"p99": 0.4007,
"throughputOperationsPerSecond": 4283.2055510343935
},
"scalar-write": {
"p50": 0.2197,
"p95": 0.2889,
"p99": 0.3367,
"throughputOperationsPerSecond": 4384.887922264707
},
"array-read": {
"p50": 0.1518,
"p95": 0.2545,
"p99": 0.3429,
"throughputOperationsPerSecond": 6052.902366684823
},
"array-write": {
"p50": 0.1445,
"p95": 0.2006,
"p99": 0.2097,
"throughputOperationsPerSecond": 6667.466762678188
}
},
"clientCpuMilliseconds": 63.388,
"clientAllocatedBytes": 673504,
"clientWorkingSetBytes": 128729088,
"clientPrivateBytes": 0,
"clientThreads": 20,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 2,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1828,
"p95": 0.2139,
"p99": 0.2324,
"throughputOperationsPerSecond": 5446.563762921972
},
"scalar-write": {
"p50": 0.1544,
"p95": 0.2086,
"p99": 8.8284,
"throughputOperationsPerSecond": 3001.903206633005
},
"array-read": {
"p50": 0.1853,
"p95": 0.227,
"p99": 0.2436,
"throughputOperationsPerSecond": 5281.448384404939
},
"array-write": {
"p50": 0.19,
"p95": 0.2219,
"p99": 0.2799,
"throughputOperationsPerSecond": 5251.163132633879
}
},
"clientCpuMilliseconds": 63.984,
"clientAllocatedBytes": 674328,
"clientWorkingSetBytes": 129597440,
"clientPrivateBytes": 0,
"clientThreads": 20,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 3,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1501,
"p95": 0.1844,
"p99": 0.196,
"throughputOperationsPerSecond": 6574.016855779218
},
"scalar-write": {
"p50": 0.1424,
"p95": 0.1684,
"p99": 0.1927,
"throughputOperationsPerSecond": 6859.181013786954
},
"array-read": {
"p50": 0.1601,
"p95": 0.1993,
"p99": 0.2257,
"throughputOperationsPerSecond": 6130.155460742485
},
"array-write": {
"p50": 0.1835,
"p95": 0.2002,
"p99": 0.2039,
"throughputOperationsPerSecond": 5506.911173522769
}
},
"clientCpuMilliseconds": 58.499,
"clientAllocatedBytes": 674224,
"clientWorkingSetBytes": 130433024,
"clientPrivateBytes": 0,
"clientThreads": 20,
"clientHandles": 0,
"collections": [
0,
0,
0
]
}
]
},
{
"name": "candidate-client-to-candidate-server",
"sdk": "2.0.1.0",
"observations": [
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.2968,
"p95": 0.3548,
"p99": 0.4229,
"throughputOperationsPerSecond": 3258.4115895183427
},
"scalar-write": {
"p50": 0.2754,
"p95": 0.3423,
"p99": 0.4283,
"throughputOperationsPerSecond": 3531.7718192862994
},
"array-read": {
"p50": 0.2407,
"p95": 0.2708,
"p99": 0.3132,
"throughputOperationsPerSecond": 4129.194229038145
},
"array-write": {
"p50": 0.27,
"p95": 0.3783,
"p99": 0.3875,
"throughputOperationsPerSecond": 3553.1047028893854
}
},
"clientCpuMilliseconds": 73.878,
"clientAllocatedBytes": 685360,
"clientWorkingSetBytes": 128188416,
"clientPrivateBytes": 0,
"clientThreads": 19,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 2,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.2477,
"p95": 0.2772,
"p99": 0.2965,
"throughputOperationsPerSecond": 4027.580873823946
},
"scalar-write": {
"p50": 0.2425,
"p95": 0.2885,
"p99": 0.357,
"throughputOperationsPerSecond": 4128.137384412154
},
"array-read": {
"p50": 0.2063,
"p95": 0.2431,
"p99": 0.2776,
"throughputOperationsPerSecond": 4806.07487864661
},
"array-write": {
"p50": 0.261,
"p95": 0.3474,
"p99": 0.3773,
"throughputOperationsPerSecond": 3704.060391000616
}
},
"clientCpuMilliseconds": 68.193,
"clientAllocatedBytes": 674904,
"clientWorkingSetBytes": 129024000,
"clientPrivateBytes": 0,
"clientThreads": 19,
"clientHandles": 0,
"collections": [
0,
0,
0
]
},
{
"benchmarkRound": 3,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.247,
"p95": 0.3,
"p99": 0.3212,
"throughputOperationsPerSecond": 4017.096763826847
},
"scalar-write": {
"p50": 0.211,
"p95": 0.2719,
"p99": 0.2778,
"throughputOperationsPerSecond": 4647.185664361664
},
"array-read": {
"p50": 0.2318,
"p95": 0.262,
"p99": 0.291,
"throughputOperationsPerSecond": 4246.789427193043
},
"array-write": {
"p50": 0.2428,
"p95": 0.2903,
"p99": 0.3024,
"throughputOperationsPerSecond": 4139.312708517878
}
},
"clientCpuMilliseconds": 67.128,
"clientAllocatedBytes": 682744,
"clientWorkingSetBytes": 129843200,
"clientPrivateBytes": 0,
"clientThreads": 19,
"clientHandles": 0,
"collections": [
0,
0,
0
]
}
]
}
]
}
@@ -0,0 +1,792 @@
[
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Client.dll",
"sha256": "fd000b186f4bc5dbd9947e876f96c178e8c4259ee3e8717d672a4ac2f4c3a058",
"bytes": 852096
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Configuration.dll",
"sha256": "30fb5142f13a3b3083c0484bcdedaec2efe2f50e57f10ec6a61257ca5359aa7e",
"bytes": 85120
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Core.dll",
"sha256": "602e85316943ad7ebae33a23d60a69a6ea50d91250ad0556906b816435daa37c",
"bytes": 7945344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Security.Certificates.dll",
"sha256": "a2a05c64348f6f8aa60de0fe27d8e5e22d12e09b1ba6172ca34b3773620e394c",
"bytes": 79488
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Types.dll",
"sha256": "c5c5e36cf6381444b408fe1b51726b17deca74173764cd62ccee954b3c8c2718",
"bytes": 1127552
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/ZB.MOM.WW.OtOpcUa.Client.CLI.deps.json",
"sha256": "8756470c547137f40ef9962dfa6f40c6dc2a1801cd397524dce7127fb79b70b9",
"bytes": 12175
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/ZB.MOM.WW.OtOpcUa.Client.CLI.dll",
"sha256": "38ff27df4c1389d2cf97a7ec1fe206733f02c3664b29c4fe18586ede225a53ca",
"bytes": 91648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/ZB.MOM.WW.OtOpcUa.Client.CLI.runtimeconfig.json",
"sha256": "9950d4583cfc9a106857c0d5b8a75b53e8774852b57b80bc3823a74d44a4d87f",
"bytes": 330
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "326e14df7bf2a7602637fbff36988c3dd4be38de936da24a1b4287c0ab685be6",
"bytes": 111616
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Client.dll",
"sha256": "fd000b186f4bc5dbd9947e876f96c178e8c4259ee3e8717d672a4ac2f4c3a058",
"bytes": 852096
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Configuration.dll",
"sha256": "30fb5142f13a3b3083c0484bcdedaec2efe2f50e57f10ec6a61257ca5359aa7e",
"bytes": 85120
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Core.dll",
"sha256": "602e85316943ad7ebae33a23d60a69a6ea50d91250ad0556906b816435daa37c",
"bytes": 7945344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Security.Certificates.dll",
"sha256": "a2a05c64348f6f8aa60de0fe27d8e5e22d12e09b1ba6172ca34b3773620e394c",
"bytes": 79488
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Server.dll",
"sha256": "d8d9706dea577858325730cd89896826ed82f7bfcf9503ccd0260311663a69f4",
"bytes": 642176
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Types.dll",
"sha256": "c5c5e36cf6381444b408fe1b51726b17deca74173764cd62ccee954b3c8c2718",
"bytes": 1127552
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/OtOpcUa.Host.deps.json",
"sha256": "f47fb25d83e40a5c1d96c063f1d63b02a04c222a10554220df58cac896654ea9",
"bytes": 153279
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/OtOpcUa.Host.dll",
"sha256": "e88fc71f59e69e15c3191a782c29ce44127e320c7560ddd26ce1759787806f98",
"bytes": 193024
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/OtOpcUa.Host.runtimeconfig.json",
"sha256": "eff38a9750f7cca2407b1d639a963d56ffea92088e6da971bbbfa74e3dcd7224",
"bytes": 540
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.AdminUI.dll",
"sha256": "1ae11959c22bc53a648b91c6c1ae41e4a5d717e396bd645eae4fb08dc1633597",
"bytes": 2152448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Cluster.dll",
"sha256": "d6bc21641172d832004b62b8bb76aeb40622a943be2172f394e5c6333c04ef57",
"bytes": 67584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Commons.dll",
"sha256": "be97a0b975afde7ec4ebf0b10de53c26f212ceca1f6a3ae090e40ebfde304413",
"bytes": 231424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Configuration.dll",
"sha256": "195dab9f7a9f80c45902e653ff361116a307d8110a3f87baad814bea57689b84",
"bytes": 542720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.ControlPlane.dll",
"sha256": "36954f51b09930df414675e5a0c038933ad2b27cd6560bf797d99801c02b30a1",
"bytes": 179200
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll",
"sha256": "b0f4e332ced57eae3ab1dcc282c073f51ea0c545a381aef50479ee58f0c23efc",
"bytes": 124416
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll",
"sha256": "a61a6ea68236dd4ed86ab4e74e4d632c5e260103aa5ebd92f4f995eb9f170b22",
"bytes": 56320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll",
"sha256": "f1e429c0b8fcab8216b9107440008b92eea1236ff1225e79580ad70f51d56431",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll",
"sha256": "ea24898698c8351bc9cf20fcce725dccc93ccf05ef3af7783f73854cc2033c31",
"bytes": 13312
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll",
"sha256": "cf44009a720a00bf9192374d371c7c76e75afbe62cc216b5c1be913b92679127",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll",
"sha256": "07800332d0842b93c3987fca1dc10a1390bcb16f44567610d867513ad9fe17e0",
"bytes": 117248
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll",
"sha256": "9637b7ffb4984f54bc54363ff2d81b6a3401f0cb7eeed8694db626ef41d54d5b",
"bytes": 121856
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll",
"sha256": "107aaf2ef2d7704e320dabc1072bc50217faabb2d1488e66c91b1f756b440c45",
"bytes": 11264
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.dll",
"sha256": "34a4d7c0dddf4efa5fae91a3798c2f1c08b992faf4a827a9e05ed1338c6e4720",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll",
"sha256": "315dcc540d304c9f1d5b48caa25e5f081569f1a41aa8784cf371c1d6cef7322d",
"bytes": 123392
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll",
"sha256": "d7b34798587d0939cc78eb69d9df1d617c1c75a61b8dd11a5308958a43a8c4f1",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll",
"sha256": "73073627fcdc8079df645478d6717576975117c3b21cfa7e9422f1e3bc5f4e44",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll",
"sha256": "5c66d76dd455c42f0c5b0aed11240fa31e1bdbd2f0a8368d8f41976977e93502",
"bytes": 30720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll",
"sha256": "cbf92a935d86596a9d4dbeeaa625e304c2045851a0367c3a6b0de03bf78bd6fa",
"bytes": 136704
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll",
"sha256": "29c079414497b30debe8d3ecd7e77bdc4eb16c4fc076e675680a2e880e54b6c2",
"bytes": 10240
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll",
"sha256": "132e36042a4691cc8e252ab9e9d8c90592fcd897959f533aa37e33f193cf00c8",
"bytes": 57344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll",
"sha256": "2bdbf743194193d5a7bc323912e2c7f740cc21633154a4a3cc8e034fd15bb7e8",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll",
"sha256": "17c28f27fdecd09a46b971b19655bdb933f84990e91bb80c7092c344a0ca974f",
"bytes": 300032
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll",
"sha256": "f2796d323c222708c28cd0a4289c46db31ec3b6537da7f5cd260fc76f8abdc76",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll",
"sha256": "780a11f69194713e2f87e74277e99882ee3518b2824551b45cd04e3b9bdf6648",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll",
"sha256": "a8e19baa5a736544d914f942d526a5cc038f6b982451bfa82a77365a159434e4",
"bytes": 224768
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll",
"sha256": "400b1896e55d08781231efeba302596299df2b00b2f48afd43d46c22d59b515c",
"bytes": 129536
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll",
"sha256": "8e91a8cce804023639a4bdb2dc60f9fc950992882e50786d45ceeb0f38ed1f68",
"bytes": 167424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll",
"sha256": "2746b8e9c03b5b8c330152803eee91cf2069f0e6c074d70d03017b1f1f1a2398",
"bytes": 51712
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll",
"sha256": "94b9bcd4506427a44158e0b299a5ae7bcee14fd40b85cc9f63420e4631aa1a6f",
"bytes": 143872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll",
"sha256": "6582151085ddea7d319b990c2c58057b6ba5a49860593229b3642dff527ae204",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll",
"sha256": "c9670c5d169056563294673839ca63321a72a438c519263be708b55f3fc818f9",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll",
"sha256": "ed07d04709372ef804f465995431b15acdef791f66c8130ab7282372728f7cda",
"bytes": 25088
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll",
"sha256": "724873ac2f6c08f307a150c5575cc3c022d7e367124ed924c0c7899b0e9575a5",
"bytes": 39424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll",
"sha256": "db1e3e7c79dc1a46e1d4ffaa5ea1aac9ed73814d7f06cbfa855ebb3b27a8810d",
"bytes": 131584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll",
"sha256": "ace18db746c30307e67efa3acd68e915cc2b62b0a85bdba833df4ea7c85b5f6c",
"bytes": 48128
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll",
"sha256": "24e795bd8027d7b3ca3d95630b73be6d7cef774243357b01850f145b6066dcb9",
"bytes": 139776
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll",
"sha256": "bec0cecc0bbb06b4715d7b909ccf4d357420e120b2bff3c10ee9f59f71044927",
"bytes": 12800
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll",
"sha256": "da64eacb80ddca9cd0a40295bba2c8ff81ee9c68ccaf32cbd329ae854375deb7",
"bytes": 195072
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll",
"sha256": "7e2ac501136d24a3d0ad6bdae2e4a47460439ad8ab78af538bbccca2e38e5695",
"bytes": 35840
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll",
"sha256": "c15e6db37681cbbef8684d5301e1bba54186ae503aaf55d1c2d06a0567ab28fe",
"bytes": 20480
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll",
"sha256": "910604abd4daa6196c8fdcd2db085873ee5a4c27b5a67c359590071117c6e4dd",
"bytes": 16384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll",
"sha256": "cd689b0ec777820d91f914abfd9e4a921143a46df84ee43d0214c66f74225ac0",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll",
"sha256": "6fe895674318dc42c0c3cc74266831862d3fe2f13098c26e7d826baf79d7fc47",
"bytes": 29696
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.S7.dll",
"sha256": "d23a7ac62d781f0c14dd7c9d4f51b712c13599ee78b9b6d302d30dfd5e77da37",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll",
"sha256": "c341d49bf100e0617d9c4e7d24f63d8affd1bc0fe2edce15e51cc14366fa2207",
"bytes": 43008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll",
"sha256": "f0a0cc852116f739247422a0427550e52c938b27d1a8b4e685f45a19a23635ab",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll",
"sha256": "7d78655da50c07ac049cd687c59f2a7b6eb2c491543bd4089ffbe60fb805205f",
"bytes": 40448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll",
"sha256": "6ec1a9bc7443c1d7b8084ee2fc5e67cbfd2a8d61add303a980cef78a46cb5c67",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll",
"sha256": "96db9e5d162b19914cf0ba55c1408c1c9271c80c1a1a12604e684f5785de4b96",
"bytes": 17408
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll",
"sha256": "c24cfc897bde6c0eb65b9958bad952814ed02a27fe25a55c416c1ba61be2c261",
"bytes": 188928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll",
"sha256": "ee1f704fa1574b77bf56cef415c47c33a4428c6852db52bb1443d6765d092cb1",
"bytes": 363008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Runtime.dll",
"sha256": "50e752383ae81ef6bb23e360fafe9162be0d1dcb7dd2d8731f16bce762834dd4",
"bytes": 539648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Security.dll",
"sha256": "a88b1577d1e4dd580e012e7673e31d5363c3d9a79fb415bef4c3d63849678a4d",
"bytes": 52736
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-baseline-oracle/OtOpcUa/Directory.Packages.props",
"sha256": "7e6459447843b93bc94fbc1f3eeb1c695b5c46c08aeb94debe86a7d419c63221",
"bytes": 18829
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/Directory.Packages.props",
"sha256": "31a4cac1c205f5b9e67119357c77751b8ab999f6c5f350da68784614040c8a93",
"bytes": 19000
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"sha256": "841f83aeb3a32d49c06518a98963743d720015bba41ae3138649126ce3a6af1c",
"bytes": 94720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Client.dll",
"sha256": "620da406fabdbc75d11f9827ea7e39d2d3c762471bd2264b0d11f1d6cd9247cd",
"bytes": 2442880
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Configuration.dll",
"sha256": "6ed6a594c93c3ff35d1a16539a9fe87c1e2640549cc2f48ed6bae333dc8bf0e7",
"bytes": 117376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Schema.dll",
"sha256": "51cfad48657d95d38074bb88be29aea6f5b361a07397247d58838d066b99772e",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Types.dll",
"sha256": "a7dd141b8dabe8848ff28c2fb8e16a85a0508e6a49e6b1a1c1e267175b99af96",
"bytes": 12703872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Core.dll",
"sha256": "9d0857aa6b7f3c49037d4ea557b4da8edf07e146069464481783e66c5c9cd35a",
"bytes": 2549376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll",
"sha256": "7f4969aceb2f0db5328c6882cb4b117342f3b18905c38acdba600683860c4fd0",
"bytes": 118400
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Server.dll",
"sha256": "930e714a2f6e15d393840bcdc95e1afa8012bc740c3738a655f958142721864e",
"bytes": 3332224
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/Opc.Ua.Types.dll",
"sha256": "c542f69882f4e8a4ebd5ccc28a3881d6967c7ffb6dcc3c56dc6c776f39c2ede1",
"bytes": 1792640
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/OtOpcUa.Host.deps.json",
"sha256": "c289766446d61a6bf15574fdde982a8c44b6faaabb38ad718522f63987a58d69",
"bytes": 179492
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/OtOpcUa.Host.dll",
"sha256": "a4ac1663a8af08aec150e02c5a9590e6fd346d051256ebbd9ee16019f2ecc6a2",
"bytes": 193024
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/OtOpcUa.Host.runtimeconfig.json",
"sha256": "eff38a9750f7cca2407b1d639a963d56ffea92088e6da971bbbfa74e3dcd7224",
"bytes": 540
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.deps.json",
"sha256": "cb76c2da9266dd11b61483fc9425d8a7ed3e25c83b1179ef60bfbd559b7db77c",
"bytes": 165039
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"sha256": "e025fc21ac3559c3796ec639f0ef7b9c3026ccbbdaa4783e14b8930eae3a2043",
"bytes": 95232
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.runtimeconfig.json",
"sha256": "bdbb6b43e509fbbab6c78b7004c4debf1e9791a648a08f730ff5997f71ef7099",
"bytes": 508
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.AdminUI.dll",
"sha256": "0f76616b8ddccdb681a9e576f7d031a58b0f5e257d579f58b2143679c27afbe6",
"bytes": 2152448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "49729f0e97e752a65fa2f8debb4ea5505a7ccdfe9ca1321ae6bf8ce5323a7049",
"bytes": 120320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Cluster.dll",
"sha256": "4ea4a506d94ecd032b41e0e3643f2d407e9904759c892ffa14a28483ad82862e",
"bytes": 67584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Commons.dll",
"sha256": "b77b9502c43e126cdb730b535dbd01c76f9f4ad4c79765ba6e7ea447938e3834",
"bytes": 231424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Configuration.dll",
"sha256": "f7f91c501acd81f7bf2d71740f2141d2cc134248388d2f43f78bb16fbf2e7c37",
"bytes": 542720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.ControlPlane.dll",
"sha256": "54484082b7d785727c1bbb4cd430542e2c101f31801ef3fe113b99efc8e347c2",
"bytes": 179200
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll",
"sha256": "c4be146d49102962324a2e4af71f17b2804e6003a82954733dd6302632e5e249",
"bytes": 124416
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll",
"sha256": "71d20c01ccafb8327ee474f1133a7b265d4252872ac9f6fb0b78fe2c8d6e636f",
"bytes": 56320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll",
"sha256": "3ad5440cb4c1644cad844c50a28ac9c0f9534795a6a553df446fb701c34c191a",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll",
"sha256": "88d9ee543a6a8525a4074ecb9524ce5c095e1bbba8017bde980964cb53da447f",
"bytes": 13312
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll",
"sha256": "c889dd89aad72e130439e916371ec4e63f0abbf10f7934e42caf504d5227aadb",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll",
"sha256": "6b21c826e93a1f8d942f2ee101d522d2566b8e8fd8b2ef223b4ca75f679d7118",
"bytes": 117248
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll",
"sha256": "f36de3c774ece202f34288c7bee877cbee3d14a688ae8b07aede00ba016f5b57",
"bytes": 121856
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll",
"sha256": "21893da38bf83afe3cb90f6a4d8caed6bb5db837fecc0c819f88ea7e17c73a27",
"bytes": 11264
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.dll",
"sha256": "7aec5cb22b6a9939044502eaedf188a5e95887057b6cc7a70b0444ff83f1802b",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll",
"sha256": "86db4c0cbca35c13f9ffaa258ecc54e15fb05c4b5fbda991909f00793a26a1dc",
"bytes": 123392
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll",
"sha256": "862f63ab4499d1e32cd5a3d7245dca4158398a7d546d5a882be37cb9e4738de8",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll",
"sha256": "bd5d38bc81fef735143ba58d2158e1cb37b2b9998e32ebb7765a1eea6111c8c5",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll",
"sha256": "a0b596bcd65014cafac896c17d1247e0c7cfef076952aee7096d90377ee3aedf",
"bytes": 30720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll",
"sha256": "fdf201aaccbaf10b53eb07f0b627e8ffd3955ec78b3e446be85c03e1ad7ff687",
"bytes": 136704
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll",
"sha256": "36033badc6dcfa646592dfe00aa184c657b24f7d73f17c4574853727275c320f",
"bytes": 10240
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll",
"sha256": "6124ecc4dae44b0f4012f03d3583c86ce4d0766205386ff7c70f319c77220e87",
"bytes": 57344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll",
"sha256": "150a79b5d38205d573399e29a2924eeb62c17261729c82bbf6c606a769f03467",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll",
"sha256": "b45e29a1d892ae00e914839dfe1001c6eb15ce14af1f9800a0ff48a5517d8dd6",
"bytes": 300032
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll",
"sha256": "87f8d77edc62c8d1c60e69620b297b1cef75b91355c871aae707e3f05f30e267",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll",
"sha256": "4eaad55f82495fedcf82a9be3157c748d2fc6b6f59eb7ea41bff88b18332dd51",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll",
"sha256": "e336053cc6fd0cb57615d2333c9ea99a2a9acac9273c8927af82c3fc551157ac",
"bytes": 224768
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll",
"sha256": "e6f7ebfb5b8078a336601a7603a094ac743c4adbf02bb311dfef29d2328eeb65",
"bytes": 129536
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll",
"sha256": "55e7cf55c8fece377cdef598f901e4347b2da13ab7feb265623866c08bad477f",
"bytes": 167424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll",
"sha256": "b033a90e65f7b67a8ab7ef5c614019a54c12dd5590fc9eae17fca4b736918373",
"bytes": 51712
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll",
"sha256": "685e8961b23190b745568955a34cca1462dffce15007c25a2265f44fd1224436",
"bytes": 143872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll",
"sha256": "a592d1481ea662ef368d07f706e70779a1f879126101f17042ce270c5faa66c3",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll",
"sha256": "1ca66a30106c4b9476eed6b766ae78a59cbf6b408814e2cce9f1d7fd68773762",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll",
"sha256": "2cb7c0cd79d399bce99f66d40fedbc002aad0d1204c252c1f62a7edd83e73b09",
"bytes": 25088
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll",
"sha256": "a8fd87c6a32b45b91d1c6e12c597916a20d5c254d137a7f8d9bb6cfe473ca674",
"bytes": 39424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll",
"sha256": "84723c305417dd10440345acefb50c33f47d55b34543584abf7d9235ad13df86",
"bytes": 131584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll",
"sha256": "a5c4262f0a0d378d99a89016d6b7fa927632ff5d99bcc5de52a1ceb359ad2d5c",
"bytes": 48128
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll",
"sha256": "f4328140545f1c8e2226865ceac9d309b8f55bbee0ed5e9713836f16bc0aff63",
"bytes": 139776
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll",
"sha256": "b592a854bb997781a1f1d316a615f629cb3fb08dad683f2fdbff2867210cc43b",
"bytes": 12800
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll",
"sha256": "4d63899c81316a0d9f856b59759e97dd9b52d53b00ae5fd57a2cdfc916fc73ea",
"bytes": 195072
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll",
"sha256": "a21d73fbd9dfd60ebf4ac56a961e172473f54e55727dc1ad856991c9e1ba756c",
"bytes": 36352
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll",
"sha256": "2e45346638a6814dc6af3f8c99ea448bd2538267baf645453e818fe702265157",
"bytes": 20480
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll",
"sha256": "a9052366f2c27e485bf9a1d6c3150459f54aa1c510b63d01d99a9270ff95f3bc",
"bytes": 19968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll",
"sha256": "3bbe213152adee004934b4fbb612957b6891461f69c20e55459b5a03660a2915",
"bytes": 147968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll",
"sha256": "0610e0f7ba83fb3c3768e4909fb1d2fa0d698608c58606b31235b782813b65ca",
"bytes": 29696
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.dll",
"sha256": "f1300ad64b7ddfde76078e9f174a10875a6e7f6a5bdf5d20ae3cdf1c94aecee9",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll",
"sha256": "0965780c6b2c8f14884e98e1e8f89d7d54d3d74473987cf63f5b97f98b147fef",
"bytes": 43008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll",
"sha256": "b705643ccd5e85e11bd585d8258c9d4bb78268bd5664ec20a7310cd92a955751",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll",
"sha256": "3ba6f0217710d3c69b1cd7baaaa99a1b43fae3b0d27da66efba6f0c58475fd91",
"bytes": 40448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll",
"sha256": "17b472fe49541f794dccdc2490cda075fc746a515195dd5cee9b1250ef7e702c",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll",
"sha256": "6b0ea052040c218b70cf2d31c437be7dc474ce6e000395259a9ce4055fd1ce0f",
"bytes": 17408
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll",
"sha256": "ecdb122f3800af6ebb07421f0987e9e1561645a10bd05c86000974ce6c898060",
"bytes": 188928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll",
"sha256": "40a65a2124fb917d6c5fe38e648ff3c5db9fb96672fd9ff1233992bd5cc17abc",
"bytes": 420864
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Runtime.dll",
"sha256": "a66420c048d83ad43f923fb3b97a07078df570d56a1bb5b2ce8406d6f9cbb4a0",
"bytes": 539648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Security.dll",
"sha256": "daf52ae4d37a05f00819d837456d1db8191cd721794a12363a4424af46f0801e",
"bytes": 52736
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/Opc.Ua.Client.dll",
"sha256": "620da406fabdbc75d11f9827ea7e39d2d3c762471bd2264b0d11f1d6cd9247cd",
"bytes": 2442880
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/Opc.Ua.Configuration.dll",
"sha256": "6ed6a594c93c3ff35d1a16539a9fe87c1e2640549cc2f48ed6bae333dc8bf0e7",
"bytes": 117376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/Opc.Ua.Core.Schema.dll",
"sha256": "51cfad48657d95d38074bb88be29aea6f5b361a07397247d58838d066b99772e",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/Opc.Ua.Core.Types.dll",
"sha256": "a7dd141b8dabe8848ff28c2fb8e16a85a0508e6a49e6b1a1c1e267175b99af96",
"bytes": 12703872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/Opc.Ua.Core.dll",
"sha256": "9d0857aa6b7f3c49037d4ea557b4da8edf07e146069464481783e66c5c9cd35a",
"bytes": 2549376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/Opc.Ua.Security.Certificates.dll",
"sha256": "7f4969aceb2f0db5328c6882cb4b117342f3b18905c38acdba600683860c4fd0",
"bytes": 118400
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/Opc.Ua.Types.dll",
"sha256": "c542f69882f4e8a4ebd5ccc28a3881d6967c7ffb6dcc3c56dc6c776f39c2ede1",
"bytes": 1792640
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/ZB.MOM.WW.OtOpcUa.Client.CLI.deps.json",
"sha256": "e1a36de862f9d940bfb55e09db02461bc20f2bd12dad30c8a8bca81ac38be40a",
"bytes": 37379
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/ZB.MOM.WW.OtOpcUa.Client.CLI.dll",
"sha256": "bf1029417276643c6e7b632b882d3fc87c611e52f9e2fdd428e94d2e11f0513e",
"bytes": 92160
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/ZB.MOM.WW.OtOpcUa.Client.CLI.runtimeconfig.json",
"sha256": "9950d4583cfc9a106857c0d5b8a75b53e8774852b57b80bc3823a74d44a4d87f",
"bytes": 330
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "49729f0e97e752a65fa2f8debb4ea5505a7ccdfe9ca1321ae6bf8ce5323a7049",
"bytes": 120320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/scripts/validation/opcua-sdk-compatibility/ProcessHost.cs",
"sha256": "724bca278fadcb44d086888415df7608acc9be56443682d4d5a08377f1aaccef",
"bytes": 30352
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/scripts/validation/opcua-sdk-compatibility/container-leg.sh",
"sha256": "1f5d1158572379b8a6304c3a3134a78c112043940f5bce468621677f7da3ef9e",
"bytes": 2589
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/scripts/validation/opcua-sdk-compatibility/run.py",
"sha256": "b94c880c0828b3bf9b330e142077dd5ef256cf6a27b037fd48a44361975fe5b6",
"bytes": 12587
}
]
@@ -0,0 +1,202 @@
[
{
"argv": [
"dotnet",
"build",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/ProcessHost.csproj",
"-c",
"Release",
"-m:1",
"--nologo"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/build.log"
},
{
"argv": [
"dotnet",
"build",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/ProcessHost.csproj",
"-c",
"Release",
"-m:1",
"--nologo"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/build.log"
},
{
"argv": [
"dotnet",
"publish",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/ZB.MOM.WW.OtOpcUa.Client.CLI.csproj",
"-c",
"Release",
"-o",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli",
"-m:1",
"--nologo"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli-build.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-baseline-server/shared"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-baseline-server/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-baseline-server/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-baseline-server/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"client",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-baseline-server/shared",
"opc.tcp://127.0.0.1:55610/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-baseline-server/shared.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-candidate-server/shared"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-candidate-server/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-candidate-server/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-candidate-server/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"client",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-candidate-server/shared",
"opc.tcp://127.0.0.1:55642/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/baseline-client-to-candidate-server/shared.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-baseline-server/shared"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-baseline-server/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-baseline-server/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-baseline-server/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"client",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-baseline-server/shared",
"opc.tcp://127.0.0.1:55671/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-baseline-server/shared.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-candidate-server/shared"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-candidate-server/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-candidate-server/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-candidate-server/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"client",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-candidate-server/shared",
"opc.tcp://127.0.0.1:55697/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-client-to-candidate-server/shared.log"
},
{
"argv": [
"docker",
"run",
"--rm",
"--name",
"otopcua-sdk2-matrix-222d08944aba",
"--network",
"none",
"-e",
"OPCUA_MATRIX_PASSWORD",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0:/candidate:ro",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-baseline/bin/Release/net10.0:/server:ro",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli:/cli:ro",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-driver-cli-to-baseline-server:/task",
"mcr.microsoft.com/dotnet/sdk:10.0.103-noble",
"bash",
"/task/run.sh"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-driver-cli-to-baseline-server/container.log"
},
{
"argv": [
"docker",
"run",
"--rm",
"--name",
"otopcua-sdk2-matrix-00f1df5c1613",
"--network",
"none",
"-e",
"OPCUA_MATRIX_PASSWORD",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0:/candidate:ro",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/build-candidate/bin/Release/net10.0:/server:ro",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-cli:/cli:ro",
"-v",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-driver-cli-to-candidate-server:/task",
"mcr.microsoft.com/dotnet/sdk:10.0.103-noble",
"bash",
"/task/run.sh"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10/candidate-driver-cli-to-candidate-server/container.log"
}
]
@@ -0,0 +1,17 @@
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":5}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
@@ -0,0 +1 @@
{"endpoint":"opc.tcp://127.0.0.1:55610/OtOpcUa","process":35791,"sdk":"1.5.378.0","rawUri":"https://zb.com/otopcua/raw","unsUri":"https://zb.com/otopcua/uns"}
@@ -0,0 +1,13 @@
{
"WorkingSet64": 231833600,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 31,
"cpuMilliseconds": 1531.714,
"allocatedBytes": 156774688,
"collections": [
20,
8,
2
]
}
@@ -0,0 +1,17 @@
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":5}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
@@ -0,0 +1 @@
{"endpoint":"opc.tcp://127.0.0.1:55642/OtOpcUa","process":35814,"sdk":"2.0.1.0","rawUri":"https://zb.com/otopcua/raw","unsUri":"https://zb.com/otopcua/uns"}
@@ -0,0 +1,13 @@
{
"WorkingSet64": 201850880,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 31,
"cpuMilliseconds": 2559.57,
"allocatedBytes": 47810656,
"collections": [
5,
1,
0
]
}
@@ -0,0 +1,17 @@
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":5}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
@@ -0,0 +1 @@
{"endpoint":"opc.tcp://127.0.0.1:55671/OtOpcUa","process":35841,"sdk":"1.5.378.0","rawUri":"https://zb.com/otopcua/raw","unsUri":"https://zb.com/otopcua/uns"}
@@ -0,0 +1,13 @@
{
"WorkingSet64": 229752832,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 30,
"cpuMilliseconds": 1699.059,
"allocatedBytes": 157134200,
"collections": [
20,
8,
2
]
}
@@ -0,0 +1,17 @@
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":5}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
@@ -0,0 +1 @@
{"endpoint":"opc.tcp://127.0.0.1:55697/OtOpcUa","process":35866,"sdk":"2.0.1.0","rawUri":"https://zb.com/otopcua/raw","unsUri":"https://zb.com/otopcua/uns"}
@@ -0,0 +1,13 @@
{
"WorkingSet64": 201097216,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 30,
"cpuMilliseconds": 2626.114,
"allocatedBytes": 47846920,
"collections": [
5,
1,
0
]
}
@@ -0,0 +1,30 @@
Event history for ns=2;s=Matrix/dev (2026-10-01 00:00 -> 2026-10-01 00:01)
EventId | Message
653030 | matrix-history
653031 | matrix-history
653032 | matrix-history
653033 | matrix-history
653034 | matrix-history
653035 | matrix-history
653036 | matrix-history
653037 | matrix-history
653038 | matrix-history
653039 | matrix-history
653130 | matrix-history
653131 | matrix-history
653132 | matrix-history
653133 | matrix-history
653134 | matrix-history
653135 | matrix-history
653136 | matrix-history
653137 | matrix-history
653138 | matrix-history
653139 | matrix-history
653230 | matrix-history
653231 | matrix-history
653232 | matrix-history
653233 | matrix-history
653234 | matrix-history
25 events returned.
@@ -0,0 +1,30 @@
History for ns=2;s=Matrix/dev/Scalar (2026-10-01 00:00 -> 2026-10-01 00:01)
Timestamp Value Status
2026-10-01T00:00:00.0000000Z 0 Good
2026-10-01T00:00:01.0000000Z 1 Good
2026-10-01T00:00:02.0000000Z 2 Good
2026-10-01T00:00:03.0000000Z 3 Good
2026-10-01T00:00:04.0000000Z 4 Good
2026-10-01T00:00:05.0000000Z 5 Good
2026-10-01T00:00:06.0000000Z 6 Good
2026-10-01T00:00:07.0000000Z 7 Good
2026-10-01T00:00:08.0000000Z 8 Good
2026-10-01T00:00:09.0000000Z 9 Good
2026-10-01T00:00:10.0000000Z 10 Good
2026-10-01T00:00:11.0000000Z 11 Good
2026-10-01T00:00:12.0000000Z 12 Good
2026-10-01T00:00:13.0000000Z 13 Good
2026-10-01T00:00:14.0000000Z 14 Good
2026-10-01T00:00:15.0000000Z 15 Good
2026-10-01T00:00:16.0000000Z 16 Good
2026-10-01T00:00:17.0000000Z 17 Good
2026-10-01T00:00:18.0000000Z 18 Good
2026-10-01T00:00:19.0000000Z 19 Good
2026-10-01T00:00:20.0000000Z 20 Good
2026-10-01T00:00:21.0000000Z 21 Good
2026-10-01T00:00:22.0000000Z 22 Good
2026-10-01T00:00:23.0000000Z 23 Good
2026-10-01T00:00:24.0000000Z 24 Good
25 values returned.
@@ -0,0 +1,5 @@
Node: ns=2;s=Matrix/dev/Scalar
Value: 92
Status: Good [0x00000000]
Source Time: 11/10/2026 17:19:14
Server Time: 11/10/2026 17:19:14
@@ -0,0 +1,9 @@
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":5}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
@@ -0,0 +1 @@
{"endpoint":"opc.tcp://127.0.0.1:44603/OtOpcUa","process":33,"sdk":"1.5.378.0","rawUri":"https://zb.com/otopcua/raw","unsUri":"https://zb.com/otopcua/uns"}
@@ -0,0 +1,13 @@
{
"WorkingSet64": 194039808,
"PrivateMemorySize64": 266993664,
"HandleCount": 141,
"threads": 19,
"cpuMilliseconds": 1705.768,
"allocatedBytes": 149139552,
"collections": [
5,
4,
1
]
}
@@ -0,0 +1,30 @@
Event history for ns=2;s=Matrix/dev (2026-10-01 00:00 -> 2026-10-01 00:01)
EventId | Message
653030 | matrix-history
653031 | matrix-history
653032 | matrix-history
653033 | matrix-history
653034 | matrix-history
653035 | matrix-history
653036 | matrix-history
653037 | matrix-history
653038 | matrix-history
653039 | matrix-history
653130 | matrix-history
653131 | matrix-history
653132 | matrix-history
653133 | matrix-history
653134 | matrix-history
653135 | matrix-history
653136 | matrix-history
653137 | matrix-history
653138 | matrix-history
653139 | matrix-history
653230 | matrix-history
653231 | matrix-history
653232 | matrix-history
653233 | matrix-history
653234 | matrix-history
25 events returned.
@@ -0,0 +1,30 @@
History for ns=2;s=Matrix/dev/Scalar (2026-10-01 00:00 -> 2026-10-01 00:01)
Timestamp Value Status
2026-10-01T00:00:00.0000000Z 0 Good
2026-10-01T00:00:01.0000000Z 1 Good
2026-10-01T00:00:02.0000000Z 2 Good
2026-10-01T00:00:03.0000000Z 3 Good
2026-10-01T00:00:04.0000000Z 4 Good
2026-10-01T00:00:05.0000000Z 5 Good
2026-10-01T00:00:06.0000000Z 6 Good
2026-10-01T00:00:07.0000000Z 7 Good
2026-10-01T00:00:08.0000000Z 8 Good
2026-10-01T00:00:09.0000000Z 9 Good
2026-10-01T00:00:10.0000000Z 10 Good
2026-10-01T00:00:11.0000000Z 11 Good
2026-10-01T00:00:12.0000000Z 12 Good
2026-10-01T00:00:13.0000000Z 13 Good
2026-10-01T00:00:14.0000000Z 14 Good
2026-10-01T00:00:15.0000000Z 15 Good
2026-10-01T00:00:16.0000000Z 16 Good
2026-10-01T00:00:17.0000000Z 17 Good
2026-10-01T00:00:18.0000000Z 18 Good
2026-10-01T00:00:19.0000000Z 19 Good
2026-10-01T00:00:20.0000000Z 20 Good
2026-10-01T00:00:21.0000000Z 21 Good
2026-10-01T00:00:22.0000000Z 22 Good
2026-10-01T00:00:23.0000000Z 23 Good
2026-10-01T00:00:24.0000000Z 24 Good
25 values returned.
@@ -0,0 +1,5 @@
Node: ns=2;s=Matrix/dev/Scalar
Value: 92
Status: Good [0x00000000]
Source Time: 11/10/2026 17:19:21
Server Time: 11/10/2026 17:19:22
@@ -0,0 +1,9 @@
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":7}
{"operation":"raw","rows":5}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
{"operation":"events","rows":7}
@@ -0,0 +1 @@
{"endpoint":"opc.tcp://127.0.0.1:44545/OtOpcUa","process":33,"sdk":"2.0.1.0","rawUri":"https://zb.com/otopcua/raw","unsUri":"https://zb.com/otopcua/uns"}
@@ -0,0 +1,13 @@
{
"WorkingSet64": 195645440,
"PrivateMemorySize64": 288792576,
"HandleCount": 153,
"threads": 26,
"cpuMilliseconds": 2091.525,
"allocatedBytes": 42602784,
"collections": [
1,
0,
0
]
}
@@ -0,0 +1,757 @@
[
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Client.dll",
"sha256": "fd000b186f4bc5dbd9947e876f96c178e8c4259ee3e8717d672a4ac2f4c3a058",
"bytes": 852096
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Configuration.dll",
"sha256": "30fb5142f13a3b3083c0484bcdedaec2efe2f50e57f10ec6a61257ca5359aa7e",
"bytes": 85120
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Core.dll",
"sha256": "602e85316943ad7ebae33a23d60a69a6ea50d91250ad0556906b816435daa37c",
"bytes": 7945344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Security.Certificates.dll",
"sha256": "a2a05c64348f6f8aa60de0fe27d8e5e22d12e09b1ba6172ca34b3773620e394c",
"bytes": 79488
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/Opc.Ua.Types.dll",
"sha256": "c5c5e36cf6381444b408fe1b51726b17deca74173764cd62ccee954b3c8c2718",
"bytes": 1127552
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/ZB.MOM.WW.OtOpcUa.Client.CLI.deps.json",
"sha256": "8756470c547137f40ef9962dfa6f40c6dc2a1801cd397524dce7127fb79b70b9",
"bytes": 12175
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/ZB.MOM.WW.OtOpcUa.Client.CLI.dll",
"sha256": "38ff27df4c1389d2cf97a7ec1fe206733f02c3664b29c4fe18586ede225a53ca",
"bytes": 91648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/client/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "326e14df7bf2a7602637fbff36988c3dd4be38de936da24a1b4287c0ab685be6",
"bytes": 111616
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Client.dll",
"sha256": "fd000b186f4bc5dbd9947e876f96c178e8c4259ee3e8717d672a4ac2f4c3a058",
"bytes": 852096
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Configuration.dll",
"sha256": "30fb5142f13a3b3083c0484bcdedaec2efe2f50e57f10ec6a61257ca5359aa7e",
"bytes": 85120
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Core.dll",
"sha256": "602e85316943ad7ebae33a23d60a69a6ea50d91250ad0556906b816435daa37c",
"bytes": 7945344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Security.Certificates.dll",
"sha256": "a2a05c64348f6f8aa60de0fe27d8e5e22d12e09b1ba6172ca34b3773620e394c",
"bytes": 79488
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Server.dll",
"sha256": "d8d9706dea577858325730cd89896826ed82f7bfcf9503ccd0260311663a69f4",
"bytes": 642176
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/Opc.Ua.Types.dll",
"sha256": "c5c5e36cf6381444b408fe1b51726b17deca74173764cd62ccee954b3c8c2718",
"bytes": 1127552
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/OtOpcUa.Host.deps.json",
"sha256": "f47fb25d83e40a5c1d96c063f1d63b02a04c222a10554220df58cac896654ea9",
"bytes": 153279
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.AdminUI.dll",
"sha256": "1ae11959c22bc53a648b91c6c1ae41e4a5d717e396bd645eae4fb08dc1633597",
"bytes": 2152448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Cluster.dll",
"sha256": "d6bc21641172d832004b62b8bb76aeb40622a943be2172f394e5c6333c04ef57",
"bytes": 67584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Commons.dll",
"sha256": "be97a0b975afde7ec4ebf0b10de53c26f212ceca1f6a3ae090e40ebfde304413",
"bytes": 231424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Configuration.dll",
"sha256": "195dab9f7a9f80c45902e653ff361116a307d8110a3f87baad814bea57689b84",
"bytes": 542720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.ControlPlane.dll",
"sha256": "36954f51b09930df414675e5a0c038933ad2b27cd6560bf797d99801c02b30a1",
"bytes": 179200
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll",
"sha256": "b0f4e332ced57eae3ab1dcc282c073f51ea0c545a381aef50479ee58f0c23efc",
"bytes": 124416
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll",
"sha256": "a61a6ea68236dd4ed86ab4e74e4d632c5e260103aa5ebd92f4f995eb9f170b22",
"bytes": 56320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll",
"sha256": "f1e429c0b8fcab8216b9107440008b92eea1236ff1225e79580ad70f51d56431",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll",
"sha256": "ea24898698c8351bc9cf20fcce725dccc93ccf05ef3af7783f73854cc2033c31",
"bytes": 13312
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll",
"sha256": "cf44009a720a00bf9192374d371c7c76e75afbe62cc216b5c1be913b92679127",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll",
"sha256": "07800332d0842b93c3987fca1dc10a1390bcb16f44567610d867513ad9fe17e0",
"bytes": 117248
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll",
"sha256": "9637b7ffb4984f54bc54363ff2d81b6a3401f0cb7eeed8694db626ef41d54d5b",
"bytes": 121856
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll",
"sha256": "107aaf2ef2d7704e320dabc1072bc50217faabb2d1488e66c91b1f756b440c45",
"bytes": 11264
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Core.dll",
"sha256": "34a4d7c0dddf4efa5fae91a3798c2f1c08b992faf4a827a9e05ed1338c6e4720",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll",
"sha256": "315dcc540d304c9f1d5b48caa25e5f081569f1a41aa8784cf371c1d6cef7322d",
"bytes": 123392
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll",
"sha256": "d7b34798587d0939cc78eb69d9df1d617c1c75a61b8dd11a5308958a43a8c4f1",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll",
"sha256": "73073627fcdc8079df645478d6717576975117c3b21cfa7e9422f1e3bc5f4e44",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll",
"sha256": "5c66d76dd455c42f0c5b0aed11240fa31e1bdbd2f0a8368d8f41976977e93502",
"bytes": 30720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll",
"sha256": "cbf92a935d86596a9d4dbeeaa625e304c2045851a0367c3a6b0de03bf78bd6fa",
"bytes": 136704
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll",
"sha256": "29c079414497b30debe8d3ecd7e77bdc4eb16c4fc076e675680a2e880e54b6c2",
"bytes": 10240
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll",
"sha256": "132e36042a4691cc8e252ab9e9d8c90592fcd897959f533aa37e33f193cf00c8",
"bytes": 57344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll",
"sha256": "2bdbf743194193d5a7bc323912e2c7f740cc21633154a4a3cc8e034fd15bb7e8",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll",
"sha256": "17c28f27fdecd09a46b971b19655bdb933f84990e91bb80c7092c344a0ca974f",
"bytes": 300032
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll",
"sha256": "f2796d323c222708c28cd0a4289c46db31ec3b6537da7f5cd260fc76f8abdc76",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll",
"sha256": "780a11f69194713e2f87e74277e99882ee3518b2824551b45cd04e3b9bdf6648",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll",
"sha256": "a8e19baa5a736544d914f942d526a5cc038f6b982451bfa82a77365a159434e4",
"bytes": 224768
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll",
"sha256": "400b1896e55d08781231efeba302596299df2b00b2f48afd43d46c22d59b515c",
"bytes": 129536
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll",
"sha256": "8e91a8cce804023639a4bdb2dc60f9fc950992882e50786d45ceeb0f38ed1f68",
"bytes": 167424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll",
"sha256": "2746b8e9c03b5b8c330152803eee91cf2069f0e6c074d70d03017b1f1f1a2398",
"bytes": 51712
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll",
"sha256": "94b9bcd4506427a44158e0b299a5ae7bcee14fd40b85cc9f63420e4631aa1a6f",
"bytes": 143872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll",
"sha256": "6582151085ddea7d319b990c2c58057b6ba5a49860593229b3642dff527ae204",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll",
"sha256": "c9670c5d169056563294673839ca63321a72a438c519263be708b55f3fc818f9",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll",
"sha256": "ed07d04709372ef804f465995431b15acdef791f66c8130ab7282372728f7cda",
"bytes": 25088
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll",
"sha256": "724873ac2f6c08f307a150c5575cc3c022d7e367124ed924c0c7899b0e9575a5",
"bytes": 39424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll",
"sha256": "db1e3e7c79dc1a46e1d4ffaa5ea1aac9ed73814d7f06cbfa855ebb3b27a8810d",
"bytes": 131584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll",
"sha256": "ace18db746c30307e67efa3acd68e915cc2b62b0a85bdba833df4ea7c85b5f6c",
"bytes": 48128
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll",
"sha256": "24e795bd8027d7b3ca3d95630b73be6d7cef774243357b01850f145b6066dcb9",
"bytes": 139776
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll",
"sha256": "bec0cecc0bbb06b4715d7b909ccf4d357420e120b2bff3c10ee9f59f71044927",
"bytes": 12800
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll",
"sha256": "da64eacb80ddca9cd0a40295bba2c8ff81ee9c68ccaf32cbd329ae854375deb7",
"bytes": 195072
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll",
"sha256": "7e2ac501136d24a3d0ad6bdae2e4a47460439ad8ab78af538bbccca2e38e5695",
"bytes": 35840
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll",
"sha256": "c15e6db37681cbbef8684d5301e1bba54186ae503aaf55d1c2d06a0567ab28fe",
"bytes": 20480
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll",
"sha256": "910604abd4daa6196c8fdcd2db085873ee5a4c27b5a67c359590071117c6e4dd",
"bytes": 16384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll",
"sha256": "cd689b0ec777820d91f914abfd9e4a921143a46df84ee43d0214c66f74225ac0",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll",
"sha256": "6fe895674318dc42c0c3cc74266831862d3fe2f13098c26e7d826baf79d7fc47",
"bytes": 29696
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.S7.dll",
"sha256": "d23a7ac62d781f0c14dd7c9d4f51b712c13599ee78b9b6d302d30dfd5e77da37",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll",
"sha256": "c341d49bf100e0617d9c4e7d24f63d8affd1bc0fe2edce15e51cc14366fa2207",
"bytes": 43008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll",
"sha256": "f0a0cc852116f739247422a0427550e52c938b27d1a8b4e685f45a19a23635ab",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll",
"sha256": "7d78655da50c07ac049cd687c59f2a7b6eb2c491543bd4089ffbe60fb805205f",
"bytes": 40448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll",
"sha256": "6ec1a9bc7443c1d7b8084ee2fc5e67cbfd2a8d61add303a980cef78a46cb5c67",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll",
"sha256": "96db9e5d162b19914cf0ba55c1408c1c9271c80c1a1a12604e684f5785de4b96",
"bytes": 17408
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll",
"sha256": "c24cfc897bde6c0eb65b9958bad952814ed02a27fe25a55c416c1ba61be2c261",
"bytes": 188928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll",
"sha256": "ee1f704fa1574b77bf56cef415c47c33a4428c6852db52bb1443d6765d092cb1",
"bytes": 363008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Runtime.dll",
"sha256": "50e752383ae81ef6bb23e360fafe9162be0d1dcb7dd2d8731f16bce762834dd4",
"bytes": 539648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua-sdk-2-upgrade/OtOpcUa/artifacts/opcua2/83ed880e/baseline/host/ZB.MOM.WW.OtOpcUa.Security.dll",
"sha256": "a88b1577d1e4dd580e012e7673e31d5363c3d9a79fb415bef4c3d63849678a4d",
"bytes": 52736
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-baseline-oracle/OtOpcUa/Directory.Packages.props",
"sha256": "7e6459447843b93bc94fbc1f3eeb1c695b5c46c08aeb94debe86a7d419c63221",
"bytes": 18829
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/Directory.Packages.props",
"sha256": "31a4cac1c205f5b9e67119357c77751b8ab999f6c5f350da68784614040c8a93",
"bytes": 19000
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"sha256": "13de622509608b80bc7dce3317e030bfea8d1b597ff8abd7b57f026c17a9ede0",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Client.dll",
"sha256": "620da406fabdbc75d11f9827ea7e39d2d3c762471bd2264b0d11f1d6cd9247cd",
"bytes": 2442880
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Configuration.dll",
"sha256": "6ed6a594c93c3ff35d1a16539a9fe87c1e2640549cc2f48ed6bae333dc8bf0e7",
"bytes": 117376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Schema.dll",
"sha256": "51cfad48657d95d38074bb88be29aea6f5b361a07397247d58838d066b99772e",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Types.dll",
"sha256": "a7dd141b8dabe8848ff28c2fb8e16a85a0508e6a49e6b1a1c1e267175b99af96",
"bytes": 12703872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Core.dll",
"sha256": "9d0857aa6b7f3c49037d4ea557b4da8edf07e146069464481783e66c5c9cd35a",
"bytes": 2549376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll",
"sha256": "7f4969aceb2f0db5328c6882cb4b117342f3b18905c38acdba600683860c4fd0",
"bytes": 118400
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Server.dll",
"sha256": "930e714a2f6e15d393840bcdc95e1afa8012bc740c3738a655f958142721864e",
"bytes": 3332224
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/Opc.Ua.Types.dll",
"sha256": "c542f69882f4e8a4ebd5ccc28a3881d6967c7ffb6dcc3c56dc6c776f39c2ede1",
"bytes": 1792640
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/OtOpcUa.Host.deps.json",
"sha256": "c289766446d61a6bf15574fdde982a8c44b6faaabb38ad718522f63987a58d69",
"bytes": 179492
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ProcessHost.deps.json",
"sha256": "cb76c2da9266dd11b61483fc9425d8a7ed3e25c83b1179ef60bfbd559b7db77c",
"bytes": 165039
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"sha256": "0db8dd8308811ceecd6f6ac468dbf0e5daacf021904cbf741e96a23daf25cfe7",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.AdminUI.dll",
"sha256": "30a400d0e69bd7a1527e30865cc4fce183bf1fd4b96bea50e7cdde93140b4f03",
"bytes": 2152448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "0856bbccac7c59faf95568e67e25af35b9a68c44ffd0eb5d1891869a454a3de0",
"bytes": 120320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Cluster.dll",
"sha256": "e875e13fe1261963984ac82f7a41da5f83caff28108edaad253641bfe3a7effc",
"bytes": 67584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Commons.dll",
"sha256": "2d1d97faebfbad03db642b77553110210890de51834e5f4b6965f079f7d044a0",
"bytes": 231424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Configuration.dll",
"sha256": "afdb724e0bd460f6deeaedb23e78ff5010f12630c3bd8e2986733ee523b9e30c",
"bytes": 542720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.ControlPlane.dll",
"sha256": "66c93e8d8457f6d842963294c36f5da4261124a4c9ddf486bca09c4c31b39c06",
"bytes": 179200
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll",
"sha256": "46d4b41bed7f4a6497d401d7925d1bd4d87a2422e0c2835dc06e006c97142150",
"bytes": 124416
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll",
"sha256": "bba5e5c363e910678700630e18e6db0d3f9151665e0e1aa2bab6917e83b0ecbf",
"bytes": 56320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll",
"sha256": "474cd76eab3f2724f73f2cc5024370523e294e012f5ecd884dcff366ceac342e",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll",
"sha256": "548b2d19b7bc761fedaf42d39045313394e32a0ccf3ad8bd182e3d31762bd7e4",
"bytes": 13312
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll",
"sha256": "a1441bac81dd7ac01794a927315bb530d022964be535e543afc3e514df4dd9a3",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll",
"sha256": "18e6dbfec8c646e463a8e268137aa1e266063e91d366a029bee4c810f39b7542",
"bytes": 117248
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll",
"sha256": "13236c602191c7866f219eb946c135cf2532bc075d2b458914abbc18efef8e43",
"bytes": 121856
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll",
"sha256": "6a1a9bdd626985dafd483e317ee9906ece7e03d583b44423cc6a95cb21bfdfaf",
"bytes": 11264
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.dll",
"sha256": "59fe6b4b8feebd8d9ec3ff2e3f12a3a8624cdaa68988b230ab7a228cdd246d04",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll",
"sha256": "6178401b851ce3155566e432a376ef2ec983497eccf298ec33d38cd6ed631be7",
"bytes": 123392
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll",
"sha256": "622505ec95e04d7140ea63252b61e01e170947ff88043394e9e7fe2d2ee38e3c",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll",
"sha256": "da3bcdd35f632e5f183ce7721fea455d6396f64234f22eea64862057737c40b9",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll",
"sha256": "8cf0f65f373b410c597cbdba4cce79a73e6388fd13f1f61964f7a78bdc7b67a8",
"bytes": 30720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll",
"sha256": "efa92e068f15126cb5f846e923c72b0c68be9b0158a22da139f4d537f68983f3",
"bytes": 136704
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll",
"sha256": "9b2b094906f46660b9cb5a4a0b53f36d206b4cd88f14837a047c7040ec54f24d",
"bytes": 10240
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll",
"sha256": "58c27311d05d2bf262404520fd2d11a0d2edcb4a98974b61532bcf72a680b4cf",
"bytes": 57344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll",
"sha256": "2358fb9fbcc9475022b190dde05ee6ee712d45c59d041830151a5bcc7418de5f",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll",
"sha256": "ff87272d5e8dae9f1bc1e560e2cd8d82ee279f220f178300ccf534042b1cf2cf",
"bytes": 300032
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll",
"sha256": "b977d56618bfcfeb71789271cefda7443c278e2da75b04fdae49e51da3474586",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll",
"sha256": "52749ea655601805af505e9aa255fb4d7a3563d58df5f86032aff59fc03e1cc8",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll",
"sha256": "41a8c6ed1fe24a50ad9793d78f0dbacff1cfb0e005c027baf27e6003af99988c",
"bytes": 224768
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll",
"sha256": "d642be7f07b7144bb4ef6d6786e73bc2965a1e3189c68b00e5ed4da522eda8df",
"bytes": 129536
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll",
"sha256": "a8d605f278ef8853fc56693d21948cc79c5f07fcd4cb62983f366cd4dcd507d2",
"bytes": 167424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll",
"sha256": "7e0c5b3e79763ede195f7446216c6ffd7617a66c2ce9b4e1b182b05ce9675f18",
"bytes": 51712
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll",
"sha256": "89c1615dbe0911e014facc4452d2140f4471a01dedd50f02eba48123fd81d11a",
"bytes": 143872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll",
"sha256": "530fdc78903fb7dc6bf635db5f7a61a35feeeee71cca5df32a433cc8a38ab239",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll",
"sha256": "d87cbf2e84042bd259cc5b6390922a84eb11bb7a11c00d2c4b5dbe00a75a441c",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll",
"sha256": "17148305ad647f1ecc42911c525bbcee43ed759b751563c92ae2e0f502f5491b",
"bytes": 25088
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll",
"sha256": "850cc34a53b154615a5966c5ab9719ffe65823b419a40b16dc83734c2c77766e",
"bytes": 39424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll",
"sha256": "912f304a47ea3c2a48b9e3ae1a1f9a29cd9577047049a408ab2f54aceb46dd47",
"bytes": 131584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll",
"sha256": "0a6ee903bea8bf1d16a7cbe5e52c80096b84c230d0266969d15004bad9b0f0e4",
"bytes": 48128
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll",
"sha256": "9dbd98038e6fd19f2cf8e28ad081a691ac1df44dcb94597f6ef6f536da9c10f0",
"bytes": 139776
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll",
"sha256": "e133940f52ee7b347dd66bb1eea0bb8a5d936e65aad600888eaea48d67f1555b",
"bytes": 12800
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll",
"sha256": "a171ce43d2f01230d975f5f9bd943fd50a8a8fe39e735935d0a5b1138e31ca1c",
"bytes": 195072
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll",
"sha256": "efb1d122a0aba3c6fd592690143dc99eea608248c0e590a1f264283a040743b2",
"bytes": 36352
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll",
"sha256": "fda75dcf622ebe33dc82dc40a1a362b5a3a10f782bda169ab255d377223a5895",
"bytes": 20480
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll",
"sha256": "ff3b3fee2c4f5954033a2cb5e2b0f3b9cccebc656c7d169687701bd52e8eb142",
"bytes": 19968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll",
"sha256": "09ecbd0ecf90b658dc83f6f2cb12211715f2c51350e86d963c112c4469549ab5",
"bytes": 147968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll",
"sha256": "c9c170f30592fc5698cb256f0f4705ac6fa5ae51a3da89f19ff7753b51ac44e1",
"bytes": 29696
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.dll",
"sha256": "29ec762d9ef4cf9f7e011069604c6bc725aac5c995bd8f7fa72a35f09921beef",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll",
"sha256": "78e0f7c4da53feefdc76137e014848b26d46fc33bc29aa79e99c43de918e15f9",
"bytes": 43008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll",
"sha256": "65c6cd709903aa34be71c62e4c760e0e01a50783497ad644a057ad1a4a179bc4",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll",
"sha256": "a6a9d82c5895b411ebdb95eb2a3de719e3f65280fa7163e0d573db1cf886935b",
"bytes": 40448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll",
"sha256": "0beddb7dd322377b2b1ee496ba59c803528668abe9b62c9ac17bfef8f355b112",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll",
"sha256": "3e37c0328157641e82a99d3d2096a9ab3d826647039da34231f14dea3af0dc43",
"bytes": 17408
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll",
"sha256": "fc9babb948338b46b965344796a0a00560ae917a19eb6d301f2cf94234a7fac5",
"bytes": 188928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll",
"sha256": "8a885d5a86dd00ed5c920e650852cda5820cb9cce05fb49781b7844680d9353f",
"bytes": 420864
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Runtime.dll",
"sha256": "19111a82fb1582866bf0d019f4daa8a5060536cfa11a5569a7e0aeeffdbecc03",
"bytes": 539648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Security.dll",
"sha256": "56f587426e81750fa406686aca50deca2ee8e293ac7969f2a0b606e6acfdfff2",
"bytes": 52736
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/Opc.Ua.Client.dll",
"sha256": "620da406fabdbc75d11f9827ea7e39d2d3c762471bd2264b0d11f1d6cd9247cd",
"bytes": 2442880
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/Opc.Ua.Configuration.dll",
"sha256": "6ed6a594c93c3ff35d1a16539a9fe87c1e2640549cc2f48ed6bae333dc8bf0e7",
"bytes": 117376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/Opc.Ua.Core.Schema.dll",
"sha256": "51cfad48657d95d38074bb88be29aea6f5b361a07397247d58838d066b99772e",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/Opc.Ua.Core.Types.dll",
"sha256": "a7dd141b8dabe8848ff28c2fb8e16a85a0508e6a49e6b1a1c1e267175b99af96",
"bytes": 12703872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/Opc.Ua.Core.dll",
"sha256": "9d0857aa6b7f3c49037d4ea557b4da8edf07e146069464481783e66c5c9cd35a",
"bytes": 2549376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/Opc.Ua.Security.Certificates.dll",
"sha256": "7f4969aceb2f0db5328c6882cb4b117342f3b18905c38acdba600683860c4fd0",
"bytes": 118400
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/Opc.Ua.Types.dll",
"sha256": "c542f69882f4e8a4ebd5ccc28a3881d6967c7ffb6dcc3c56dc6c776f39c2ede1",
"bytes": 1792640
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/ZB.MOM.WW.OtOpcUa.Client.CLI.deps.json",
"sha256": "e1a36de862f9d940bfb55e09db02461bc20f2bd12dad30c8a8bca81ac38be40a",
"bytes": 37379
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/ZB.MOM.WW.OtOpcUa.Client.CLI.dll",
"sha256": "4e86b2f64ed5bb37826977c9104dd370d80d11553084e5570d445cecc6b0aaeb",
"bytes": 92160
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08/candidate-cli/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "0856bbccac7c59faf95568e67e25af35b9a68c44ffd0eb5d1891869a454a3de0",
"bytes": 120320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/scripts/validation/opcua-sdk-compatibility/ProcessHost.cs",
"sha256": "f0a7aca11c38cc8c74c26573458405aa14ed10c81a0a56210dfabf42ead45a83",
"bytes": 27089
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/scripts/validation/opcua-sdk-compatibility/container-leg.sh",
"sha256": "1f5d1158572379b8a6304c3a3134a78c112043940f5bce468621677f7da3ef9e",
"bytes": 2589
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/scripts/validation/opcua-sdk-compatibility/run.py",
"sha256": "240d14f71aca358de5107174bbfbef7ddd5b036cd96fe0889e095a8b9698ec6b",
"bytes": 12459
}
]
@@ -0,0 +1,14 @@
{
"baseline": {
"root": "/Users/dohertj2/.codex/worktrees/opcua2-baseline-oracle/OtOpcUa",
"commit": "83ed880e4471344deaf008da9bd028c7e170bdc7",
"sdkPackages": "/Users/dohertj2/.codex/worktrees/opcua2-baseline-oracle/OtOpcUa/Directory.Packages.props"
},
"candidate": {
"root": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa",
"commit": "ebdc5892063502ccd56e136dd9c2acaccf027f20",
"sdkPackages": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/Directory.Packages.props"
},
"scope": "Loopback application contract and 3 warmed 50-operation rounds per scalar/Int32[3] read/write kind; shared development host, no full load/reconnect/failover/backend/soak performance claim.",
"dateUtc": "2026-11-10T17:18:22Z"
}
@@ -0,0 +1,103 @@
{
"date": "2026-11-10",
"harnessCommit": "ebdc5892",
"candidateSourceCommit": "ebdc5892",
"baselineSourceCommit": "83ed880e",
"browseFixOriginalCommit": "fa823378",
"browseFixLocalCherryPick": "b104ef9a",
"baselineSdkPackage": "1.5.378.182",
"candidateSdkPackage": "2.0.1",
"functional": {
"passed": 62,
"failed": 0,
"skipped": 0,
"legs": [
{
"name": "baseline-client-to-baseline-server",
"passed": 12
},
{
"name": "baseline-client-to-candidate-server",
"passed": 12
},
{
"name": "candidate-client-to-baseline-server",
"passed": 12
},
{
"name": "candidate-client-to-candidate-server",
"passed": 12
},
{
"name": "candidate-driver-cli-to-baseline-server",
"passed": 7
},
{
"name": "candidate-driver-cli-to-candidate-server",
"passed": 7
}
],
"requiredThreeSharedLegsPlusDriverCliCases": 50,
"additionalBaselineReferenceCases": 12
},
"security": {
"policy": "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
"mode": "SignAndEncrypt",
"anonymous": false,
"aclEnabled": true,
"fixtureAuthenticator": "Exact ephemeral API-key-shaped credential; production ACL/write/method gates",
"serverSharedDriverAutoaccept": false,
"cliAutoaccept": true,
"cliLimitationEvidence": "Client.CLI CommandBase.CreateConnectionSettings sets AutoAcceptCertificates=true; no strict-validation option"
},
"continuationPaging": {
"rawSamplesPerSharedLeg": 25,
"rawBackendCeiling": 7,
"eventSamplesPerSharedLeg": 25,
"eventBackendCeiling": 7,
"eventTimestampTies": true,
"assertions": "Exact raw values and event IDs, no loss/duplicates; production session-bound continuation store"
},
"preFix": {
"passed": 60,
"failed": 2,
"finding": "Candidate alarm missing from raw parent browse; original->candidate and candidate->candidate failed exact identity checks. SDK2 Create reset ReferenceTypeId to null/default. Original->original and candidate->original controls passed. Fixed by restoring HasComponent after Create; unchanged strict assertions then passed."
},
"performance": {
"status": "diagnostic-within-budget",
"warmupOperations": 24000,
"measuredOperations": 48000,
"totalCalls": 72000,
"nativeProcessPairs": 3,
"tieredCompilation": "0 for both clients and servers; supplementary experiment only",
"budgetPercent": 15,
"medianP95ChangesPercent": {
"scalar-read": 14.94885916601103,
"scalar-write": 1.577761081893314,
"array-read": -16.279069767441868,
"array-write": -17.23684210526316
},
"limitation": "Small local subset; scalar-read candidate pair3 p95 .2219 ms remains an outlier, preserved in raw data; no full Gate G4 claim",
"allocationMetric": "Average allocated bytes/op across all four operation kinds"
},
"rawArtifacts": {
"functional": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-10",
"warmPerformance": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01",
"preFix": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-08",
"earlyShortPerformance": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-07"
},
"notCertified": [
"Real SQL Server/QuestDB/AVEVA backend matrix",
"Full production load/fan-out/reconnect/backpressure performance",
"Two-hour soak",
"External ScadaBridge consumer",
"Mixed-version Akka cluster rolling upgrade"
],
"capabilityNA": [
{
"component": "OPC UA driver",
"capability": "HistoryRead",
"evidence": ".claude/rules/drivers.md #655: driver history capability removed; Client.Shared and CLI perform history"
}
]
}
@@ -0,0 +1,637 @@
[
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"sha256": "cdb0565a37704509e19fde6eb9a751b7fd770dc92086e7df55da4d9c76712e41",
"bytes": 94720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Core.dll",
"sha256": "602e85316943ad7ebae33a23d60a69a6ea50d91250ad0556906b816435daa37c",
"bytes": 7945344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Types.dll",
"sha256": "c5c5e36cf6381444b408fe1b51726b17deca74173764cd62ccee954b3c8c2718",
"bytes": 1127552
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Server.dll",
"sha256": "d8d9706dea577858325730cd89896826ed82f7bfcf9503ccd0260311663a69f4",
"bytes": 642176
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Client.dll",
"sha256": "fd000b186f4bc5dbd9947e876f96c178e8c4259ee3e8717d672a4ac2f4c3a058",
"bytes": 852096
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll",
"sha256": "a2a05c64348f6f8aa60de0fe27d8e5e22d12e09b1ba6172ca34b3773620e394c",
"bytes": 79488
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Configuration.dll",
"sha256": "30fb5142f13a3b3083c0484bcdedaec2efe2f50e57f10ec6a61257ca5359aa7e",
"bytes": 85120
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll",
"sha256": "da64eacb80ddca9cd0a40295bba2c8ff81ee9c68ccaf32cbd329ae854375deb7",
"bytes": 195072
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll",
"sha256": "c15e6db37681cbbef8684d5301e1bba54186ae503aaf55d1c2d06a0567ab28fe",
"bytes": 20480
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll",
"sha256": "b0f4e332ced57eae3ab1dcc282c073f51ea0c545a381aef50479ee58f0c23efc",
"bytes": 124416
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "326e14df7bf2a7602637fbff36988c3dd4be38de936da24a1b4287c0ab685be6",
"bytes": 111616
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll",
"sha256": "a61a6ea68236dd4ed86ab4e74e4d632c5e260103aa5ebd92f4f995eb9f170b22",
"bytes": 56320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll",
"sha256": "6582151085ddea7d319b990c2c58057b6ba5a49860593229b3642dff527ae204",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll",
"sha256": "c24cfc897bde6c0eb65b9958bad952814ed02a27fe25a55c416c1ba61be2c261",
"bytes": 188928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll",
"sha256": "107aaf2ef2d7704e320dabc1072bc50217faabb2d1488e66c91b1f756b440c45",
"bytes": 11264
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll",
"sha256": "bec0cecc0bbb06b4715d7b909ccf4d357420e120b2bff3c10ee9f59f71044927",
"bytes": 12800
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.AdminUI.dll",
"sha256": "1ae11959c22bc53a648b91c6c1ae41e4a5d717e396bd645eae4fb08dc1633597",
"bytes": 2152448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll",
"sha256": "07800332d0842b93c3987fca1dc10a1390bcb16f44567610d867513ad9fe17e0",
"bytes": 117248
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Configuration.dll",
"sha256": "195dab9f7a9f80c45902e653ff361116a307d8110a3f87baad814bea57689b84",
"bytes": 542720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll",
"sha256": "94b9bcd4506427a44158e0b299a5ae7bcee14fd40b85cc9f63420e4631aa1a6f",
"bytes": 143872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll",
"sha256": "9637b7ffb4984f54bc54363ff2d81b6a3401f0cb7eeed8694db626ef41d54d5b",
"bytes": 121856
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll",
"sha256": "910604abd4daa6196c8fdcd2db085873ee5a4c27b5a67c359590071117c6e4dd",
"bytes": 16384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll",
"sha256": "cbf92a935d86596a9d4dbeeaa625e304c2045851a0367c3a6b0de03bf78bd6fa",
"bytes": 136704
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.ControlPlane.dll",
"sha256": "36954f51b09930df414675e5a0c038933ad2b27cd6560bf797d99801c02b30a1",
"bytes": 179200
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll",
"sha256": "29c079414497b30debe8d3ecd7e77bdc4eb16c4fc076e675680a2e880e54b6c2",
"bytes": 10240
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll",
"sha256": "73073627fcdc8079df645478d6717576975117c3b21cfa7e9422f1e3bc5f4e44",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll",
"sha256": "5c66d76dd455c42f0c5b0aed11240fa31e1bdbd2f0a8368d8f41976977e93502",
"bytes": 30720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll",
"sha256": "6fe895674318dc42c0c3cc74266831862d3fe2f13098c26e7d826baf79d7fc47",
"bytes": 29696
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll",
"sha256": "24e795bd8027d7b3ca3d95630b73be6d7cef774243357b01850f145b6066dcb9",
"bytes": 139776
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll",
"sha256": "cd689b0ec777820d91f914abfd9e4a921143a46df84ee43d0214c66f74225ac0",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll",
"sha256": "ace18db746c30307e67efa3acd68e915cc2b62b0a85bdba833df4ea7c85b5f6c",
"bytes": 48128
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll",
"sha256": "ea24898698c8351bc9cf20fcce725dccc93ccf05ef3af7783f73854cc2033c31",
"bytes": 13312
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.dll",
"sha256": "d23a7ac62d781f0c14dd7c9d4f51b712c13599ee78b9b6d302d30dfd5e77da37",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll",
"sha256": "2bdbf743194193d5a7bc323912e2c7f740cc21633154a4a3cc8e034fd15bb7e8",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll",
"sha256": "6ec1a9bc7443c1d7b8084ee2fc5e67cbfd2a8d61add303a980cef78a46cb5c67",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll",
"sha256": "400b1896e55d08781231efeba302596299df2b00b2f48afd43d46c22d59b515c",
"bytes": 129536
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll",
"sha256": "7d78655da50c07ac049cd687c59f2a7b6eb2c491543bd4089ffbe60fb805205f",
"bytes": 40448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll",
"sha256": "8e91a8cce804023639a4bdb2dc60f9fc950992882e50786d45ceeb0f38ed1f68",
"bytes": 167424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Client.CLI.dll",
"sha256": "38ff27df4c1389d2cf97a7ec1fe206733f02c3664b29c4fe18586ede225a53ca",
"bytes": 91648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll",
"sha256": "96db9e5d162b19914cf0ba55c1408c1c9271c80c1a1a12604e684f5785de4b96",
"bytes": 17408
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll",
"sha256": "db1e3e7c79dc1a46e1d4ffaa5ea1aac9ed73814d7f06cbfa855ebb3b27a8810d",
"bytes": 131584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll",
"sha256": "132e36042a4691cc8e252ab9e9d8c90592fcd897959f533aa37e33f193cf00c8",
"bytes": 57344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll",
"sha256": "780a11f69194713e2f87e74277e99882ee3518b2824551b45cd04e3b9bdf6648",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll",
"sha256": "c341d49bf100e0617d9c4e7d24f63d8affd1bc0fe2edce15e51cc14366fa2207",
"bytes": 43008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll",
"sha256": "315dcc540d304c9f1d5b48caa25e5f081569f1a41aa8784cf371c1d6cef7322d",
"bytes": 123392
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll",
"sha256": "d7b34798587d0939cc78eb69d9df1d617c1c75a61b8dd11a5308958a43a8c4f1",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll",
"sha256": "cf44009a720a00bf9192374d371c7c76e75afbe62cc216b5c1be913b92679127",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Commons.dll",
"sha256": "be97a0b975afde7ec4ebf0b10de53c26f212ceca1f6a3ae090e40ebfde304413",
"bytes": 231424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll",
"sha256": "f2796d323c222708c28cd0a4289c46db31ec3b6537da7f5cd260fc76f8abdc76",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll",
"sha256": "7e2ac501136d24a3d0ad6bdae2e4a47460439ad8ab78af538bbccca2e38e5695",
"bytes": 35840
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll",
"sha256": "c9670c5d169056563294673839ca63321a72a438c519263be708b55f3fc818f9",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll",
"sha256": "17c28f27fdecd09a46b971b19655bdb933f84990e91bb80c7092c344a0ca974f",
"bytes": 300032
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.dll",
"sha256": "34a4d7c0dddf4efa5fae91a3798c2f1c08b992faf4a827a9e05ed1338c6e4720",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll",
"sha256": "ed07d04709372ef804f465995431b15acdef791f66c8130ab7282372728f7cda",
"bytes": 25088
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll",
"sha256": "f0a0cc852116f739247422a0427550e52c938b27d1a8b4e685f45a19a23635ab",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll",
"sha256": "724873ac2f6c08f307a150c5575cc3c022d7e367124ed924c0c7899b0e9575a5",
"bytes": 39424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll",
"sha256": "ee1f704fa1574b77bf56cef415c47c33a4428c6852db52bb1443d6765d092cb1",
"bytes": 363008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll",
"sha256": "a8e19baa5a736544d914f942d526a5cc038f6b982451bfa82a77365a159434e4",
"bytes": 224768
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Cluster.dll",
"sha256": "d6bc21641172d832004b62b8bb76aeb40622a943be2172f394e5c6333c04ef57",
"bytes": 67584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Security.dll",
"sha256": "a88b1577d1e4dd580e012e7673e31d5363c3d9a79fb415bef4c3d63849678a4d",
"bytes": 52736
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll",
"sha256": "f1e429c0b8fcab8216b9107440008b92eea1236ff1225e79580ad70f51d56431",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll",
"sha256": "2746b8e9c03b5b8c330152803eee91cf2069f0e6c074d70d03017b1f1f1a2398",
"bytes": 51712
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Runtime.dll",
"sha256": "50e752383ae81ef6bb23e360fafe9162be0d1dcb7dd2d8731f16bce762834dd4",
"bytes": 539648
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"sha256": "500c0c486bd91e04b97560b2f08c1fc2b7fc5ac5fa79642aa2b9af6e7a812617",
"bytes": 95232
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Schema.dll",
"sha256": "51cfad48657d95d38074bb88be29aea6f5b361a07397247d58838d066b99772e",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.dll",
"sha256": "9d0857aa6b7f3c49037d4ea557b4da8edf07e146069464481783e66c5c9cd35a",
"bytes": 2549376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Types.dll",
"sha256": "c542f69882f4e8a4ebd5ccc28a3881d6967c7ffb6dcc3c56dc6c776f39c2ede1",
"bytes": 1792640
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Server.dll",
"sha256": "930e714a2f6e15d393840bcdc95e1afa8012bc740c3738a655f958142721864e",
"bytes": 3332224
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Types.dll",
"sha256": "a7dd141b8dabe8848ff28c2fb8e16a85a0508e6a49e6b1a1c1e267175b99af96",
"bytes": 12703872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Client.dll",
"sha256": "620da406fabdbc75d11f9827ea7e39d2d3c762471bd2264b0d11f1d6cd9247cd",
"bytes": 2442880
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll",
"sha256": "7f4969aceb2f0db5328c6882cb4b117342f3b18905c38acdba600683860c4fd0",
"bytes": 118400
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Configuration.dll",
"sha256": "6ed6a594c93c3ff35d1a16539a9fe87c1e2640549cc2f48ed6bae333dc8bf0e7",
"bytes": 117376
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll",
"sha256": "ad2ebe0e8411f8f1b1d51a0b297f145d633fc8decb6c90f35bd84689f1cb3a69",
"bytes": 195072
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll",
"sha256": "0c28890f2a6ddf1ccfa8cdb3b8c95bb2284c3721b53eb2210b1249ef8a9e6638",
"bytes": 20480
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll",
"sha256": "fbcb699370cfdf2518758ce3979d1af4fa2041660afad1eaacdf66e32615c549",
"bytes": 124416
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Client.Shared.dll",
"sha256": "c2fe235ab38cd6e9f69201cadfd414e065412c6bd272f97850b33d616ce5ad60",
"bytes": 120320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll",
"sha256": "12f5ed08d11bfd88a3dfe42418b014d6e23a7785202b91ad12c6e1a83d192fc4",
"bytes": 56320
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll",
"sha256": "a8c4a4a2a9ff90d8f00183ab1a67e44e5eb1e957780d1a27100ca0e93cd61f28",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll",
"sha256": "602fc15da19e29198a3cef5d5020ffa6b0bbb446a6484d984bb3f7a69b83a45d",
"bytes": 188928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll",
"sha256": "c03601d921f0d483a18b8766405223c80f639f734118de1da5d189a4ed513715",
"bytes": 11264
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll",
"sha256": "4c31fcfd93242aafa13cb4779425ff02909f81c2d2c1cf7e8ceefb6aaaf1a3f9",
"bytes": 12800
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.AdminUI.dll",
"sha256": "0ce4013902b8cd704e7a20afafcbaa5a487cd1bb7c26cd2ac0713dc11c5a0a0d",
"bytes": 2152448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll",
"sha256": "4a50434a1e440608679f353e10d715c633c9e0220905f12e3e289e0224679224",
"bytes": 117248
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Configuration.dll",
"sha256": "fc9ce3d1c11dfceeee597bc5ae203bd5748c0e7f2b130c3cc8176757790d51aa",
"bytes": 542720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll",
"sha256": "d93a430dc6d2faad5834ca0b4cdf172734db51bb6752d0c5a11fbf1d16e4cb2d",
"bytes": 143872
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll",
"sha256": "1a2c6a0695579b2f5f7885ba488d075683fe9929a092c1d42e1db64ebe187d9a",
"bytes": 121856
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll",
"sha256": "bb99f9e72c8ee6e25d50faeae179ffe243f8f39bb8ef2d7ae761294cf1ddc23c",
"bytes": 19968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll",
"sha256": "84959687ffbff354616472e085785a583a1d7c2548494bb6d8aa771f034e52bf",
"bytes": 136704
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.ControlPlane.dll",
"sha256": "a37b6d6789271d5f95a3663757049765ea19a20235bfca6da3bbe05e2cb0a993",
"bytes": 179200
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll",
"sha256": "c4c1bc2ab5c5f4f594e484b84e9cbe16959439221b287d08c99621de8314107f",
"bytes": 10240
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll",
"sha256": "877a62c49e1c4a829127424270310ad03a9b140ba28ab90cb9f0d26f57bdc23e",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll",
"sha256": "921cf8b87f0a00007ff3afcb9038539143d9156dc8ca6c106e4736784bafe108",
"bytes": 30720
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll",
"sha256": "bd6bdfb0a1b477eba5c982d11630a281649a0b7e6eab0dd0e1b6da977b8348a9",
"bytes": 29696
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll",
"sha256": "b3c73be797d483bd0887fb02ea3104323f713e609cf8e91487c44035b64511a1",
"bytes": 139776
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll",
"sha256": "e2863d570d0bb8afe59b15f9e3d594dccf41c966e78cd783c53cbbb6f071514b",
"bytes": 147968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll",
"sha256": "47f5fe5968d002e8d608dc0b08305c7a5e8acfedf76ef2524d1c269fbb138ccf",
"bytes": 48128
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll",
"sha256": "22db91e2af8bc93fb050b4c0d1de9fdf2703029939b82ab6d5b95bc39c9b8c8a",
"bytes": 13312
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.S7.dll",
"sha256": "0fdab087e07f2fae6ebfdd3660177ac32abf0e629a62b2405c0b0af07a096302",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll",
"sha256": "7c0dd5a8a1e41c0b1b535b657ecb3f8bc30706d51a0674e452312099d6815542",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll",
"sha256": "6a35e1840e33acb081425716253025c8cc1d83cea0303fb5c746dc3d5fa5dae4",
"bytes": 144384
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll",
"sha256": "a947eba055aa5196a67bd7fd0864e859f3ecd4600f4869e88902e55e64a2d9b0",
"bytes": 129536
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll",
"sha256": "ffb2018ed15cd44939a8b48cf87147905485ac7381f49011e8ad7496ee290a7f",
"bytes": 40448
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll",
"sha256": "8c58149292eb015a9dfff038dcc2a0b0bfc706a0c9240d1e47b254cdbd422c1e",
"bytes": 167424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll",
"sha256": "d669e85c94bfc026d41bc8f85ef0400d449fc20c266f1b22080df8bc078930fc",
"bytes": 17408
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll",
"sha256": "54eafb843b8f4eedde13dd5ec97acd6c2f3aacc169979c4e2bed5b89ce996496",
"bytes": 131584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll",
"sha256": "1038eb45625e93c77e15f1561d5cd0988ea90753769f40b15f84b634624a71e5",
"bytes": 57344
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll",
"sha256": "b205095b406d297009c6027dd89cc3ede058fb47fe1e2ddd73ec7fe6ce669c68",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll",
"sha256": "4fb7a9ff8938b2e66bc361741e2beff8f1ab489c02ea6391c7a4141851ded4b8",
"bytes": 43008
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll",
"sha256": "d0484e3fcb36299fa9eb1d0c83ee6cdb0ca35d748584c72b5db7466fde69716c",
"bytes": 123392
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll",
"sha256": "db0f111f8debd7b97e374a594a94ccf6f73e21791a65c952773f53f3a87c0b8a",
"bytes": 24576
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll",
"sha256": "f4249cb6b89d06becf41e5494c3b36a154042cd96aad8d09c73a73c1b4e2d5f4",
"bytes": 135168
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Commons.dll",
"sha256": "b230c84ffd9eb1ef56d5321cab9dd32859056dbb861f1d8167ba5f9d0da9ea54",
"bytes": 231424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll",
"sha256": "28755d92235c896d345bccd6eca9b847f784e6c404178e791cc213a95f9b4eb6",
"bytes": 19456
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll",
"sha256": "14c57c172cce3d0ae79cbcf23c4f5eef939d02f96f922af98908e33ead2f17b5",
"bytes": 36352
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll",
"sha256": "c2789ab6ac08510360f5c376819c77e51002680d5e53b2c83357c9ca06672b8d",
"bytes": 214016
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll",
"sha256": "b235e797154aaf86822e575b9ce226ba18002f15be6b6945531e6ba9c059fb98",
"bytes": 300032
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.dll",
"sha256": "9d00ecb44437222ed3aecc42e9b3337ba1d7450a246fa2390841acc7dc58ac13",
"bytes": 124928
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll",
"sha256": "4348dd5ee686c32c27de164d1c1e4dbd40b52d99f52f286270142acf030c16f8",
"bytes": 25088
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll",
"sha256": "cd17a68345dfb0ead81b045fd6057c18b186b14393fd2e6a979c242b34fc219d",
"bytes": 38912
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll",
"sha256": "4a8aa7eff2d8129f4803de73041c2daae5ff1643d8499fbdec721659abf9f727",
"bytes": 39424
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll",
"sha256": "9175d2271e271a0052f165f33513d23014d879d46eb5c8922157a80f6381125d",
"bytes": 420864
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll",
"sha256": "6c25cabf5039eefd70f762567ab95ca2a0a18b756f9898af20a881e15185c249",
"bytes": 224768
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Cluster.dll",
"sha256": "071e30ca57f8c7baeea75e8f5b2de15092a0f990636b5ebe3aefb7f974b7b155",
"bytes": 67584
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Security.dll",
"sha256": "b169438db06ed0d0ebddae0b188bbcb1b5725953daad741146ebb95a6f943749",
"bytes": 52736
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll",
"sha256": "66fedb5dc0905be00a157e0d041068f0eb2edd925eb8e7ce1c58f2c382eb234e",
"bytes": 83968
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll",
"sha256": "9eb0644fea0d29ea31f4825fb69c8ae81d1207a4210afe716ce17f1db6688b51",
"bytes": 51712
},
{
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ZB.MOM.WW.OtOpcUa.Runtime.dll",
"sha256": "2ab4d24740bb3ad0f94c42043c494a0b37c94faa692a9c29e925267a7ae3c896",
"bytes": 539648
}
]
@@ -0,0 +1,170 @@
[
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-baseline/client"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-baseline/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-baseline/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-baseline/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"performance",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-baseline/client",
"opc.tcp://127.0.0.1:54954/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-baseline/client.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-candidate/client"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-candidate/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-candidate/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-candidate/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"performance",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-candidate/client",
"opc.tcp://127.0.0.1:54976/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-1-candidate/client.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-baseline/client"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-baseline/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-baseline/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-baseline/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"performance",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-baseline/client",
"opc.tcp://127.0.0.1:55036/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-baseline/client.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-candidate/client"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-candidate/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-candidate/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-candidate/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"performance",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-candidate/client",
"opc.tcp://127.0.0.1:55057/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-2-candidate/client.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-baseline/client"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-baseline/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-baseline/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-baseline/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/ProcessHost.dll",
"performance",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-baseline/client",
"opc.tcp://127.0.0.1:55141/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-baseline/client.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"prepare",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-candidate/client"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-candidate/prepare.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"server",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-candidate/server"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-candidate/server.log"
},
{
"argv": [
"dotnet",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/ProcessHost.dll",
"performance",
"/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-candidate/client",
"opc.tcp://127.0.0.1:55174/OtOpcUa"
],
"log": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/performance-01/pair-3-candidate/client.log"
}
]
@@ -0,0 +1,683 @@
[
{
"sdk": "1.5.378.0",
"process": 28670,
"cases": [
{
"name": "warmed-production-client-read-write-measurement",
"status": "passed"
}
],
"observations": [
{
"SecurityMode": "SignAndEncrypt",
"SecurityPolicyUri": "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
"tieredCompilation": "0",
"scope": "Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"
},
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1084,
"p95": 0.1271,
"p99": 0.1421,
"throughputOperationsPerSecond": 9285.499392728334
},
"scalar-write": {
"p50": 0.1098,
"p95": 0.131,
"p99": 0.1444,
"throughputOperationsPerSecond": 9130.46892262293
},
"array-read": {
"p50": 0.1261,
"p95": 0.1622,
"p99": 0.1971,
"throughputOperationsPerSecond": 7760.146294277952
},
"array-write": {
"p50": 0.129,
"p95": 0.1618,
"p99": 0.214,
"throughputOperationsPerSecond": 7611.187074986556
}
},
"clientCpuMilliseconds": 1561.548,
"clientAllocatedBytes": 52843304,
"clientAllocatedBytesPerOperation": 6605.413,
"clientWorkingSetBytes": 137527296,
"clientPrivateBytes": 0,
"clientThreads": 17,
"clientHandles": 0,
"collections": [
6,
0,
0
]
}
],
"failures": 0,
"loadedSdkAssemblies": [
{
"name": "Opc.Ua.Core",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Core.dll"
},
{
"name": "Opc.Ua.Types",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Types.dll"
},
{
"name": "Opc.Ua.Configuration",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Configuration.dll"
},
{
"name": "Opc.Ua.Security.Certificates",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll"
},
{
"name": "Opc.Ua.Client",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Client.dll"
}
],
"pair": 1,
"version": "baseline",
"server": {
"endpoint": "opc.tcp://127.0.0.1:54954/OtOpcUa",
"process": 28663,
"sdk": "1.5.378.0",
"rawUri": "https://zb.com/otopcua/raw",
"unsUri": "https://zb.com/otopcua/uns"
},
"serverResources": {
"WorkingSet64": 223887360,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 30,
"cpuMilliseconds": 3865.762,
"allocatedBytes": 282715048,
"collections": [
36,
10,
3
]
}
},
{
"sdk": "2.0.1.0",
"process": 29028,
"cases": [
{
"name": "warmed-production-client-read-write-measurement",
"status": "passed"
}
],
"observations": [
{
"SecurityMode": "SignAndEncrypt",
"SecurityPolicyUri": "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
"tieredCompilation": "0",
"scope": "Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"
},
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1066,
"p95": 0.123,
"p99": 0.1348,
"throughputOperationsPerSecond": 9448.442447883575
},
"scalar-write": {
"p50": 0.1102,
"p95": 0.1273,
"p99": 0.1392,
"throughputOperationsPerSecond": 9103.911131261095
},
"array-read": {
"p50": 0.1061,
"p95": 0.1224,
"p99": 0.138,
"throughputOperationsPerSecond": 9477.231188999194
},
"array-write": {
"p50": 0.1087,
"p95": 0.1253,
"p99": 0.1361,
"throughputOperationsPerSecond": 9297.171056790836
}
},
"clientCpuMilliseconds": 1592.923,
"clientAllocatedBytes": 26878216,
"clientAllocatedBytesPerOperation": 3359.777,
"clientWorkingSetBytes": 151945216,
"clientPrivateBytes": 0,
"clientThreads": 18,
"clientHandles": 0,
"collections": [
3,
0,
0
]
}
],
"failures": 0,
"loadedSdkAssemblies": [
{
"name": "Opc.Ua.Core",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.dll"
},
{
"name": "Opc.Ua.Types",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Types.dll"
},
{
"name": "Opc.Ua.Core.Types",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Types.dll"
},
{
"name": "Opc.Ua.Configuration",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Configuration.dll"
},
{
"name": "Opc.Ua.Security.Certificates",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll"
},
{
"name": "Opc.Ua.Client",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Client.dll"
}
],
"pair": 1,
"version": "candidate",
"server": {
"endpoint": "opc.tcp://127.0.0.1:54976/OtOpcUa",
"process": 29017,
"sdk": "2.0.1.0",
"rawUri": "https://zb.com/otopcua/raw",
"unsUri": "https://zb.com/otopcua/uns"
},
"serverResources": {
"WorkingSet64": 225460224,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 28,
"cpuMilliseconds": 14631.949,
"allocatedBytes": 152391328,
"collections": [
20,
5,
2
]
}
},
{
"sdk": "1.5.378.0",
"process": 29047,
"cases": [
{
"name": "warmed-production-client-read-write-measurement",
"status": "passed"
}
],
"observations": [
{
"SecurityMode": "SignAndEncrypt",
"SecurityPolicyUri": "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
"tieredCompilation": "0",
"scope": "Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"
},
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1066,
"p95": 0.1238,
"p99": 0.139,
"throughputOperationsPerSecond": 9484.700940265833
},
"scalar-write": {
"p50": 0.1124,
"p95": 0.1331,
"p99": 0.1461,
"throughputOperationsPerSecond": 8957.752105855532
},
"array-read": {
"p50": 0.115,
"p95": 0.1462,
"p99": 0.166,
"throughputOperationsPerSecond": 8586.679741317685
},
"array-write": {
"p50": 0.1177,
"p95": 0.152,
"p99": 0.1822,
"throughputOperationsPerSecond": 8333.253472987553
}
},
"clientCpuMilliseconds": 1437.526,
"clientAllocatedBytes": 52855576,
"clientAllocatedBytesPerOperation": 6606.947,
"clientWorkingSetBytes": 137445376,
"clientPrivateBytes": 0,
"clientThreads": 17,
"clientHandles": 0,
"collections": [
6,
0,
0
]
}
],
"failures": 0,
"loadedSdkAssemblies": [
{
"name": "Opc.Ua.Core",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Core.dll"
},
{
"name": "Opc.Ua.Types",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Types.dll"
},
{
"name": "Opc.Ua.Configuration",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Configuration.dll"
},
{
"name": "Opc.Ua.Security.Certificates",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll"
},
{
"name": "Opc.Ua.Client",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Client.dll"
}
],
"pair": 2,
"version": "baseline",
"server": {
"endpoint": "opc.tcp://127.0.0.1:55036/OtOpcUa",
"process": 29040,
"sdk": "1.5.378.0",
"rawUri": "https://zb.com/otopcua/raw",
"unsUri": "https://zb.com/otopcua/uns"
},
"serverResources": {
"WorkingSet64": 226934784,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 29,
"cpuMilliseconds": 3721.212,
"allocatedBytes": 283566920,
"collections": [
36,
10,
3
]
}
},
{
"sdk": "2.0.1.0",
"process": 29091,
"cases": [
{
"name": "warmed-production-client-read-write-measurement",
"status": "passed"
}
],
"observations": [
{
"SecurityMode": "SignAndEncrypt",
"SecurityPolicyUri": "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
"tieredCompilation": "0",
"scope": "Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"
},
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1148,
"p95": 0.1461,
"p99": 0.1916,
"throughputOperationsPerSecond": 8453.853583482856
},
"scalar-write": {
"p50": 0.1106,
"p95": 0.1352,
"p99": 0.1535,
"throughputOperationsPerSecond": 9031.92242662466
},
"array-read": {
"p50": 0.1037,
"p95": 0.1201,
"p99": 0.1278,
"throughputOperationsPerSecond": 9771.59387887815
},
"array-write": {
"p50": 0.1098,
"p95": 0.1258,
"p99": 0.1357,
"throughputOperationsPerSecond": 9218.53127594152
}
},
"clientCpuMilliseconds": 1599.821,
"clientAllocatedBytes": 26876112,
"clientAllocatedBytesPerOperation": 3359.514,
"clientWorkingSetBytes": 151846912,
"clientPrivateBytes": 0,
"clientThreads": 18,
"clientHandles": 0,
"collections": [
3,
0,
0
]
}
],
"failures": 0,
"loadedSdkAssemblies": [
{
"name": "Opc.Ua.Core",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.dll"
},
{
"name": "Opc.Ua.Types",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Types.dll"
},
{
"name": "Opc.Ua.Core.Types",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Types.dll"
},
{
"name": "Opc.Ua.Configuration",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Configuration.dll"
},
{
"name": "Opc.Ua.Security.Certificates",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll"
},
{
"name": "Opc.Ua.Client",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Client.dll"
}
],
"pair": 2,
"version": "candidate",
"server": {
"endpoint": "opc.tcp://127.0.0.1:55057/OtOpcUa",
"process": 29069,
"sdk": "2.0.1.0",
"rawUri": "https://zb.com/otopcua/raw",
"unsUri": "https://zb.com/otopcua/uns"
},
"serverResources": {
"WorkingSet64": 221364224,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 28,
"cpuMilliseconds": 14663.082,
"allocatedBytes": 152371904,
"collections": [
20,
5,
2
]
}
},
{
"sdk": "1.5.378.0",
"process": 29442,
"cases": [
{
"name": "warmed-production-client-read-write-measurement",
"status": "passed"
}
],
"observations": [
{
"SecurityMode": "SignAndEncrypt",
"SecurityPolicyUri": "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
"tieredCompilation": "0",
"scope": "Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"
},
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1113,
"p95": 0.1326,
"p99": 0.1514,
"throughputOperationsPerSecond": 8990.861239093505
},
"scalar-write": {
"p50": 0.1122,
"p95": 0.135,
"p99": 0.1487,
"throughputOperationsPerSecond": 8981.86516513833
},
"array-read": {
"p50": 0.1088,
"p95": 0.1297,
"p99": 0.148,
"throughputOperationsPerSecond": 9229.57080649836
},
"array-write": {
"p50": 0.1013,
"p95": 0.1363,
"p99": 0.1511,
"throughputOperationsPerSecond": 9424.462228404675
}
},
"clientCpuMilliseconds": 1460.265,
"clientAllocatedBytes": 52847520,
"clientAllocatedBytesPerOperation": 6605.94,
"clientWorkingSetBytes": 137510912,
"clientPrivateBytes": 0,
"clientThreads": 17,
"clientHandles": 0,
"collections": [
6,
0,
0
]
}
],
"failures": 0,
"loadedSdkAssemblies": [
{
"name": "Opc.Ua.Core",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Core.dll"
},
{
"name": "Opc.Ua.Types",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Types.dll"
},
{
"name": "Opc.Ua.Configuration",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Configuration.dll"
},
{
"name": "Opc.Ua.Security.Certificates",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll"
},
{
"name": "Opc.Ua.Client",
"version": "1.5.378.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-baseline/bin/Release/net10.0/Opc.Ua.Client.dll"
}
],
"pair": 3,
"version": "baseline",
"server": {
"endpoint": "opc.tcp://127.0.0.1:55141/OtOpcUa",
"process": 29435,
"sdk": "1.5.378.0",
"rawUri": "https://zb.com/otopcua/raw",
"unsUri": "https://zb.com/otopcua/uns"
},
"serverResources": {
"WorkingSet64": 218546176,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 30,
"cpuMilliseconds": 3652.527,
"allocatedBytes": 284326360,
"collections": [
35,
9,
2
]
}
},
{
"sdk": "2.0.1.0",
"process": 29814,
"cases": [
{
"name": "warmed-production-client-read-write-measurement",
"status": "passed"
}
],
"observations": [
{
"SecurityMode": "SignAndEncrypt",
"SecurityPolicyUri": "http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256",
"tieredCompilation": "0",
"scope": "Two scalar/Int32[3] variables; zero data monitors during measurement; five fixture variables and one native condition"
},
{
"benchmarkRound": 1,
"warmupOperationsPerKind": 10,
"operationsPerKind": 50,
"latencyMilliseconds": {
"scalar-read": {
"p50": 0.1134,
"p95": 0.2219,
"p99": 0.2964,
"throughputOperationsPerSecond": 7963.32094373317
},
"scalar-write": {
"p50": 0.1177,
"p95": 0.1569,
"p99": 0.2249,
"throughputOperationsPerSecond": 8232.878494239445
},
"array-read": {
"p50": 0.1161,
"p95": 0.1455,
"p99": 0.171,
"throughputOperationsPerSecond": 8493.990077320781
},
"array-write": {
"p50": 0.1183,
"p95": 0.1433,
"p99": 0.1651,
"throughputOperationsPerSecond": 8450.517361799171
}
},
"clientCpuMilliseconds": 1754.458,
"clientAllocatedBytes": 26950792,
"clientAllocatedBytesPerOperation": 3368.849,
"clientWorkingSetBytes": 151781376,
"clientPrivateBytes": 0,
"clientThreads": 18,
"clientHandles": 0,
"collections": [
3,
0,
0
]
}
],
"failures": 0,
"loadedSdkAssemblies": [
{
"name": "Opc.Ua.Core",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.dll"
},
{
"name": "Opc.Ua.Types",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Types.dll"
},
{
"name": "Opc.Ua.Core.Types",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Core.Types.dll"
},
{
"name": "Opc.Ua.Configuration",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Configuration.dll"
},
{
"name": "Opc.Ua.Security.Certificates",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Security.Certificates.dll"
},
{
"name": "Opc.Ua.Client",
"version": "2.0.1.0",
"path": "/Users/dohertj2/.codex/worktrees/opcua2-cross-version/OtOpcUa/artifacts/cross-version/run-09/build-candidate/bin/Release/net10.0/Opc.Ua.Client.dll"
}
],
"pair": 3,
"version": "candidate",
"server": {
"endpoint": "opc.tcp://127.0.0.1:55174/OtOpcUa",
"process": 29458,
"sdk": "2.0.1.0",
"rawUri": "https://zb.com/otopcua/raw",
"unsUri": "https://zb.com/otopcua/uns"
},
"serverResources": {
"WorkingSet64": 226361344,
"PrivateMemorySize64": 0,
"HandleCount": 0,
"threads": 28,
"cpuMilliseconds": 15066.213,
"allocatedBytes": 152491688,
"collections": [
20,
5,
2
]
}
}
]
@@ -0,0 +1,220 @@
{
"scope": "Supplementary warmed, matched native-process experiment; not full Gate G4.",
"environment": {
"DOTNET_TieredCompilation": "0",
"OPCUA_MATRIX_PERF_ROUNDS": "1",
"OPCUA_MATRIX_PERF_WARMUPS": "1000",
"OPCUA_MATRIX_PERF_MEASURED": "2000"
},
"dotnetSdk": "10.0.403",
"p95BudgetPercent": 15,
"dateUtc": "2026-11-10T17:16:20Z",
"logicalCpuCount": 14,
"summary": [
{
"operation": "scalar-read",
"samples": {
"baseline": {
"p95Milliseconds": [
0.1271,
0.1238,
0.1326
],
"allocatedBytesPerOperation": [
6605.413,
6606.947,
6605.94
],
"clientWorkingSetBytes": [
137527296,
137445376,
137510912
],
"serverWorkingSetBytes": [
223887360,
226934784,
218546176
]
},
"candidate": {
"p95Milliseconds": [
0.123,
0.1461,
0.2219
],
"allocatedBytesPerOperation": [
3359.777,
3359.514,
3368.849
],
"clientWorkingSetBytes": [
151945216,
151846912,
151781376
],
"serverWorkingSetBytes": [
225460224,
221364224,
226361344
]
}
},
"medianP95ChangePercent": 14.94885916601103,
"status": "diagnostic-within-budget"
},
{
"operation": "scalar-write",
"samples": {
"baseline": {
"p95Milliseconds": [
0.131,
0.1331,
0.135
],
"allocatedBytesPerOperation": [
6605.413,
6606.947,
6605.94
],
"clientWorkingSetBytes": [
137527296,
137445376,
137510912
],
"serverWorkingSetBytes": [
223887360,
226934784,
218546176
]
},
"candidate": {
"p95Milliseconds": [
0.1273,
0.1352,
0.1569
],
"allocatedBytesPerOperation": [
3359.777,
3359.514,
3368.849
],
"clientWorkingSetBytes": [
151945216,
151846912,
151781376
],
"serverWorkingSetBytes": [
225460224,
221364224,
226361344
]
}
},
"medianP95ChangePercent": 1.577761081893314,
"status": "diagnostic-within-budget"
},
{
"operation": "array-read",
"samples": {
"baseline": {
"p95Milliseconds": [
0.1622,
0.1462,
0.1297
],
"allocatedBytesPerOperation": [
6605.413,
6606.947,
6605.94
],
"clientWorkingSetBytes": [
137527296,
137445376,
137510912
],
"serverWorkingSetBytes": [
223887360,
226934784,
218546176
]
},
"candidate": {
"p95Milliseconds": [
0.1224,
0.1201,
0.1455
],
"allocatedBytesPerOperation": [
3359.777,
3359.514,
3368.849
],
"clientWorkingSetBytes": [
151945216,
151846912,
151781376
],
"serverWorkingSetBytes": [
225460224,
221364224,
226361344
]
}
},
"medianP95ChangePercent": -16.279069767441868,
"status": "diagnostic-within-budget"
},
{
"operation": "array-write",
"samples": {
"baseline": {
"p95Milliseconds": [
0.1618,
0.152,
0.1363
],
"allocatedBytesPerOperation": [
6605.413,
6606.947,
6605.94
],
"clientWorkingSetBytes": [
137527296,
137445376,
137510912
],
"serverWorkingSetBytes": [
223887360,
226934784,
218546176
]
},
"candidate": {
"p95Milliseconds": [
0.1253,
0.1258,
0.1433
],
"allocatedBytesPerOperation": [
3359.777,
3359.514,
3368.849
],
"clientWorkingSetBytes": [
151945216,
151846912,
151781376
],
"serverWorkingSetBytes": [
225460224,
221364224,
226361344
]
}
},
"medianP95ChangePercent": -17.23684210526316,
"status": "diagnostic-within-budget"
}
],
"status": "diagnostic-within-budget"
}
@@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""Supplementary warmed, matched native-process experiment; not full Gate G4."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import secrets
import shutil
import statistics
import subprocess
import time
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--baseline-harness', type=Path, required=True)
parser.add_argument('--candidate-harness', type=Path, required=True)
parser.add_argument('--output', type=Path, required=True)
parser.add_argument('--tiered-compilation', choices=['0', '1'], default='0')
args = parser.parse_args()
output = args.output.resolve()
output.mkdir(parents=True, exist_ok=False)
env = dict(os.environ, OPCUA_MATRIX_PASSWORD='otua_matrix_' + secrets.token_urlsafe(32),
DOTNET_TieredCompilation=args.tiered_compilation, OPCUA_MATRIX_PERF_ROUNDS='1',
OPCUA_MATRIX_PERF_WARMUPS='1000', OPCUA_MATRIX_PERF_MEASURED='2000')
for key in ('OPCUA_MATRIX_SERVER_SECURITY', 'OPCUA_MATRIX_CLIENT_PKI'):
env.pop(key, None)
metadata = {'scope': __doc__, 'environment': {k: env[k] for k in ('DOTNET_TieredCompilation', 'OPCUA_MATRIX_PERF_ROUNDS', 'OPCUA_MATRIX_PERF_WARMUPS', 'OPCUA_MATRIX_PERF_MEASURED')},
'dotnetSdk': subprocess.check_output(['dotnet', '--version'], text=True).strip(), 'p95BudgetPercent': 15,
'dateUtc': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()), 'logicalCpuCount': os.cpu_count()}
commands, results, hashes = [], [], []
def write(path, data):
path.write_text(json.dumps(data, indent=2) + '\n')
def run(command, log):
commands.append({'argv': list(map(str, command)), 'log': str(log)})
with log.open('w') as stream:
result = subprocess.run(list(map(str, command)), stdout=stream, stderr=subprocess.STDOUT, env=env, timeout=240)
if result.returncode:
raise RuntimeError(f'Process exited {result.returncode}; {log}')
def copy_certs(source, destination):
destination.mkdir(parents=True, exist_ok=True)
files = list(source.glob('*'))
if not files:
raise RuntimeError('Missing public certificates: ' + str(source))
for path in files:
shutil.copy2(path, destination / path.name)
try:
for pair in range(1, 4):
for version, harness in [('baseline', args.baseline_harness.resolve()), ('candidate', args.candidate_harness.resolve())]:
leg = output / f'pair-{pair}-{version}'
leg.mkdir()
client, server = leg / 'client', leg / 'server'
client.mkdir()
server.mkdir()
run(['dotnet', harness, 'prepare', client], leg / 'prepare.log')
copy_certs(client / 'client-pki/own/certs', server / 'server-pki/trusted/certs')
server_log = (leg / 'server.log').open('w')
command = ['dotnet', str(harness), 'server', str(server)]
commands.append({'argv': command, 'log': str(leg / 'server.log')})
process = subprocess.Popen(command, env=env, stdout=server_log, stderr=subprocess.STDOUT)
try:
deadline = time.monotonic() + 60
while not (server / 'ready.json').exists():
if process.poll() is not None or time.monotonic() > deadline:
raise RuntimeError('Server failed to start: ' + str(leg / 'server.log'))
time.sleep(.1)
ready = json.loads((server / 'ready.json').read_text())
copy_certs(server / 'server-pki/own/certs', client / 'client-pki/trusted/certs')
run(['dotnet', harness, 'performance', client, ready['endpoint']], leg / 'client.log')
result = json.loads((client / 'result.json').read_text())
result.update({'pair': pair, 'version': version, 'server': ready})
finally:
(server / 'stop').touch()
try:
process.wait(timeout=15)
except subprocess.TimeoutExpired:
process.terminate()
process.wait(timeout=10)
server_log.close()
result['serverResources'] = json.loads((server / 'server-resources.json').read_text())
results.append(result)
write(leg / 'measurement.json', result)
summary = []
for operation in ('scalar-read', 'scalar-write', 'array-read', 'array-write'):
samples = {}
for version in ('baseline', 'candidate'):
rounds = [o for r in results if r['version'] == version for o in r['observations'] if 'benchmarkRound' in o]
samples[version] = {'p95Milliseconds': [r['latencyMilliseconds'][operation]['p95'] for r in rounds],
'allocatedBytesPerOperation': [r['clientAllocatedBytesPerOperation'] for r in rounds],
'clientWorkingSetBytes': [r['clientWorkingSetBytes'] for r in rounds],
'serverWorkingSetBytes': [r['serverResources']['WorkingSet64'] for r in results if r['version'] == version]}
ratio = statistics.median(samples['candidate']['p95Milliseconds']) / statistics.median(samples['baseline']['p95Milliseconds'])
summary.append({'operation': operation, 'samples': samples, 'medianP95ChangePercent': 100 * (ratio - 1), 'status': 'diagnostic-regression' if ratio > 1.15 else 'diagnostic-within-budget'})
metadata['summary'] = summary
metadata['status'] = 'diagnostic-regression' if any(r['status'] == 'diagnostic-regression' for r in summary) else 'diagnostic-within-budget'
for row in summary:
print(f"{row['operation']}: median p95 {row['medianP95ChangePercent']:+.1f}% ({row['status']})")
finally:
for harness in (args.baseline_harness.resolve(), args.candidate_harness.resolve()):
for path in [harness, *harness.parent.glob('Opc.Ua*.dll'), *harness.parent.glob('ZB.MOM.WW.OtOpcUa*.dll'), *harness.parent.glob('OtOpcUa.Host.dll')]:
hashes.append({'path': str(path), 'sha256': hashlib.sha256(path.read_bytes()).hexdigest(), 'bytes': path.stat().st_size})
write(output / 'artifact-hashes.json', hashes)
write(output / 'commands.json', commands)
write(output / 'measurements.json', results)
write(output / 'summary.json', metadata)
return 2 if metadata.get('status') == 'diagnostic-regression' else 0
if __name__ == '__main__':
raise SystemExit(main())
@@ -0,0 +1,194 @@
#!/usr/bin/env python3
"""Separate-process production application compatibility gate (no mixed SDK process)."""
import argparse
import hashlib
import json
import os
from pathlib import Path
import secrets
import shutil
import subprocess
import time
import uuid
import xml.etree.ElementTree as ET
HERE = Path(__file__).resolve().parent
HOST = 'src/Server/ZB.MOM.WW.OtOpcUa.Host/ZB.MOM.WW.OtOpcUa.Host.csproj'
CLIENT = 'src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/ZB.MOM.WW.OtOpcUa.Client.Shared.csproj'
DRIVER = 'src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.csproj'
CLI = 'src/Client/ZB.MOM.WW.OtOpcUa.Client.CLI/ZB.MOM.WW.OtOpcUa.Client.CLI.csproj'
def write_json(path, value):
path.write_text(json.dumps(value, indent=2) + '\n')
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--baseline-root', required=True, type=Path)
parser.add_argument('--baseline-artifacts', required=True, type=Path, help='Existing immutable host/ and client/ publishes')
parser.add_argument('--candidate-root', required=True, type=Path, help='Dedicated candidate checkout; this script builds it')
parser.add_argument('--container-image', default='mcr.microsoft.com/dotnet/sdk:10.0.103-noble', help='Disposable local driver/CLI isolation; must supply .NET 10 and bash')
parser.add_argument('--output', required=True, type=Path, help='Fresh nonexistent evidence directory')
args = parser.parse_args()
args.baseline_root = args.baseline_root.resolve()
args.candidate_root = args.candidate_root.resolve()
args.baseline_artifacts = args.baseline_artifacts.resolve()
args.output = args.output.resolve()
args.output.mkdir(parents=True, exist_ok=False)
source_info = {}
for name, root in [('baseline', args.baseline_root), ('candidate', args.candidate_root)]:
source_info[name] = {'root': str(root), 'commit': subprocess.check_output(['git', '-C', str(root), 'rev-parse', 'HEAD'], text=True).strip(),
'sdkPackages': str(root / 'Directory.Packages.props')}
source_info['scope'] = 'Loopback application contract and 3 warmed 50-operation rounds per scalar/Int32[3] read/write kind; shared development host, no full load/reconnect/failover/backend/soak performance claim.'
source_info['dateUtc'] = time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime())
write_json(args.output / 'source-info.json', source_info)
commands = []
matrix = []
env = dict(os.environ, OPCUA_MATRIX_PASSWORD='otua_matrix_' + secrets.token_urlsafe(32))
env.pop('OPCUA_MATRIX_CLIENT_PKI', None)
env.pop('OPCUA_MATRIX_SERVER_SECURITY', None)
def run(command, log, process_env=env, timeout=300):
commands.append({'argv': ['<ephemeral-key>' if x == env['OPCUA_MATRIX_PASSWORD'] else str(x) for x in command], 'log': str(log)})
with log.open('w') as stream:
result = subprocess.run([str(x) for x in command], stdout=stream, stderr=subprocess.STDOUT, env=process_env, timeout=timeout)
return result.returncode
def build(version):
folder = args.output / ('build-' + version)
folder.mkdir()
project = ET.Element('Project', Sdk='Microsoft.NET.Sdk')
props = ET.SubElement(project, 'PropertyGroup')
for k, v in {'OutputType': 'Exe', 'TargetFramework': 'net10.0', 'Nullable': 'enable', 'ImplicitUsings': 'enable', 'LangVersion': 'latest', 'DefineConstants': 'SDK2' if version == 'candidate' else ''}.items():
ET.SubElement(props, k).text = v
items = ET.SubElement(project, 'ItemGroup')
ET.SubElement(items, 'FrameworkReference', Include='Microsoft.AspNetCore.App')
if version == 'candidate':
for path in (HOST, CLIENT, DRIVER):
ET.SubElement(items, 'ProjectReference', Include=str(args.candidate_root / path))
else:
dlls = {}
for path in ('host', 'client'):
for dll in (args.baseline_artifacts / path).glob('*.dll'):
dlls[dll.name] = dll
for name, dll in sorted(dlls.items()):
ref = ET.SubElement(items, 'Reference', Include=name[:-4])
ET.SubElement(ref, 'HintPath').text = str(dll)
ET.SubElement(ref, 'Private').text = 'true'
ET.SubElement(items, 'Compile', Include=str(HERE / 'ProcessHost.cs'))
csproj = folder / 'ProcessHost.csproj'
ET.ElementTree(project).write(csproj, encoding='unicode')
status = run(['dotnet', 'build', csproj, '-c', 'Release', '-m:1', '--nologo'], folder / 'build.log')
if status:
raise RuntimeError(f'{version} harness build failed ({status}); see {folder / "build.log"}')
return folder / 'bin/Release/net10.0/ProcessHost.dll'
def certificates(source, target):
target.mkdir(parents=True, exist_ok=True)
files = list(source.glob('*'))
if not files:
raise RuntimeError('No public certificates at ' + str(source))
for file in files:
shutil.copy2(file, target / file.name)
def receipt(paths):
return [{'path': str(p), 'sha256': hashlib.sha256(p.read_bytes()).hexdigest(), 'bytes': p.stat().st_size} for p in sorted(set(paths)) if p.is_file()]
baseline = candidate = candidate_cli = None
try:
# Baseline builds only the portable harness against the exact published production DLLs.
baseline = build('baseline')
candidate = build('candidate')
candidate_cli = args.output / 'candidate-cli'
status = run(['dotnet', 'publish', args.candidate_root / CLI, '-c', 'Release', '-o', candidate_cli, '-m:1', '--nologo'], args.output / 'candidate-cli-build.log')
if status:
raise RuntimeError('Candidate CLI publish failed')
for name, client, server in [('baseline-client-to-baseline-server', baseline, baseline), ('baseline-client-to-candidate-server', baseline, candidate), ('candidate-client-to-baseline-server', candidate, baseline), ('candidate-client-to-candidate-server', candidate, candidate)]:
leg = args.output / name
leg.mkdir()
server_root = leg / 'server'
client_root = leg / 'shared'
server_root.mkdir()
client_root.mkdir()
status = run(['dotnet', client, 'prepare', client_root], leg / 'prepare.log')
if status:
matrix.append({'name': name, 'status': 'failed', 'stage': 'client-certificate-preparation'})
continue
certificates(client_root / 'client-pki/own/certs', server_root / 'server-pki/trusted/certs')
server_log = (leg / 'server.log').open('w')
command = ['dotnet', str(server), 'server', str(server_root)]
commands.append({'argv': command, 'log': str(leg / 'server.log')})
proc = subprocess.Popen(command, stdout=server_log, stderr=subprocess.STDOUT, env=env)
try:
deadline = time.monotonic() + 60
while not (server_root / 'ready.json').exists():
if proc.poll() is not None or time.monotonic() > deadline:
raise RuntimeError(f'{name}: server did not become ready; see server.log')
time.sleep(.1)
ready = json.loads((server_root / 'ready.json').read_text())
certificates(server_root / 'server-pki/own/certs', client_root / 'client-pki/trusted/certs')
status = run(['dotnet', client, 'client', client_root, ready['endpoint']], leg / 'shared.log')
result = json.loads((client_root / 'result.json').read_text())
history = [json.loads(x) for x in (server_root / 'history-requests.jsonl').read_text().splitlines()] if (server_root / 'history-requests.jsonl').exists() else []
result.update({'name': name, 'server': ready, 'status': 'passed' if status == 0 else 'failed', 'historyBackendRequests': history, 'certificateValidation': 'explicit trusted peers; server and Shared client autoaccept disabled', 'authentication': 'ephemeral API-key-shaped credential, exact fixture authenticator; real authority/ACL/method gates'})
write_json(leg / 'leg.json', result)
matrix.append(result)
except Exception as exc:
matrix.append({'name': name, 'status': 'failed', 'error': str(exc)})
finally:
(server_root / 'stop').touch()
try:
proc.wait(timeout=15)
except subprocess.TimeoutExpired:
proc.terminate()
proc.wait(timeout=10)
server_log.close()
image_info = subprocess.check_output(['docker', 'image', 'inspect', args.container_image, '--format', '{{json .}}'], text=True)
image_data = json.loads(image_info)
write_json(args.output / 'container-image.json', {k: image_data.get(k) for k in ('Id', 'RepoDigests', 'Architecture', 'Os')})
for server_name, server in [('baseline', baseline), ('candidate', candidate)]:
name = 'candidate-driver-cli-to-' + server_name + '-server'
leg = args.output / name
leg.mkdir()
shutil.copy2(HERE / 'container-leg.sh', leg / 'run.sh')
container_name = 'otopcua-sdk2-matrix-' + uuid.uuid4().hex[:12]
command = ['docker', 'run', '--rm', '--name', container_name, '--network', 'none', '-e', 'OPCUA_MATRIX_PASSWORD',
'-v', str(candidate.parent) + ':/candidate:ro', '-v', str(server.parent) + ':/server:ro',
'-v', str(candidate_cli) + ':/cli:ro', '-v', str(leg) + ':/task', args.container_image, 'bash', '/task/run.sh']
try:
status = run(command, leg / 'container.log')
finally:
subprocess.run(['docker', 'rm', '-f', container_name], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
if (leg / 'driver/result.json').exists():
result = json.loads((leg / 'driver/result.json').read_text())
else:
result = {'cases': [], 'error': 'Driver result missing; inspect preparation/container/server logs'}
for operation, expected in [('read', 'Value: 92'), ('raw-history', '25 values returned.'), ('event-history', '25 events returned.')]:
log = leg / ('cli-' + operation + '.log')
passed = log.exists() and expected in log.read_text()
result['cases'].append({'name': 'production-CLI-' + operation, 'status': 'passed' if passed else 'failed', 'log': str(log), 'expectedOutput': expected})
result.update({'name': name, 'status': 'passed' if status == 0 and all(x['status'] == 'passed' for x in result['cases']) else 'failed',
'container': container_name, 'network': 'none; all peers in task container, separate SDK processes',
'driverCertificateValidation': 'explicit trusted peers; autoaccept disabled', 'cliCertificateValidation': 'explicit exchanged peers; CLI always configures AutoAcceptCertificates=true (CommandBase.CreateConnectionSettings)',
'server': json.loads((leg / 'server/ready.json').read_text()) if (leg / 'server/ready.json').exists() else None})
write_json(leg / 'leg.json', result)
matrix.append(result)
finally:
paths = [p for p in (baseline, candidate, args.baseline_root / 'Directory.Packages.props', args.candidate_root / 'Directory.Packages.props', HERE / 'ProcessHost.cs', HERE / 'run.py', HERE / 'container-leg.sh') if p is not None]
for folder in (args.baseline_artifacts / 'host', args.baseline_artifacts / 'client', candidate.parent if candidate else None, candidate_cli):
if folder is not None:
paths.extend(folder.glob('Opc.Ua*.dll'))
paths.extend(folder.glob('*.deps.json'))
paths.extend(folder.glob('ZB.MOM.WW.OtOpcUa*.dll'))
paths.extend(folder.glob('OtOpcUa.Host.dll'))
paths.extend(folder.glob('*.runtimeconfig.json'))
write_json(args.output / 'artifact-hashes.json', receipt(paths))
write_json(args.output / 'commands.json', commands)
write_json(args.output / 'matrix.json', matrix)
return 1 if not matrix or any(x['status'] != 'passed' for x in matrix) else 0
if __name__ == '__main__':
raise SystemExit(main())
@@ -0,0 +1 @@
__pycache__/
@@ -0,0 +1,107 @@
# Linux SDK 2 server lifecycle soak
This launcher publishes and runs the existing
`Sdk2LifecycleSoakTests.Repeated_lifecycles_return_resources_to_a_steady_baseline`
without copying, rewriting, suppressing or changing its test logic. It imports the
canonical descriptor fixes from `642aefe3`: physical symlink resolution, path
separator boundaries, open/closed PKI positive controls, and bounded probe process
and stream cleanup. The same test still owns the production server, node manager,
sessions, subscriptions, continuation points, revocation, stalled TCP proxy,
surgical changes/rebuild and same-PKI restarts.
A diagnostic run:
```sh
python3 scripts/validation/opcua-server-lifecycle-linux/run.py \
--duration 90 --output /tmp/otopcua-server-linux-diagnostic-unique
```
The coordinator must launch and own a full run in its persistent execution
session. A diagnostic cannot satisfy the full gate:
```sh
python3 scripts/validation/opcua-server-lifecycle-linux/run.py \
--full --duration 7200 --output /tmp/otopcua-server-linux-full-unique
```
An already published artifact can be reused with
`--published-app /absolute/path/to/app`. Its parent must contain the launcher's
`publish-receipt.json`; the test source, apphost and test assembly hashes must
match. The recorded diagnostic artifact can be reused with:
```sh
python3 /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/scripts/validation/opcua-server-lifecycle-linux/run.py \
--full --duration 7200 \
--published-app /tmp/opcua2-server-linux-diagnostic-20261110a/app \
--output /tmp/opcua2-server-linux-full-20261110
```
The output directory must be fresh. It is mode 0700 and can contain task-owned
private PKI under `task/tmp` during a run or after a failure. Never commit the
entire output. The existing successful test removes its own stores. Only selected
redacted receipt/log/JSONL/TRX files belong under this directory's `evidence/`.
The exact publish command uses the host .NET SDK (recorded as 10.0.403 for the
verified diagnostic), RID `linux-arm64`, self-contained runtime 10.0.14, explicit
`UseAppHost=true`, `PublishSingleFile=false`, `PublishTrimmed=false`, one MSBuild
node, and an external task-owned artifacts directory. All runtime packs were
already cached. No production or test source is patched during publish. The
launcher requires an empty production/package source diff against `7b353d7b` and
records the actual published revision separately from the launcher revision.
That is source equivalence, not a claim that separately built Linux and macOS
assemblies have identical hashes. The full publish file hashes, exact test source
hash, runtimeconfig and SDK dependency versions are retained.
The cached official SDK image
`mcr.microsoft.com/dotnet/sdk:10.0.103-noble` is resolved to its immutable local
image ID and must be Linux arm64. The container has `--network none`, no host
ports and only a read-only application mount plus its fresh task volume.
`TMPDIR=/task/tmp` and `XDG_DATA_HOME=/task/data` isolate temporary files and PKI;
`HOME` is not changed. Nothing targets fleet instances, production stores or
other task fixtures.
The image's VSTest runner first executes exactly the two existing descriptor
controls. A separate invocation executes exactly one lifecycle test. Both TRX
files must contain the expected exact executed/passed counts, no skips and no
failure/error/abort/timeout. The published xUnit v3 application must be ELF64
AArch64. During the live test, `/proc/<testpid>/exe` must point to the published
application and the mapped CLR must be `/app/libcoreclr.so`, proving that the
out-of-process test host is the self-contained Linux publish rather than an
accidentally copied macOS host.
The original test resource limits remain **64 MiB retained managed growth,
128 MiB RSS growth, and 32 additional FDs**, using its original third-cycle
baseline and original managed trend check. Quiescent sessions, subscriptions,
items, browse/history points, monitored-node/live-item counts and PKI FDs must be
zero. Cached certificate stores and address-space shape must remain at baseline.
The original exact-tag read-only diagnostics and manager/store disposal assertions
are unchanged. The wrapper verifies the same limits in the header and requires
one start, one completion, no failed row, one active/stall/quiescent row per
completed cycle and one restart per four cycles. Full mode requires both requested
and actual monotonic observation time of at least 7200 seconds and a true final
`satisfiesTwoHourDuration`. The outer container deadline is duration plus 300
seconds. Its own container is forcibly removed on timeout/interruption.
Artifacts include `publish.log`, `publish-receipt.json`, `source.json`,
`artifact-manifest.json`, `command.json`, `result.json`, `container.log`, and
`task/{soak.jsonl,soak.log,descriptor-controls.log,linux-precheck.txt,
linux-runtime-process.txt,container-dotnet-info.txt,results/*.trx}`. A reused
artifact keeps its original publish receipt; `source.json` identifies both source
revisions. `result.json` is passing only after TRX and completion validation.
This supplies supported Linux runtime evidence. It does not resolve the observed
macOS RSS failure or establish its cause. A short Linux pass is not a two-hour
pass, and a later Linux pass alone cannot explain away the macOS failure. This
lane makes no Windows, AVEVA, interoperability or complete G4 performance claim.
The final checked-in diagnostic completed **91.602 seconds**, 25 cycles, six
actual server restarts, 25 recovered network stalls, and one passing lifecycle
TRX result. Both descriptor tests passed: the symlink control observed
`before=0, opened=1, closed=0`, excluded the sibling path, and the timed-out probe
was reaped in 267 ms. All quiescent logical-resource counts and PKI FDs were zero.
Third-cycle to final deltas were **−145,080 managed bytes, +53,739,520 RSS bytes,
and +2 FDs**, within the unchanged diagnostic limits. These short observations do
not establish a two-hour resource trend. The full Linux gate remains pending.
CLI rejection of `--full --duration 90`, rejection of a short completion as a full
run, and rejection of the wrong TRX executed count were also verified. Selected
receipts are in `evidence/2026-11-10-diagnostic/`.
@@ -0,0 +1,41 @@
#!/usr/bin/env bash
# Task-owned Linux namespace only. Existing test logic and limits are unchanged.
set -euo pipefail
mkdir -p /task/tmp /task/data /task/results
export TMPDIR=/task/tmp
export XDG_DATA_HOME=/task/data
export OTOPCUA_SDK2_SOAK=1
export OTOPCUA_SDK2_SOAK_OUTPUT=/task/soak.jsonl
export DOTNET_CLI_TELEMETRY_OPTOUT=1
export DOTNET_NOLOGO=1
[[ $(uname -s) == Linux && $(uname -m) == aarch64 ]]
[[ -d /proc/self/fd ]]
printf 'kernel=%s machine=%s tmp=%s procfs=yes\n' "$(uname -s)" "$(uname -m)" "$(readlink -f "$TMPDIR")" > /task/linux-precheck.txt
dotnet --info > /task/container-dotnet-info.txt
dotnet vstest /app/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.dll \
--TestCaseFilter:'FullyQualifiedName~Sdk2LifecycleSoakTests.Descriptor_probe_' \
--ResultsDirectory:/task/results '--Logger:trx;LogFileName=descriptor-controls.trx' > /task/descriptor-controls.log 2>&1
# VSTest launches the published xUnit v3 self-contained Linux ELF apphost.
# A distinct invocation gives the soak its own otherwise idle test process.
dotnet vstest /app/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.dll \
--TestCaseFilter:'FullyQualifiedName=ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Repeated_lifecycles_return_resources_to_a_steady_baseline' \
--ResultsDirectory:/task/results '--Logger:trx;LogFileName=soak.trx' > /task/soak.log 2>&1 &
vstest_pid=$!
observed=0
for attempt in $(seq 1 600); do
if [[ -s /task/soak.jsonl ]]; then
test_pid=$(head -n 1 /task/soak.jsonl | sed -n 's/.*"processId":\([0-9]*\),.*/\1/p')
[[ -n "$test_pid" ]]
test_exe=$(readlink "/proc/$test_pid/exe")
[[ "$test_exe" == /app/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests ]]
printf 'testProcessId=%s\nactualExecutable=%s\n' "$test_pid" "$test_exe" > /task/linux-runtime-process.txt
awk '$6 ~ /\/(libcoreclr.so|libhostfxr.so|libhostpolicy.so|System.Private.CoreLib.dll)$/ {print $6}' "/proc/$test_pid/maps" | sort -u >> /task/linux-runtime-process.txt
grep -Fx /app/libcoreclr.so /task/linux-runtime-process.txt > /dev/null
observed=1
break
fi
kill -0 "$vstest_pid" 2>/dev/null || break
sleep 0.1
done
[[ "$observed" == 1 ]]
wait "$vstest_pid"
@@ -0,0 +1,25 @@
{
"argv": [
"docker",
"run",
"--rm",
"--name",
"otopcua-server-linux-soak-fb2c804a7d01",
"--network",
"none",
"-e",
"OTOPCUA_SDK2_SOAK_MODE=diagnostic",
"-e",
"OTOPCUA_SDK2_SOAK_SECONDS=90",
"-e",
"OTOPCUA_SOAK_BUILD_SHA=74c938f37cbb9cf08b6ca72e4effc511120dc274",
"-v",
"/private/tmp/opcua2-server-linux-diagnostic-20261110a/app:/app:ro",
"-v",
"/private/tmp/opcua2-server-linux-diagnostic-20261110c/task:/task",
"sha256:b04611ee9e1b7d36797012ed921962c57189cb4dbb3dff12afb8e158110f293b",
"bash",
"/task/container.sh"
],
"timeoutSeconds": 390
}
@@ -0,0 +1,51 @@
.NET SDK:
Version: 10.0.103
Commit: c2435c3e0f
Workload version: 10.0.100-manifests.a62d7899
MSBuild version: 18.0.11+c2435c3e0
Runtime Environment:
OS Name: ubuntu
OS Version: 24.04
OS Platform: Linux
RID: linux-arm64
Base Path: /usr/share/dotnet/sdk/10.0.103/
.NET workloads installed:
There are no installed workloads to display.
Configured to use workload sets when installing new manifests.
No workload sets are installed. Run "dotnet workload restore" to install a workload set.
Host:
Version: 10.0.3
Architecture: arm64
Commit: c2435c3e0f
.NET SDKs installed:
10.0.103 [/usr/share/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 10.0.3 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 10.0.3 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Other architectures found:
None
Environment variables:
DOTNET_CLI_TELEMETRY_OPTOUT [1]
DOTNET_GENERATE_ASPNET_CERTIFICATE [false]
DOTNET_NOLOGO [1]
DOTNET_ROLL_FORWARD [Major]
DOTNET_RUNNING_IN_CONTAINER [true]
DOTNET_SDK_VERSION [10.0.103]
DOTNET_USE_POLLING_FILE_WATCHER [true]
DOTNET_VERSION [10.0.3]
global.json file:
Not found
Learn more:
https://aka.ms/dotnet/info
Download .NET:
https://aka.ms/dotnet/download
@@ -0,0 +1,7 @@
VSTest version 18.0.1 (arm64)
Starting test execution, please wait...
A total of 1 test files matched the specified pattern.
Results File: /task/results/descriptor-controls.trx
Passed! - Failed: 0, Passed: 2, Skipped: 0, Total: 2, Duration: 297 ms - ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.dll (net10.0)
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<TestRun id="a4046507-6b54-4afc-b1d6-dbb3ad85db1c" name="@8c898f464f50 2026-11-10 18:06:02" xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<Times creation="2026-11-10T18:06:02.0288408+00:00" queuing="2026-11-10T18:06:02.0288408+00:00" start="2026-11-10T18:06:01.1322717+00:00" finish="2026-11-10T18:06:02.0312051+00:00" />
<TestSettings name="default" id="bfdcc811-3a6d-455f-9eda-152573bdc6d9">
<Deployment runDeploymentRoot="_8c898f464f50_2026-11-10_18_06_02" />
</TestSettings>
<Results>
<UnitTestResult executionId="5dae5583-2c39-479e-9715-2339d7f6593d" testId="02aca891-6c73-5df6-4396-20f20d6490ce" testName="ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Descriptor_probe_times_out_and_reaps_a_process_that_keeps_both_streams_open" computerName="8c898f464f50" duration="00:00:00.2676070" startTime="2026-11-10T18:06:01.6988716+00:00" endTime="2026-11-10T18:06:01.9669755+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="5dae5583-2c39-479e-9715-2339d7f6593d">
<Output>
<StdOut>Descriptor timeout control: deadlineMs=250, elapsedMs=267, childExited=True</StdOut>
</Output>
</UnitTestResult>
<UnitTestResult executionId="b05a5663-eb92-4c4c-993a-7236c459b1ce" testId="1d78597f-0424-4abc-5484-1d1084deba0d" testName="ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Descriptor_probe_observes_an_open_PKI_file_through_a_symlink_alias_and_its_close" computerName="8c898f464f50" duration="00:00:00.0235426" startTime="2026-11-10T18:06:01.6695099+00:00" endTime="2026-11-10T18:06:01.6964907+00:00" testType="13cdc9d9-ddb5-4fa4-a97d-d965ccfc6d4b" outcome="Passed" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" relativeResultsDirectory="b05a5663-eb92-4c4c-993a-7236c459b1ce">
<Output>
<StdOut>PKI descriptor control: before=0, opened=1, closed=0; siblingExcluded=true; aliasResolved=true</StdOut>
</Output>
</UnitTestResult>
</Results>
<TestDefinitions>
<UnitTest name="ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Descriptor_probe_observes_an_open_PKI_file_through_a_symlink_alias_and_its_close" storage="/app/zb.mom.ww.otopcua.opcuaserver.integrationtests.dll" id="1d78597f-0424-4abc-5484-1d1084deba0d">
<Execution id="b05a5663-eb92-4c4c-993a-7236c459b1ce" />
<TestMethod codeBase="/app/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.dll" adapterTypeName="executor://xunit/VsTestRunner3/netcore/" className="ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests" name="Descriptor_probe_observes_an_open_PKI_file_through_a_symlink_alias_and_its_close" />
</UnitTest>
<UnitTest name="ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests.Descriptor_probe_times_out_and_reaps_a_process_that_keeps_both_streams_open" storage="/app/zb.mom.ww.otopcua.opcuaserver.integrationtests.dll" id="02aca891-6c73-5df6-4396-20f20d6490ce">
<Execution id="5dae5583-2c39-479e-9715-2339d7f6593d" />
<TestMethod codeBase="/app/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.dll" adapterTypeName="executor://xunit/VsTestRunner3/netcore/" className="ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.Sdk2LifecycleSoakTests" name="Descriptor_probe_times_out_and_reaps_a_process_that_keeps_both_streams_open" />
</UnitTest>
</TestDefinitions>
<TestEntries>
<TestEntry testId="02aca891-6c73-5df6-4396-20f20d6490ce" executionId="5dae5583-2c39-479e-9715-2339d7f6593d" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestEntry testId="1d78597f-0424-4abc-5484-1d1084deba0d" executionId="b05a5663-eb92-4c4c-993a-7236c459b1ce" testListId="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
</TestEntries>
<TestLists>
<TestList name="Results Not in a List" id="8c84fa94-04c1-424b-9868-57a2d4851a1d" />
<TestList name="All Loaded Results" id="19431567-8539-422a-85d7-44ee4e166bda" />
</TestLists>
<ResultSummary outcome="Completed">
<Counters total="2" executed="2" passed="2" 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" />
<Output>
<StdOut>[xUnit.net 00:00:00.00] xUnit.net VSTest Adapter v3.0.2+dd36e86129 (64-bit .NET 10.0.14)
[xUnit.net 00:00:00.08] Discovering: ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests
[xUnit.net 00:00:00.22] Discovered: ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests
[xUnit.net 00:00:00.30] Starting: ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests
[xUnit.net 00:00:00.64] Finished: ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests
</StdOut>
</Output>
</ResultSummary>
</TestRun>
@@ -0,0 +1,3 @@
usage: run.py [-h] --output OUTPUT [--duration DURATION] [--full]
[--published-app PUBLISHED_APP] [--image IMAGE]
run.py: error: full requires duration >=7200; diagnostic requires 60..120 seconds
@@ -0,0 +1 @@
kernel=Linux machine=aarch64 tmp=/task/tmp procfs=yes
@@ -0,0 +1,6 @@
testProcessId=196
actualExecutable=/app/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests
/app/System.Private.CoreLib.dll
/app/libcoreclr.so
/app/libhostfxr.so
/app/libhostpolicy.so
@@ -0,0 +1,29 @@
{
"sourceRevision": "74c938f37cbb9cf08b6ca72e4effc511120dc274",
"command": [
"dotnet",
"publish",
"/Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj",
"-c",
"Release",
"-r",
"linux-arm64",
"--self-contained",
"true",
"-p:RuntimeFrameworkVersion=10.0.14",
"-p:PublishSingleFile=false",
"-p:PublishTrimmed=false",
"-p:UseAppHost=true",
"--artifacts-path",
"/tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts",
"-o",
"/tmp/opcua2-server-linux-diagnostic-20261110a/app",
"-m:1",
"--nologo"
],
"hostDotnet": ".NET SDK:\n Version: 10.0.403\n Commit: 5a2162bea6\n Workload version: 10.0.400-manifests.a00bebb6\n MSBuild version: 18.9.15+5a2162bea\n\nRuntime Environment:\n OS Name: Mac OS X\n OS Version: 26.5\n OS Platform: Darwin\n RID: osx-arm64\n Base Path: /opt/homebrew/Cellar/dotnet/10.0.403/libexec/sdk/10.0.403/\n\n.NET workloads installed:\nThere are no installed workloads to display.\nConfigured to use workload sets when installing new manifests.\nNo workload sets are installed. Run \"dotnet workload restore\" to install a workload set.\n\nHost:\n Version: 10.0.14\n Architecture: arm64\n Commit: 0427b9abbe\n\n.NET SDKs installed:\n 10.0.403 [/opt/homebrew/Cellar/dotnet/10.0.403/libexec/sdk]\n\n.NET runtimes installed:\n Microsoft.AspNetCore.App 10.0.14 [/opt/homebrew/Cellar/dotnet/10.0.403/libexec/shared/Microsoft.AspNetCore.App]\n Microsoft.NETCore.App 10.0.14 [/opt/homebrew/Cellar/dotnet/10.0.403/libexec/shared/Microsoft.NETCore.App]\n\nOther architectures found:\n None\n\nEnvironment variables:\n DOTNET_ROOT [/opt/homebrew/Cellar/dotnet/10.0.403/libexec]\n\nglobal.json file:\n /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/global.json\n\nLearn more:\n https://aka.ms/dotnet/info\n\nDownload .NET:\n https://aka.ms/dotnet/download\n",
"testSourceSha256": "e695783e05787d94bf5d167b25b1c48b446b800c28259f023c28ed6012d737d1",
"apphostSha256": "97531b8005df9dc8b129d2b22ba2049cf572d5d970046f7e8644ec632e860032",
"testAssemblySha256": "9d64b5b3dd9bf7eff38f6fabe10382c107ab824485a309ba9649bfee9bbd843a",
"publishExitCode": 0
}
@@ -0,0 +1,121 @@
Determining projects to restore...
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Abstractions/ZB.MOM.WW.OtOpcUa.Core.Abstractions.csproj (in 490 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.csproj (in 494 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.csproj (in 494 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.csproj (in 2 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.csproj (in 4 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.csproj (in 569 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Tooling/ZB.MOM.WW.OtOpcUa.Analyzers/ZB.MOM.WW.OtOpcUa.Analyzers.csproj (in 574 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.csproj (in 1 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.csproj (in 591 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.ScriptWorker/ZB.MOM.WW.OtOpcUa.ScriptWorker.csproj (in 589 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.csproj (in 6 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.csproj (in 6 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.Security/ZB.MOM.WW.OtOpcUa.Security.csproj (in 605 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.csproj (in 2 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.csproj (in 36 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Calculation/ZB.MOM.WW.OtOpcUa.Driver.Calculation.csproj (in 101 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.csproj (in 107 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbCip/ZB.MOM.WW.OtOpcUa.Driver.AbCip.csproj (in 31 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer/ZB.MOM.WW.OtOpcUa.OpcUaServer.csproj (in 613 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.csproj (in 9 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.csproj (in 10 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.csproj (in 6 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.csproj (in 19 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core/ZB.MOM.WW.OtOpcUa.Core.csproj (in 30 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.csproj (in 27 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.csproj (in 2 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.Runtime/ZB.MOM.WW.OtOpcUa.Runtime.csproj (in 651 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.VirtualTags/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.csproj (in 12 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.Scripting/ZB.MOM.WW.OtOpcUa.Core.Scripting.csproj (in 12 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Commons/ZB.MOM.WW.OtOpcUa.Commons.csproj (in 4 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.MTConnect/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.csproj (in 33 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.csproj (in 656 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.csproj (in 655 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.csproj (in 144 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Mqtt/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.csproj (in 36 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.csproj (in 11 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.csproj (in 6 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Client/ZB.MOM.WW.OtOpcUa.Client.Shared/ZB.MOM.WW.OtOpcUa.Client.Shared.csproj (in 11 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.csproj (in 2 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.csproj (in 2 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.csproj (in 44 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Cluster/ZB.MOM.WW.OtOpcUa.Cluster.csproj (in 45 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.csproj (in 6 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.csproj (in 36 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.csproj (in 10 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql/ZB.MOM.WW.OtOpcUa.Driver.Sql.csproj (in 50 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.csproj (in 66 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.ControlPlane/ZB.MOM.WW.OtOpcUa.ControlPlane.csproj (in 53 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.csproj (in 3 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Modbus/ZB.MOM.WW.OtOpcUa.Driver.Modbus.csproj (in 41 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.csproj (in 9 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.S7/ZB.MOM.WW.OtOpcUa.Driver.S7.csproj (in 49 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Core/ZB.MOM.WW.OtOpcUa.Configuration/ZB.MOM.WW.OtOpcUa.Configuration.csproj (in 92 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.csproj (in 51 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.csproj (in 86 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Drivers/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.csproj (in 24 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.AdminUI/ZB.MOM.WW.OtOpcUa.AdminUI.csproj (in 89 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/src/Server/ZB.MOM.WW.OtOpcUa.Host/ZB.MOM.WW.OtOpcUa.Host.csproj (in 784 ms).
Restored /Users/dohertj2/.codex/worktrees/opcua2-client-lifecycle/OtOpcUa/tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.csproj (in 793 ms).
ZB.MOM.WW.OtOpcUa.Analyzers -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Analyzers/release/ZB.MOM.WW.OtOpcUa.Analyzers.dll
ZB.MOM.WW.OtOpcUa.Core.Abstractions -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.Abstractions/release/ZB.MOM.WW.OtOpcUa.Core.Abstractions.dll
ZB.MOM.WW.OtOpcUa.Commons -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Commons/release/ZB.MOM.WW.OtOpcUa.Commons.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions/release/ZB.MOM.WW.OtOpcUa.Core.Scripting.Abstractions.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.Scripting/release/ZB.MOM.WW.OtOpcUa.Core.Scripting.dll
ZB.MOM.WW.OtOpcUa.Core.VirtualTags -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.VirtualTags/release/ZB.MOM.WW.OtOpcUa.Core.VirtualTags.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.Sql.Contracts.dll
ZB.MOM.WW.OtOpcUa.Configuration -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Configuration/release/ZB.MOM.WW.OtOpcUa.Configuration.dll
ZB.MOM.WW.OtOpcUa.Core -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core/release/ZB.MOM.WW.OtOpcUa.Core.dll
ZB.MOM.WW.OtOpcUa.OpcUaServer -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.OpcUaServer/release/ZB.MOM.WW.OtOpcUa.OpcUaServer.dll
ZB.MOM.WW.OtOpcUa.Cluster -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Cluster/release/ZB.MOM.WW.OtOpcUa.Cluster.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol/release/ZB.MOM.WW.OtOpcUa.Core.Scripting.Protocol.dll
ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess/release/ZB.MOM.WW.OtOpcUa.Core.Scripting.OutOfProcess.dll
ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms/release/ZB.MOM.WW.OtOpcUa.Core.ScriptedAlarms.dll
ZB.MOM.WW.OtOpcUa.Security -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Security/release/ZB.MOM.WW.OtOpcUa.Security.dll
ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing/release/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Addressing.dll
ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.Modbus.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.S7.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.AbCip.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.Calculation.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Contracts.dll
ZB.MOM.WW.OtOpcUa.ControlPlane -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.ControlPlane/release/ZB.MOM.WW.OtOpcUa.ControlPlane.dll
ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian/release/ZB.MOM.WW.OtOpcUa.Core.AlarmHistorian.dll
ZB.MOM.WW.OtOpcUa.Runtime -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Runtime/release/ZB.MOM.WW.OtOpcUa.Runtime.dll
ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts/release/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Contracts.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session/release/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Session.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser/release/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.Browser.dll
ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser/release/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.Browser.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect/release/ZB.MOM.WW.OtOpcUa.Driver.Sql.Dialect.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser/release/ZB.MOM.WW.OtOpcUa.Driver.Sql.Browser.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport/release/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Transport.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser/release/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.Browser.dll
ZB.MOM.WW.OtOpcUa.AdminUI -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.AdminUI/release/ZB.MOM.WW.OtOpcUa.AdminUI.dll
ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport/release/ZB.MOM.WW.OtOpcUa.Driver.Ab.Transport.dll
ZB.MOM.WW.OtOpcUa.Driver.AbCip -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.AbCip/release/ZB.MOM.WW.OtOpcUa.Driver.AbCip.dll
ZB.MOM.WW.OtOpcUa.Driver.AbLegacy -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy/release/ZB.MOM.WW.OtOpcUa.Driver.AbLegacy.dll
ZB.MOM.WW.OtOpcUa.Driver.Calculation -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Calculation/release/ZB.MOM.WW.OtOpcUa.Driver.Calculation.dll
ZB.MOM.WW.OtOpcUa.Driver.FOCAS -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.FOCAS/release/ZB.MOM.WW.OtOpcUa.Driver.FOCAS.dll
ZB.MOM.WW.OtOpcUa.Driver.Galaxy -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Galaxy/release/ZB.MOM.WW.OtOpcUa.Driver.Galaxy.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common/release/ZB.MOM.WW.OtOpcUa.Driver.Historian.Sql.Common.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway/release/ZB.MOM.WW.OtOpcUa.Driver.Historian.Gateway.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer/release/ZB.MOM.WW.OtOpcUa.Driver.Historian.SqlServer.dll
ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb/release/ZB.MOM.WW.OtOpcUa.Driver.Historian.QuestDb.dll
ZB.MOM.WW.OtOpcUa.Driver.Modbus -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Modbus/release/ZB.MOM.WW.OtOpcUa.Driver.Modbus.dll
ZB.MOM.WW.OtOpcUa.Driver.Mqtt -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Mqtt/release/ZB.MOM.WW.OtOpcUa.Driver.Mqtt.dll
ZB.MOM.WW.OtOpcUa.Driver.MTConnect -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.MTConnect/release/ZB.MOM.WW.OtOpcUa.Driver.MTConnect.dll
ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient/release/ZB.MOM.WW.OtOpcUa.Driver.OpcUaClient.dll
ZB.MOM.WW.OtOpcUa.Driver.S7 -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.S7/release/ZB.MOM.WW.OtOpcUa.Driver.S7.dll
ZB.MOM.WW.OtOpcUa.Driver.Sql -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.Sql/release/ZB.MOM.WW.OtOpcUa.Driver.Sql.dll
ZB.MOM.WW.OtOpcUa.Driver.TwinCAT -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT/release/ZB.MOM.WW.OtOpcUa.Driver.TwinCAT.dll
ZB.MOM.WW.OtOpcUa.ScriptWorker -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.ScriptWorker/release_linux-arm64/ZB.MOM.WW.OtOpcUa.ScriptWorker.dll
ZB.MOM.WW.OtOpcUa.Host -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Host/release_linux-arm64/OtOpcUa.Host.dll
ZB.MOM.WW.OtOpcUa.Client.Shared -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.Client.Shared/release/ZB.MOM.WW.OtOpcUa.Client.Shared.dll
ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests -> /tmp/opcua2-server-linux-diagnostic-20261110a/build-artifacts/bin/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests/release_linux-arm64/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests.dll
ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests -> /tmp/opcua2-server-linux-diagnostic-20261110a/app/

Some files were not shown because too many files have changed in this diff Show More