docs: record completed Linux OPC UA lifecycle diagnostic
v2-ci / unit-tests (pull_request) Waiting to run

This commit is contained in:
Joseph Doherty
2026-11-10 20:28:11 -05:00
parent 1e4b017f6e
commit da4e27003e
5 changed files with 858 additions and 6 deletions
+17 -6
View File
@@ -603,10 +603,21 @@ were released, with no owned files/descriptors and unchanged keychain fingerprin
Deletion occurred during copied-certificate untracking with item references still
live. This establishes that a managed caller is unnecessary for reproduction; it
does not distinguish native bridge ownership from Apple Security retention or
authorize a production workaround. A separate matched deletion-order control
remains under review. The failed first attempt is retained independently.
authorize a production workaround. The separate
[matched deletion-order control](../../scripts/validation/opcua-lifecycle-memory/native-retention/PRIVATE_UPSTREAM_HANDOFF.md)
observed the same 1→201 inventory with both ordinary and deferred deletion.
The failed first attempt is retained independently. The upstream handoff remains
private; no application correction has been established.
#799 and G4 remain open. The [proposed Linux late-slope diagnostic](../../scripts/validation/opcua-lifecycle-memory/LATE_SLOPE.md)
has implementation design approval only. It retains the cold baseline and first
resource rejection and cannot emit acceptance. No new long run or release is
approved; Windows/live interoperability gates remain separate.
### Completed Linux late-slope diagnostic
The [one-shot result](evidence/2026-11-10-opcua2/late-slope-linux.md) completed
7,201.014 seconds, 1,937 cycles and 484 restarts on Linux ARM64 .NET 10.0.14,
source `b18f9723`. All three tests passed, shutdown and container removal were
verified, and no resource cap tripped. Peak quiescent RSS was 338.99 MiB,
4.20 MiB below the unchanged cycle-3 cap; the three late-window medians were
316.35, 317.03 and 317.20 MiB, and the late RSS fit was +0.194 MiB/hour.
No quiescent PKI descriptor was observed. This tracked diagnostic has
`acceptance=false`; earlier cold failures remain, and there is no warmed
baseline, matched representative-load acceptance, or macOS resolution.
#799 and G4 remain open. Windows and live interoperability gates remain separate.
@@ -112,6 +112,10 @@ criterion, but retained the cold RSS rejection and exit1. The original-SDK adapt
records partial wire coverage and unsupported ownership/process-memory parity;
it supplies no approved performance denominator. See [scoped saturation result](evidence/2026-11-10-opcua2/saturation-candidate.md)
and [original adapter limitations](../../scripts/validation/opcua-lifecycle-memory/baseline-canonical/README.md).
A later [Linux diagnostic](evidence/2026-11-10-opcua2/late-slope-linux.md)
completed 7,201.014 seconds and 484 restarts without a cold-cap breach, with a
4.20 MiB minimum margin at observed quiescent samples. This one tracked run
does not supersede the earlier failures or satisfy resource acceptance.
Astra's final source/security review is closed; release remains on HOLD.
@@ -0,0 +1,785 @@
{
"scope": "One fixed 7200-second Linux late-slope diagnostic; not server resource or G4 acceptance.",
"rawDirectory": "/private/tmp/opcua2-late-slope-linux-run1",
"rawRunReceiptSha256": "695434af4b22296c7420949d8965a2cbd513b7a67da8ebacc54f3337085f0f7c",
"rawAnalysisSha256": "38f8d8c7f620cc9fc54f27059c9ae0529c7aa1f53b8a665305d4deb7375f9ad2",
"bundle": {
"rawDirectory": "/private/tmp/opcua2-late-slope-reviewed-b18f9723",
"image": "sha256:b04611ee9e1b7d36797012ed921962c57189cb4dbb3dff12afb8e158110f293b",
"coreClrSha256": "5eaed8176e960fa1b00a244d25a5d64116d8cd19909e9bad1f65f0c1415117c7",
"runtimeVersion": "10.0.14",
"rid": "linux-arm64",
"sdkVersion": "2.0.1",
"historianGatewayClientAndContractsVersion": "1.0.0",
"files": 939,
"receiptSha256": "f446a7368aee7e04cdb147b62d97d2344a4bef5398ef4ee4226d7f414bee21ae"
},
"run": {
"runId": "34f42362313643eeac2a2a9274d6fa65",
"wallSeconds": 7204.7963791670045,
"containerRemoved": true,
"diagnosticCompleted": true,
"launcherExitStatus": 0
},
"analysis": {
"protocol": "sdk2-late-slope-v1",
"acceptance": false,
"bundleReceiptSha256": "f446a7368aee7e04cdb147b62d97d2344a4bef5398ef4ee4226d7f414bee21ae",
"sourceRevision": "b18f97236a033b54945b3b9a1d5e306e11e278a7",
"evidenceSha256": {
"launch.json": "5513fa5a69f119b4a892d302244157674e9499c2dcadc27158cd48e4ea1e8530",
"container.log": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"container-exit-status.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"controller-runtime.txt": "a642f96420f847eaaaccec852e41cc349d430a7d823242e08cb0f3498331056e",
"descriptor-controls.log": "68f24ee87f563f09e60ca6cad98fab745f17d7980407c748615fdf4004133cc4",
"test.log": "5d402059bf09abca2815a281d46ead36e8371ca8a9bb19ffad0cbd1ee8201667",
"target-runtime.txt": "a3278769f0c0cb364ffc270c885b5279914381907b6a3f95736c797f519cb998",
"resources.jsonl": "2ef6b27e7849400f794ab47119c601a84dfc4f35ded884e7f24b537bfeb37324",
"test-exit-status.txt": "9a271f2a916b0b6ee6cecb2426f0b3206ef074578be55d9bc94f6f3fe3ab86aa",
"results/descriptor-controls.trx": "890cf43b22fe9450bb3ac0d189d4aaffd2e883b08ba1f359db7e005aba6770cb",
"results/late-slope.trx": "fe68c144dfd0484b1e84de4b19d20f893bb7b37140b364465844dca2b0504258"
},
"diagnosticOutcome": {
"kind": "late-slope-result",
"mode": "late-slope",
"cycles": 1937,
"restarts": 484,
"cycleSeconds": 7201.0136877,
"shutdownSeconds": 0.0172284,
"durationCompleted": true,
"shutdownVerified": true,
"coldBudgetRejected": false,
"fatalFailure": false,
"failureTypes": [],
"acceptance": false
},
"firstColdRejection": null,
"descriptorTests": {
"executed": 2,
"passed": 2,
"failed": 0,
"skipped": 0
},
"experimentTests": {
"executed": 1,
"passed": 1,
"failed": 0,
"skipped": 0
},
"testExitStatus": 0,
"containerExitStatus": 0,
"allQuiescent": {
"sampleCount": 1937,
"firstSeconds": 2.7228004,
"lastSeconds": 7201.0129856,
"spanSeconds": 7198.2901852,
"maximumGapSeconds": 7.651318599999968,
"Sessions": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"Subscriptions": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"Items": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"BrowsePoints": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"HistoryPoints": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"LiveDataItems": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"LiveEventItems": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"MonitoredNodes": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"PkiDescriptors": {
"first": 0,
"last": 0,
"min": 0,
"max": 0,
"median": 0
},
"Variables": {
"first": 19,
"last": 19,
"min": 19,
"max": 19,
"median": 19
},
"Folders": {
"first": 4,
"last": 4,
"min": 4,
"max": 4,
"median": 4
},
"Conditions": {
"first": 1,
"last": 1,
"min": 1,
"max": 1,
"median": 1
},
"CachedCertificateStores": {
"first": 2,
"last": 2,
"min": 2,
"max": 2,
"median": 2
},
"Descriptors": {
"first": 189,
"last": 193,
"min": 189,
"max": 195,
"median": 193
},
"ManagedBytes": {
"first": 19589176,
"last": 19815600,
"min": 19500536,
"max": 20410640,
"median": 19959568
},
"RssBytes": {
"first": 221298688,
"last": 332910592,
"min": 213692416,
"max": 355459072,
"median": 331042816
},
"AllocatedBytes": {
"first": 62675872,
"last": 41675654344,
"min": 62675872,
"max": 41675654344,
"median": 20890037224
},
"Gen0": {
"first": 3,
"last": 4843,
"min": 3,
"max": 4843,
"median": 2423
},
"Gen1": {
"first": 2,
"last": 4358,
"min": 2,
"max": 4358,
"median": 2180
},
"Gen2": {
"first": 2,
"last": 3874,
"min": 2,
"max": 3874,
"median": 1938
},
"GcCommittedBytes": {
"first": 47538176,
"last": 46473216,
"min": 39727104,
"max": 51621888,
"median": 46432256
},
"GcHeapBytes": {
"first": 20419784,
"last": 20189448,
"min": 19900312,
"max": 22382248,
"median": 21138072
},
"GcFragmentedBytes": {
"first": 838832,
"last": 373848,
"min": 373824,
"max": 2205736,
"median": 1107120
},
"PinnedObjects": {
"first": 1,
"last": 1,
"min": 1,
"max": 1,
"median": 1
},
"PendingFinalizers": {
"first": 19,
"last": 25,
"min": 16,
"max": 31,
"median": 17
},
"JitMethods": {
"first": 29098,
"last": 84208,
"min": 29098,
"max": 84208,
"median": 81493
},
"JitIlBytes": {
"first": 4112731,
"last": 12267831,
"min": 4112731,
"max": 12267831,
"median": 12220632
},
"ActiveTimers": {
"first": 15,
"last": 16,
"min": 13,
"max": 19,
"median": 19
},
"Threads": {
"first": 26,
"last": 20,
"min": 19,
"max": 26,
"median": 20
}
},
"finalQuiescentSample": {
"Cycle": 1937,
"Seconds": 7201.0129856,
"Sessions": 0,
"Subscriptions": 0,
"Items": 0,
"BrowsePoints": 0,
"HistoryPoints": 0,
"LiveDataItems": 0,
"LiveEventItems": 0,
"MonitoredNodes": 0,
"Variables": 19,
"Folders": 4,
"Conditions": 1,
"CachedCertificateStores": 2,
"Descriptors": 193,
"PkiDescriptors": 0,
"ManagedBytes": 19815600,
"RssBytes": 332910592,
"AllocatedBytes": 41675654344,
"Gen0": 4843,
"Gen1": 4358,
"Gen2": 3874,
"GcCommittedBytes": 46473216,
"GcHeapBytes": 20189448,
"GcFragmentedBytes": 373848,
"PinnedObjects": 1,
"PendingFinalizers": 25,
"JitMethods": 84208,
"JitIlBytes": 12267831,
"ActiveTimers": 16,
"Threads": 20
},
"windows": [
{
"windowSeconds": [
1800,
2400
],
"sampleCount": 162,
"firstSeconds": 1801.8241442,
"lastSeconds": 2399.1054766,
"spanSeconds": 597.2813324000001,
"maximumGapSeconds": 7.632806000000073,
"Descriptors": {
"first": 193,
"last": 193,
"min": 193,
"max": 194,
"median": 193.0
},
"ManagedBytes": {
"first": 19792656,
"last": 19958240,
"min": 19603712,
"max": 20252008,
"median": 19941740.0
},
"RssBytes": {
"first": 335007744,
"last": 332382208,
"min": 325906432,
"max": 336637952,
"median": 331720704.0
},
"AllocatedBytes": {
"first": 10498090392,
"last": 13943797944,
"min": 10498090392,
"max": 13943797944,
"median": 12220405168.0
},
"Gen0": {
"first": 1213,
"last": 1615,
"min": 1213,
"max": 1615,
"median": 1414.0
},
"Gen1": {
"first": 1091,
"last": 1453,
"min": 1091,
"max": 1453,
"median": 1272.0
},
"Gen2": {
"first": 970,
"last": 1292,
"min": 970,
"max": 1292,
"median": 1131.0
},
"GcCommittedBytes": {
"first": 47386624,
"last": 47796224,
"min": 40095744,
"max": 50475008,
"median": 46211072.0
},
"GcHeapBytes": {
"first": 21300784,
"last": 21801488,
"min": 19985248,
"max": 22201672,
"median": 21115508.0
},
"GcFragmentedBytes": {
"first": 1508128,
"last": 1843248,
"min": 373824,
"max": 2166744,
"median": 1508116.0
},
"PinnedObjects": {
"first": 1,
"last": 1,
"min": 1,
"max": 1,
"median": 1.0
},
"PendingFinalizers": {
"first": 26,
"last": 17,
"min": 16,
"max": 31,
"median": 17.0
},
"JitMethods": {
"first": 80102,
"last": 80584,
"min": 80102,
"max": 80584,
"median": 80354.0
},
"JitIlBytes": {
"first": 12195039,
"last": 12204702,
"min": 12195039,
"max": 12204702,
"median": 12200236.5
},
"ActiveTimers": {
"first": 16,
"last": 19,
"min": 14,
"max": 19,
"median": 19.0
},
"Threads": {
"first": 22,
"last": 20,
"min": 19,
"max": 23,
"median": 20.0
}
},
{
"windowSeconds": [
3600,
4200
],
"sampleCount": 162,
"firstSeconds": 3601.0122763,
"lastSeconds": 4198.5352774,
"spanSeconds": 597.5230011000003,
"maximumGapSeconds": 7.6141325000003235,
"Descriptors": {
"first": 193,
"last": 193,
"min": 193,
"max": 194,
"median": 193.0
},
"ManagedBytes": {
"first": 19741928,
"last": 19957808,
"min": 19674832,
"max": 20386632,
"median": 20025312.0
},
"RssBytes": {
"first": 332455936,
"last": 335466496,
"min": 324829184,
"max": 337289216,
"median": 332433408.0
},
"AllocatedBytes": {
"first": 20890037224,
"last": 24335562096,
"min": 20890037224,
"max": 24335562096,
"median": 22612138936.0
},
"Gen0": {
"first": 2423,
"last": 2825,
"min": 2423,
"max": 2825,
"median": 2624.0
},
"Gen1": {
"first": 2180,
"last": 2542,
"min": 2180,
"max": 2542,
"median": 2361.0
},
"Gen2": {
"first": 1938,
"last": 2260,
"min": 1938,
"max": 2260,
"median": 2099.0
},
"GcCommittedBytes": {
"first": 46424064,
"last": 50216960,
"min": 39788544,
"max": 51249152,
"median": 46196736.0
},
"GcHeapBytes": {
"first": 20115776,
"last": 20744344,
"min": 20049200,
"max": 22295072,
"median": 21137924.0
},
"GcFragmentedBytes": {
"first": 373848,
"last": 786536,
"min": 373824,
"max": 2179024,
"median": 983980.0
},
"PinnedObjects": {
"first": 1,
"last": 1,
"min": 1,
"max": 1,
"median": 1.0
},
"PendingFinalizers": {
"first": 26,
"last": 17,
"min": 16,
"max": 26,
"median": 17.0
},
"JitMethods": {
"first": 81493,
"last": 81955,
"min": 81493,
"max": 81955,
"median": 81732.0
},
"JitIlBytes": {
"first": 12220632,
"last": 12229078,
"min": 12220632,
"max": 12229078,
"median": 12225507.5
},
"ActiveTimers": {
"first": 16,
"last": 17,
"min": 14,
"max": 19,
"median": 19.0
},
"Threads": {
"first": 20,
"last": 21,
"min": 19,
"max": 22,
"median": 20.0
}
},
{
"windowSeconds": [
6600,
7200
],
"sampleCount": 160,
"firstSeconds": 6606.5860975,
"lastSeconds": 7193.4335924,
"spanSeconds": 586.8474949000001,
"maximumGapSeconds": 7.601607499999773,
"Descriptors": {
"first": 193,
"last": 193,
"min": 193,
"max": 194,
"median": 193.0
},
"ManagedBytes": {
"first": 19815664,
"last": 20124168,
"min": 19676936,
"max": 20387248,
"median": 19974360.0
},
"RssBytes": {
"first": 329056256,
"last": 333631488,
"min": 328650752,
"max": 335728640,
"median": 332609536.0
},
"AllocatedBytes": {
"first": 38238711064,
"last": 41621645280,
"min": 38238711064,
"max": 41621645280,
"median": 39928799852.0
},
"Gen0": {
"first": 4443,
"last": 4839,
"min": 4443,
"max": 4839,
"median": 4641.0
},
"Gen1": {
"first": 3998,
"last": 4355,
"min": 3998,
"max": 4355,
"median": 4176.5
},
"Gen2": {
"first": 3554,
"last": 3872,
"min": 3554,
"max": 3872,
"median": 3713.0
},
"GcCommittedBytes": {
"first": 43245568,
"last": 47431680,
"min": 42844160,
"max": 48513024,
"median": 46374912.0
},
"GcHeapBytes": {
"first": 20189512,
"last": 22144344,
"min": 20114032,
"max": 22289696,
"median": 21174404.0
},
"GcFragmentedBytes": {
"first": 373848,
"last": 2020176,
"min": 373824,
"max": 2097352,
"median": 1307612.0
},
"PinnedObjects": {
"first": 1,
"last": 1,
"min": 1,
"max": 1,
"median": 1.0
},
"PendingFinalizers": {
"first": 26,
"last": 17,
"min": 16,
"max": 30,
"median": 17.0
},
"JitMethods": {
"first": 83748,
"last": 84203,
"min": 83748,
"max": 84203,
"median": 83973.5
},
"JitIlBytes": {
"first": 12258209,
"last": 12267741,
"min": 12258209,
"max": 12267741,
"median": 12263300.0
},
"ActiveTimers": {
"first": 16,
"last": 17,
"min": 14,
"max": 19,
"median": 19.0
},
"Threads": {
"first": 20,
"last": 20,
"min": 19,
"max": 24,
"median": 20.0
}
}
],
"leastSquares": {
"sampleCount": 1452,
"firstSeconds": 1801.8241442,
"lastSeconds": 7193.4335924,
"spanSeconds": 5391.6094482,
"maximumGapSeconds": 7.64098279999962,
"rangeSeconds": [
1800,
7200
],
"units": "bytes/hour",
"rss": 203355.13509451656,
"retainedManaged": 52381.09375374565
},
"workCompletedBy1800Seconds": {
"cycles": 484,
"restarts": 121,
"earlierSaturationWorkloadReached": true
}
},
"coldBudget": {
"baseline": {
"Cycle": 3,
"Seconds": 7.6044949,
"Sessions": 0,
"Subscriptions": 0,
"Items": 0,
"BrowsePoints": 0,
"HistoryPoints": 0,
"LiveDataItems": 0,
"LiveEventItems": 0,
"MonitoredNodes": 0,
"Variables": 19,
"Folders": 4,
"Conditions": 1,
"CachedCertificateStores": 2,
"Descriptors": 191,
"PkiDescriptors": 0,
"ManagedBytes": 19923288,
"RssBytes": 225640448,
"AllocatedBytes": 87148184,
"Gen0": 7,
"Gen1": 6,
"Gen2": 6,
"GcCommittedBytes": 42201088,
"GcHeapBytes": 20679920,
"GcFragmentedBytes": 756632,
"PinnedObjects": 1,
"PendingFinalizers": 16,
"JitMethods": 35715,
"JitIlBytes": 4628455,
"ActiveTimers": 17,
"Threads": 26
},
"limits": {
"retainedManagedGrowthBytes": 67108864,
"rssGrowthBytes": 134217728,
"fdGrowth": 32
},
"peakQuiescentRss": {
"Cycle": 251,
"Seconds": 929.8172991,
"Sessions": 0,
"Subscriptions": 0,
"Items": 0,
"BrowsePoints": 0,
"HistoryPoints": 0,
"LiveDataItems": 0,
"LiveEventItems": 0,
"MonitoredNodes": 0,
"Variables": 19,
"Folders": 4,
"Conditions": 1,
"CachedCertificateStores": 2,
"Descriptors": 194,
"PkiDescriptors": 0,
"ManagedBytes": 19845440,
"RssBytes": 355459072,
"AllocatedBytes": 5450774872,
"Gen0": 627,
"Gen1": 564,
"Gen2": 502,
"GcCommittedBytes": 46583808,
"GcHeapBytes": 20637424,
"GcFragmentedBytes": 800208,
"PinnedObjects": 1,
"PendingFinalizers": 16,
"JitMethods": 79366,
"JitIlBytes": 12178915,
"ActiveTimers": 17,
"Threads": 22
}
},
"runtimeObservation": {
"targetPid": 209,
"startupSeconds": 1.3593413,
"mappedCoreClr": "/app/libcoreclr.so",
"certificateAllocationStackTracking": true,
"eventPipeAttached": false
}
}
@@ -0,0 +1,45 @@
# Linux canonical late-slope diagnostic — completed, no cold-cap breach
One fixed Linux ARM64 diagnostic ran from source
`b18f97236a033b54945b3b9a1d5e306e11e278a7` with OPC UA SDK 2.0.1,
HistorianGateway Client/Contracts 1.0.0 and the pinned self-contained .NET 10.0.14
runtime. The runtime mapping, descriptor controls (2/2), workload (1/1),
shutdown and removal of the task-owned container were verified. The canonical
phase completed **7,201.014 seconds, 1,937 cycles and 484 restarts**. The workload,
container and launcher exited 0. The diagnostic receipt explicitly reports
`acceptance=false`.
No resource assertion latched. Cycle 3 set the original RSS baseline at
225,640,448 bytes (215.19 MiB); the unchanged +128 MiB limit was 359,858,176
bytes (343.19 MiB). The observed quiescent peak was 355,459,072 bytes
(338.99 MiB) at cycle 251 / 929.817 seconds, **4.20 MiB below the limit**.
Retained managed memory peaked at 20,410,640 bytes against its cycle-3
19,923,288-byte baseline; total descriptors peaked at 195 against a baseline of
191. All 1,937 quiescent samples had zero PKI descriptors and zero live
session/subscription/continuation/monitored-item inventories.
| Fixed window (minutes) | Samples | Median RSS (MiB) | Min–max RSS (MiB) | Median retained managed (MiB) |
|---|---:|---:|---:|---:|
| 30–40 | 162 | 316.35 | 310.81–321.04 | 19.02 |
| 60–70 | 162 | 317.03 | 309.78–321.66 | 19.10 |
| 110–120 | 160 | 317.20 | 313.43–320.18 | 19.05 |
Ordinary least squares over all 1,452 quiescent observations from 1,800 through
7,200 seconds yields **+203,355 RSS bytes/hour (+0.194 MiB/hour)** and
**+52,381 retained managed bytes/hour (+0.050 MiB/hour)**. The largest gap
between those observations was 7.641 seconds. At 1,800 seconds, 484 cycles and
121 restarts had completed, exceeding the earlier restart-step work count
without asserting new trace readiness.
This is evidence that sampled RSS largely leveled off after startup in this
**one** tracked Linux run. It does not identify which components own all RSS,
bound unsampled transient peaks, prove that growth can never recur, or supersede
the earlier Linux cold failures. No EventPipe observer was attached; certificate
allocation stack tracking and per-cycle quiescent GC remained enabled. This is
not uninstrumented resource acceptance, a matched SDK1/SDK2 comparison, or a
resolution of macOS native import retention. The original cold cap remains
binding; no warmed-baseline rule was adopted. Issue #799 and G4 remain open.
The [selected receipt](late-slope-linux.json) retains exact identities, raw
evidence hashes, exit statuses, window statistics and sample counts. The
[rehearsal](late-slope-rehearsal.json) and its earlier failure remain separate.