Commit Graph

210 Commits

Author SHA1 Message Date
Joseph Doherty f381b471f9 docs(sweep): AbLegacy verified green — fixture-deployment gap, not a code defect (#4)
v2-ci / build (pull_request) Successful in 4m26s
v2-ci / unit-tests (pull_request) Failing after 3h11m47s
The sweep's AbLegacy 4F was a fixture-deployment gap, not a driver/test defect.
The suite needs ab_server in PCCC mode (--plc=SLC500|Micrologix|PLC/5), which
reuses the AbCip image (already on the host) and binds :44818. No PCCC container
was deployed, and the 4F-not-skip means :44818 was answering CIP (a leftover
AbCip container) so the PCCC reads returned Bad — same shared-port contamination
class as the Modbus false alarm.

Deployed the PCCC compose to ~/otopcua-ablegacy and ran each family with
AB_LEGACY_COMPOSE_PROFILE set to match the running container (required — without
it the [Theory] parametrises over all 3 families and 2 fail against a single-
family container): slc500 2/2, micrologix 1/1 (+1 skip), plc5 1/1 (+1 skip).
Skips are family-inapplicable file types. No code change.

Corrected the sweep record + added the AbLegacy bring-up + run recipe.
Integration-sweep follow-up #4.
2026-07-15 05:38:18 -04:00
Joseph Doherty 00f39c849e docs(modbus-tests): document profile-cycling gotcha; sweep #2 was a false alarm
v2-ci / build (pull_request) Successful in 4m13s
v2-ci / unit-tests (pull_request) Failing after 9m41s
The 2026-07 integration sweep flagged the Modbus non-standard profiles as
8F/5F/3F/8F and guessed 'pymodbus 4.x drift'. Re-investigation shows that was
wrong on both counts:

- The image runs the PINNED pymodbus 3.13.0 (verified via import pymodbus;
  __version__). The '...removed in v4' log is 3.13.0's forward-deprecation
  warning, misread as running 4.x.
- The failures were a fixture-cycling artifact: each profile is a separate
  profile-gated compose service sharing :5020, and a plain 'docker compose down'
  (no --profile) does NOT stop the running profile container. It kept holding
  :5020; the next '--profile up' container silently failed to bind (compose
  still says 'Started'), so every later profile run hit the STALE sim. Proven by
  a raw Modbus probe: the 'mitsubishi' sim served DL205's 0xCAFE at HR0.

After force-removing all modbus containers and bringing up each profile cleanly
(verifying it actually published :5020), all four pass: dl205 16/16,
mitsubishi 13/13, s7_1500 10/10, exception_injection 17/17. No OtOpcUa or test
code change needed.

Added a profile-cycling gotcha + reliable-cycle recipe to Docker/README.md and
corrected the sweep record. Integration-sweep follow-up #2.
2026-07-15 05:12:52 -04:00
Joseph Doherty de9d9697fd fix(opcuaserver-tests): supply client cert-store paths + adapt to SDK read-throws
v2-ci / build (pull_request) Successful in 7m23s
v2-ci / unit-tests (pull_request) Failing after 15m33s
OpcUaServer.IntegrationTests was 4F. Two distinct, previously-masked issues:

1. Cert-store gap: the in-test client SecurityConfiguration used a bare
   new SecurityConfiguration()/CertificateIdentifier(), so ValidateAsync threw
   'TrustedIssuerCertificates StorePath must be specified' before any connect.
   Added TestClientSecurity helper building Directory own/issuer/trusted/rejected
   stores under a throwaway temp PKI dir (mirrors DefaultApplicationConfigurationFactory);
   wired into DualEndpointTests + SubscriptionSurvivalTests.

2. Fixing #1 unmasked an SDK-version drift: the 1.5.378 node-cache read path
   throws ServiceResultException(BadNodeIdUnknown) for a removed node instead of
   returning a bad DataValue. The two subscription-survival assertions now expect
   the throw via Should.ThrowAsync. Behavior under test (removed node -> unknown)
   is unchanged; only the delivery mechanism differs.

Suite 4F -> 4/4 green. Integration-sweep follow-up #5.
2026-07-15 03:34:14 -04:00
Joseph Doherty 2ba867b0f8 docs(archreview): mark integration-sweep follow-up #1 (AbCip static-init) done
v2-ci / build (pull_request) Successful in 4m19s
v2-ci / unit-tests (pull_request) Failing after 17m55s
2026-07-15 03:28:24 -04:00
Joseph Doherty 1ee73d76d6 docs(archreview): record integration-suite sweep results + follow-ups (2026-07-14)
v2-ci / build (pull_request) Successful in 4m46s
v2-ci / unit-tests (pull_request) Failing after 10m56s
Ran the deferred *.IntegrationTests sweep (Mac + docker-host fixtures,
serial). No OtOpcUa regression: OpcUaClient(+Browser)/S7/Modbus-standard
green, Host 105/117, TwinCAT clean-skip. The rest fail on pre-existing
test/fixture bit-rot of distinct kinds (AbCip static-init bug, Modbus
pymodbus-4.x sim drift, FOCAS 127.0.0.1-mock topology, AbLegacy no
fixture, OpcUaServer cert-store config, Host openldap:2.6 image gone).

New INTEGRATION-SWEEP-STATUS.md has the full table, per-suite evidence,
7 follow-ups, and re-run fixture recipes; STATUS.md links it.
2026-07-15 01:25:55 -04:00
Joseph Doherty eccb15bdab docs(archreview): R2-04 T13/T15 live-passed 2026-07-14
v2-ci / build (pull_request) Successful in 4m8s
v2-ci / unit-tests (pull_request) Failing after 11m0s
Both R2-04 verification gates for the S4 primary-gate default-deny run:
- T15 (docker-dev 2-node rig, rebuilt from master 365a90e6 + Modbus sim):
  ServiceLevel 250/240; boot-window write rejected 'not primary (role
  unknown)' (meter reason=role-unknown,site=write); steady-state
  secondary rejected 'not primary' + node reverted (read-back 1234 not
  9999, meter reason=secondary); primary write reaches device; clean
  apply (no apply.failed). The behavior-affecting S4 slice is trusted.
- T13 (in-process PrimaryGateFailoverTests): 1/1, ran without SQL; the
  real DPS-delivered snapshot drives the gate; negative control covered.

STATUS.md + R2-04 tasks.json updated.
2026-07-14 15:13:43 -04:00
Joseph Doherty 9f62310b49 fix(historian): map Boolean historization to Int2, not degenerate Int1 (#441)
v2-ci / build (pull_request) Successful in 3m24s
v2-ci / unit-tests (pull_request) Failing after 8m19s
The historian's Int1 analog-tag creation path is server-degenerate:
EnsureTags(Int1) stores an unusable stub (live-probed on the deployed
2023 R2 historian; root-caused + documented gateway-side in
HistorianGateway #11 / PR #16). HistorianTypeMapper mapped
DriverDataType.Boolean -> HistorianDataType.Int1, so Boolean historized
tags failed auto-provisioning.

Map Boolean -> Int2 instead (store 0/1). Int2 is a proven-creatable
analog type, and the value-write path already sends every value as a
double on WriteLiveValues regardless of tag type, so Boolean 0.0/1.0
round-trips cleanly. Both Float and Int2 are supported, so a
pre-existing Float Boolean tag retypes cleanly on its next deploy.

- HistorianTypeMapper: Boolean => Int2 (+ remarks)
- Unit pins: HistorianTypeMapperTests, GatewayTagProvisionerTests
  (Boolean_definition_carries_explicit_Int2_presence)
- Live gate: EnsureTags_boolean_sandbox_provisions_as_Int2 (was _Int1);
  retype probe reframed Float->Int2 (drops the dead Int1 leg)
- Docs: docs/Historian.md 'Boolean historization maps to Int2', CLAUDE.md,
  archreview STATUS.md (R2-06 live gate -> 6/6)

Resolves #441.
2026-07-14 11:57:27 -04:00
Joseph Doherty 9ba162d0f8 docs(archreview): cross-reference historiangw#11 for the Int1 EnsureTags gap
v2-ci / build (push) Successful in 3m49s
v2-ci / unit-tests (push) Failing after 8m10s
2026-07-14 05:35:15 -04:00
Joseph Doherty 416789c6ab docs(archreview): R2-06 live gate 5/6 + U-7 retype policy answered
v2-ci / build (push) Successful in 4m21s
v2-ci / unit-tests (push) Failing after 8m44s
- StorageRateMs bug found+fixed (PR #439); live suite 3/6 -> 5/6
- U-7: EnsureTags is a real upsert; supported-type retype ACCEPTED (Float->Double);
  Int1 not creatable on this histsdk (ProtocolEvidenceMissingException, Int1-only)
- record the observed retype policy in docs/Historian.md (fills the placeholder)
2026-07-13 19:31:47 -04:00
Joseph Doherty 7154ec8f04 docs(archreview): record R2-06 live gate attempt (3/6 green; RuntimeDb Windows-auth + gateway EnsureTags blockers)
v2-ci / build (push) Successful in 3m18s
v2-ci / unit-tests (push) Failing after 8m37s
2026-07-13 18:58:19 -04:00
Joseph Doherty 40d130e7c2 docs(archreview): record post-round-2 namespace-flatten fix (PR #438)
v2-ci / build (push) Successful in 4m24s
v2-ci / unit-tests (push) Failing after 9m9s
2026-07-13 18:29:53 -04:00
Joseph Doherty e4c7c8ab6d docs(archreview): conclude docker-dev live pass — R2-10 pipeline live, R2-03 rig-blocked
v2-ci / build (push) Successful in 3m19s
v2-ci / unit-tests (push) Failing after 9m1s
R2-10: driver failures propagate through the full Polly pipeline (CircuitBreaker->
Retry->Timeout->CapabilityInvoker.cs:84) live — the #10 dispatch-gap fix + tracker
source confirmed in prod; breaker-OPEN not forced (backoff-throttled, per FOLLOWUP-10).
R2-03: rig has no driver data (all nodes Bad_WaitingForInitialData), so VT Good->Bad
can't be staged; unit-verified. 5 gates live-confirmed total; remaining items need
external infra (integration fixtures, VPN gateway, live LDAP, S7 blackhole).
2026-07-13 18:17:41 -04:00
Joseph Doherty b1268544e0 docs(archreview): record docker-dev live-/run pass — 4 R2 gates live-confirmed
v2-ci / build (push) Successful in 3m20s
v2-ci / unit-tests (push) Failing after 9m0s
R2-02 (S-6 range warning + S-8 disabled cells), R2-11 (Writable checkbox),
R2-07 (PureAdd + PureRemove, rebuild=False — F10b MUST), R2-04 (younger-crash
keep-oldest survives sole primary; oldest-crash reproduced the documented SBR
asymmetry, not an R2 regression). R2-05 partial (deny unobservable under
DisableLogin). R2-10/R2-03 unit-verified, live-trigger constrained.
2026-07-13 17:53:32 -04:00
Joseph Doherty 6aeb53a993 docs(archreview): round-2 COMPLETE capstone — all 12 plans merged @31c98200
v2-ci / build (push) Successful in 3m49s
v2-ci / unit-tests (push) Failing after 8m22s
All 12 R2 plans executed + merged (PRs #426-#437) in 3 waves. Consolidated unit
sweep green on merged master; 3 failures confirmed pre-existing/environmental (not
R2). Records the PR/wave map, unit-sweep tallies, and the deferred integration /
docker-dev / 2-node-rig / VPN heavy-pass checklist.
2026-07-13 12:55:15 -04:00
Joseph Doherty 31c982008b Merge R2-09 Driver fleet batch (arch-review round 2) [PR #437]
v2-ci / build (push) Successful in 3m51s
v2-ci / unit-tests (push) Failing after 9m22s
Findings 05/STAB-3/4/5/8/12/16/17 + CONV-4 + onError (6 sub-batches, 29 tasks):
Modbus desync teardown, AbCip runtime lock, FOCAS concurrent caches, new
ConnectionBackoff + PollGroupEngine v2 (S7 poll fork deleted onto it, reconciled
with R2-01), fleet connect throttles, ResolveHost via resolver, TwinCAT replay
hardening. 29/29 tasks. S7 254/254 verified post-merge; build clean.
2026-07-13 12:48:12 -04:00
Joseph Doherty 6ee74d26fc docs(r2-09): record execution deviations; clear CS8604 nullable warning in the 5 PollErrorHealthTests
v2-ci / build (pull_request) Successful in 3m32s
v2-ci / unit-tests (pull_request) Failing after 9m27s
2026-07-13 12:45:50 -04:00
Joseph Doherty 502a327f25 fix(twincat): probe recycle honors cancellation — no uncancellable gate wait (05/STAB-12 compounded part); B6 complete (TwinCAT suite 189 green) 2026-07-13 12:43:06 -04:00
Joseph Doherty 082ee99b6b fix(twincat): retract the fresh ADS notification when unsubscribe raced the replay (05/STAB-17) 2026-07-13 12:39:39 -04:00
Joseph Doherty de29759643 fix(twincat): retry failed replay intents on the next successful probe tick (05/STAB-16) 2026-07-13 12:37:20 -04:00
Joseph Doherty a06515ae91 fix(twincat): replay failure marks the registration dead, publishes Bad quality, degrades health (05/STAB-16) 2026-07-13 12:34:43 -04:00
Joseph Doherty 4f16620948 test(twincat): failing repro for STAB-16 silent replay failure 2026-07-13 12:33:35 -04:00
Joseph Doherty e27416956e fix(r2-09): B5.4 five driver suites green (Modbus 312, AbCip 336, AbLegacy 209, TwinCAT 185, FOCAS 265); B5 complete 2026-07-13 12:29:52 -04:00
Joseph Doherty e69d3b3b0f fix(modbus): equipment tags carry unitId; ResolveHost keys per-unit via the resolver (CONV-4) 2026-07-13 12:29:13 -04:00
Joseph Doherty 04fa2f5cb2 Merge R2-07 Surgical pure-adds (arch-review round 2) [PR #436]
v2-ci / build (push) Successful in 3m19s
v2-ci / unit-tests (push) Failing after 8m13s
Finding 03/P1: surgical in-place address-space adds/removals skip full rebuilds
(AddressSpaceChangeClassifier default-closed to Rebuild). 3 new
ISurgicalAddressSpaceSink remove members, guard-first + forwarded through
DeferredAddressSpaceSink (F10b inertness net green). T5/T6/T12/T14 over-the-wire +
docker-dev gates deferred. Auto-merged OtOpcUaNodeManager.cs with R2-08; verified
OpcUaServer.Tests 341/341 + forwarding guard 3/3. Build clean.
2026-07-13 12:27:59 -04:00
Joseph Doherty 9262dd25b7 fix(drivers): ResolveHost resolves equipment-tag refs via EquipmentTagRefResolver — per-host breaker isolation (CONV-4) 2026-07-13 12:26:42 -04:00
Joseph Doherty ded0595ca7 test+docs: mixed-deploy survival, STATUS/P1 close-out (R2-07 T14)
v2-ci / build (pull_request) Successful in 4m3s
v2-ci / unit-tests (pull_request) Failing after 9m47s
2026-07-13 12:24:50 -04:00
Joseph Doherty 8a7701db3f test(drivers): failing repro for CONV-4 equipment-tag ResolveHost mis-keying 2026-07-13 12:23:43 -04:00
Joseph Doherty e2b47638ec feat(opcua): surgical mixed add+remove deploys (R2-07 T13) 2026-07-13 12:22:45 -04:00
Joseph Doherty 354d74d370 docs: ServerHistorian HistoryRead knobs + Security:Ldap resilience keys; R2-08 status (03/S2, 03/S3)
v2-ci / build (pull_request) Successful in 3m33s
v2-ci / unit-tests (pull_request) Failing after 9m24s
2026-07-13 12:21:33 -04:00
Joseph Doherty dd01565d9a docs(s7): point R2-01 at the shipped ConnectionBackoff primitive for the S7 connect throttle (05/STAB-8 seam); B4 complete 2026-07-13 12:20:58 -04:00
Joseph Doherty 86742ad8cb fix(abcip): throttle evict-recreate Forward-Open attempts per device (05/STAB-8) 2026-07-13 12:20:10 -04:00
Joseph Doherty f4ea834fac test(opcua): subscription-survival on pure-remove + live-verify note (R2-07 T12) 2026-07-13 12:19:36 -04:00
Joseph Doherty 3cebfae417 feat(opcuaserver): process-wide HistoryRead batch limiter — flood degrades to BadTooManyOperations, not pool exhaustion (03/S3) 2026-07-13 12:18:35 -04:00
Joseph Doherty 502d7650d0 feat(opcua): surgical pure-remove deploys — scoped teardown, no full rebuild (R2-07 T11) 2026-07-13 12:18:08 -04:00
Joseph Doherty e54af9b948 fix(focas): per-device connect-attempt backoff across the three loops (05/STAB-8) 2026-07-13 12:16:31 -04:00
Joseph Doherty 888cf86655 feat(opcuaserver): per-request HistoryRead deadline — hung backends surface BadTimeout (03/S3) 2026-07-13 12:13:38 -04:00
Joseph Doherty 962afed241 fix(twincat): per-device connect-attempt backoff, probe-driven recovery (05/STAB-8) 2026-07-13 12:13:23 -04:00
Joseph Doherty 4504ed930c feat(opcua): surgical RemoveEquipmentSubtree with notifier demotion (R2-07 T10) 2026-07-13 12:12:09 -04:00
Joseph Doherty 9653493905 feat(opcua): surgical RemoveAlarmConditionNode (R2-07 T9) 2026-07-13 12:09:55 -04:00
Joseph Doherty 8c365da754 feat(opcuaserver): bounded per-node parallel HistoryRead within a batch (03/S3) 2026-07-13 12:09:53 -04:00
Joseph Doherty defb7a8c3d fix(r2-09): B3.7 engine + 5 driver suites green (S7 254, Modbus 308, AbCip 331, AbLegacy 207, TwinCAT 181, FOCAS 260); B3 complete 2026-07-13 12:09:18 -04:00
Joseph Doherty 14003ab9b8 feat(opcua): surgical RemoveVariableNode with NodeDeleted model-change (R2-07 T8) 2026-07-13 12:09:14 -04:00
Joseph Doherty 85ef74ea86 refactor(s7): retire the bespoke poll fork onto PollGroupEngine v2 (CONV-1; fixes PERF-3 + STAB-6-S7; deletes the fork's bare-OCE poll-death — cross-ref plan R2-01) 2026-07-13 12:07:39 -04:00
Joseph Doherty 438004e371 feat(commons): add surgical remove members to ISurgicalAddressSpaceSink + deferred forwarding (guard-verified) (R2-07 T7) 2026-07-13 12:07:01 -04:00
Joseph Doherty cef7d9b281 refactor(opcuaserver): async-ify ServeRawPaged + HistoryReadEvents internals (03/S3) 2026-07-13 12:07:00 -04:00
Joseph Doherty 0d879363f8 test(s7): failing guards for the poll-fork retirement (PERF-3, STAB-6) 2026-07-13 12:05:08 -04:00
Joseph Doherty 1e83fe7085 refactor(opcuaserver): async-ify ServeNode + Processed/AtTime HistoryRead internals, thread cancellation (03/S3) 2026-07-13 12:04:54 -04:00
Joseph Doherty 304442dba4 feat(runtime): ServerHistorian HistoryRead parallelism/limiter/deadline knobs + node-manager wiring (03/S3) 2026-07-13 12:03:27 -04:00
Joseph Doherty 4f1853b21f docs(archreview): record R2-07 Phase 1 (offline-verified; live gate deferred) in STATUS.md 2026-07-13 12:02:16 -04:00
Joseph Doherty d5c6609cdf test(opcuaserver): red repro — HistoryRead serves a batch strictly sequentially (03/S3) 2026-07-13 12:01:47 -04:00