Files
lmxopcua/archreview/plans/artifacts/456-resilience-config-live-proof-2026-07-15.md
T
Joseph Doherty 0c005c9a72
v2-ci / build (pull_request) Successful in 4m17s
v2-ci / unit-tests (pull_request) Failing after 10m27s
docs(archreview): live proof authored ResilienceConfig reaches the runtime pipeline (#456)
Captures the docker-dev live verification for follow-up #10 acceptance item 2:
a non-default per-instance ResilienceConfig (Subscribe.retryCount:999) authored on
MAIN rode the deploy artifact into BOTH central-1/central-2 runtimes, which parsed
and clamped it — the authored value appears verbatim in the spawn-time diagnostic.
Confirms the artifact bytes carry ResilienceConfig and the runtime pipeline applies
authored (not tier-default) policy. Item 1 (raw retry/breaker-on-fault log line)
remains, with the connect-then-idempotent-write recipe documented.
2026-07-15 08:49:17 -04:00

3.4 KiB

Follow-up #10 / issue #456 — live proof that authored ResilienceConfig reaches the runtime pipeline

Date: 2026-07-15 · Rig: docker-dev (central-1 + central-2, MAIN cluster, Warm/2-node) built from source.

What this proves

The #456 "sub-gap" worried that per-instance DriverInstance.ResilienceConfig never reaches the runtime resilience pipeline (so it runs tier-defaults only). This is disproven — both by a new regression test and by this live capture.

Setup

Seeded on MAIN (SQL): an Equipment namespace ns-res + an OpcUaClient driver drv-res carrying a non-default override:

"ResilienceConfig": {"capabilityPolicies":{"Subscribe":{"retryCount":999}}}

retryCount:999 is deliberately over the cap (100) so the parser emits an unmistakable clamp diagnostic that echoes the authored value. Deployed headless: POST /api/deployments → Accepted (deploymentId 80b4be3c…).

Evidence

1. The persisted deployment artifact bytes carry it (dbo.Deployment.ArtifactBlob, 4055 bytes): CHARINDEX('ResilienceConfig') > 0 = YES, CHARINDEX('999') > 0 = YES; the drv-res object slice shows …"DriverType":"OpcUaClient"…"DriverConfig":"…"…"Resil…".

2. The runtime parsed + applied it — on BOTH redundancy nodes:

central-1  [WRN] Driver resilience config for instance=drv-res type=OpcUaClient: Subscribe.retryCount 999 exceeds the cap (100); clamped.
central-1  [INF] DriverHost central-1:4053: spawned OpcUaClient driver drv-res (stub=False)
central-2  [WRN] Driver resilience config for instance=drv-res type=OpcUaClient: Subscribe.retryCount 999 exceeds the cap (100); clamped.
central-2  [INF] DriverHost central-2:4053: spawned OpcUaClient driver drv-res (stub=False)

The authored value 999 appears verbatim in the runtime log. If the artifact did not carry ResilienceConfig (the feared sub-gap), spec.ResilienceConfig would be null, the parser would take pure tier-defaults, and no clamp diagnostic would fire. The diagnostic firing = the authored policy rode DB → ConfigComposer → artifact → DriverHostActor → DriverCapabilityInvokerFactory.Create → DriverResilienceOptionsParser. This is arch-review follow-up #10 acceptance item 2 ("re-verify the behavioral gate with a non-default policy"), verified live on both nodes.

Regression guard

ConfigComposerTests.ResilienceConfig_survives_ConfigComposer_to_ParseDriverInstances_round_trip (master 809e7886) proves the same composer→artifact→parse leg deterministically, guarding against a future projection / [JsonIgnore] silently reverting authored policy to tier defaults.

Still open (acceptance item 1)

The raw retry/breaker log line on an actual driver fault was NOT captured. It requires a connect-then-fault-mid-flight trigger: the wrapped capability calls (Subscribe/Discover/Write) only fire after a driver reaches Connected (DriverInstanceActor ResubscribeDesired runs on the Become(Connected) transition), so a driver at a dead endpoint stays in Reconnecting and never exercises the wrapped path. The reliable trigger is an idempotent Write to a Connected-then-killed driver (LDAP-gated Client.CLI write) or an S7 dead-socket reconnect. The retry/breaker behaviour is already proven deterministically (CapabilityInvokerTests retry, the pipeline-builder logging test, DriverCapabilityInvokerFactoryTests override-applies-to-behaviour). This remaining line is operator-confidence only.