139 lines
8.1 KiB
JSON
139 lines
8.1 KiB
JSON
{
|
|
"planPath": "docs/plans/2026-08-17-perf-followups.md",
|
|
"tasks": [
|
|
{
|
|
"id": 1,
|
|
"subject": "Task 1: Per-driver poll-overrun meter + PollGroupEngine doc notes",
|
|
"status": "completed",
|
|
"note": "e22ecea0 + fix 97902d68 (snake_case tag consts); spec ✅ + code APPROVED; close-out nit: stale doc comment on PollOverruns at OtOpcUaTelemetry.cs:50 still says driver.type"
|
|
},
|
|
{
|
|
"id": 2,
|
|
"subject": "Task 2: S7 span-option validation guard",
|
|
"status": "completed",
|
|
"note": "acb37724; code review APPROVED; deviations: new test file, 2 doc corrections (<= -1 wording)"
|
|
},
|
|
{
|
|
"id": 3,
|
|
"subject": "Task 3: Historian drain — shutdown cancellation is not a per-tag failure",
|
|
"status": "completed",
|
|
"note": "7870c91f; spec ✅ + code APPROVED (Minor: Task.Delay(500) hope-wait at test :590); red run proved healthy-tag sample discard at shutdown; falsification via when-guard weakening"
|
|
},
|
|
{
|
|
"id": 4,
|
|
"subject": "Task 4: Direct-apply artifact read — explicit command timeout",
|
|
"status": "completed",
|
|
"note": "dba5f806; spec ✅ + code APPROVED; IsRelational guard (InMemory tests); EF 10.0.7 pool-reset verified empirically; minor for close-out: comment could state the relational branch is untested in-suite"
|
|
},
|
|
{
|
|
"id": 5,
|
|
"subject": "Task 5: SessionAclDecisionCache eviction race + stress test",
|
|
"status": "completed",
|
|
"note": "d8849345; spec ✅ (interleavings traced) + code APPROVED; falsification 6/6 red reverted. FOLLOW-UP for register (pre-existing, Important, non-blocking): InvalidateIfStale generation-rollover window — a racer can serve a stale-generation verdict from a not-yet-purged shard during the winner's ClearAll (microseconds; revocation/expiry unaffected). Fix shape: generation stamp on Shard or wait-on-winner. Minors: fresh-Shard capacity hint, un-elected global ClearAll comment, CAS backoff, stress-test CI wall-time, 'every booked entry' wording"
|
|
},
|
|
{
|
|
"id": 6,
|
|
"subject": "Task 6: Revalidate memo — reject empty node identifiers",
|
|
"status": "completed",
|
|
"note": "c4d8e4a2; code review APPROVED (pattern-form deviation positive); bypass-count test shape (clock.Calls==2), clock-read-above-guard verified"
|
|
},
|
|
{
|
|
"id": 7,
|
|
"subject": "Task 7: SQL-Server-backed tests for drift probe + rename scan",
|
|
"status": "completed",
|
|
"note": "c149410b; spec ✅ + code APPROVED (5 Minors: mid-run blip not skipped, kill-orphaned DBs, duplicated 200 const in test, ~3s discovery probe offline, TryDropDatabase catches DbException only); xunit-v2 SqlServerFactAttribute skip; 10/10 ran live vs 10.100.0.35"
|
|
},
|
|
{
|
|
"id": 8,
|
|
"subject": "Task 8: ScriptedAlarmEngine TrackBackgroundTask ordering + volatile _disposed",
|
|
"status": "completed",
|
|
"note": "5ae43023; spec ✅ + code APPROVED (2 Minors: null-coalesce comment, remove-before-complete ordering comment); TCS placeholder register-first, volatile _disposed, handover Task.Run preserved"
|
|
},
|
|
{
|
|
"id": 9,
|
|
"subject": "Task 9: Test-reliability hardening (durability second-reader, #491 controls)",
|
|
"status": "completed",
|
|
"blockedBy": [
|
|
3
|
|
],
|
|
"note": "6b46c485; code review APPROVED; robust-wait path (empirically verified fresh-reader re-open observes later commits; xunit v3 skip was available but unneeded); both #491 tests carry load-nondeterminism warnings"
|
|
},
|
|
{
|
|
"id": 10,
|
|
"subject": "Task 10: MTConnect Build streams through XmlReader",
|
|
"status": "completed",
|
|
"note": "cda82c07; spec ✅ + code APPROVED (2 Minors: pre-existing error-phrase asymmetry, AsStream ownership comment); disclosed diff: double-broken doc reports observation error first; ~19% alloc win, honest"
|
|
},
|
|
{
|
|
"id": 11,
|
|
"subject": "Task 11: IS7Plc multi-variable read seam",
|
|
"status": "completed",
|
|
"note": "6ee553cf; code review APPROVED; no shared delegate-hook fake exists — Task 12 gives ImageS7Plc a real multi-var impl"
|
|
},
|
|
{
|
|
"id": 12,
|
|
"subject": "Task 12: S7 multi-var reads for span leftovers",
|
|
"status": "completed",
|
|
"blockedBy": [
|
|
1,
|
|
11
|
|
],
|
|
"note": "20022083; spec ✅ + code APPROVED; Timer/Counter excluded (int vs ushort box parity); S7.Net throws wholesale → per-chunk fallback; 2 Minor coverage gaps for register: no cancellation-branch test on any read path (pre-existing), no one-bad-decode-in-chunk integration case"
|
|
},
|
|
{
|
|
"id": 13,
|
|
"subject": "Task 13: S7 live gate — span planner + multi-var vs s7_1500 fixture",
|
|
"status": "completed",
|
|
"blockedBy": [
|
|
2,
|
|
12
|
|
],
|
|
"note": "57c66416; GATE PASSED live vs 10.100.0.35:1102 (3 requests vs 10; multi-var leg + cross-area MW10 confirmed; falsification bit); code review APPROVED; ops findings: fixture profile baked into image (--build mandatory), /opt/otopcua-s7 root-owned (rsync needs sudo rsync-path); Timer/Counter not live-pinned (no TM/CT fixture area)"
|
|
},
|
|
{
|
|
"id": 14,
|
|
"subject": "Task 14: docker-dev live gate (regression of the merged remainder)",
|
|
"status": "completed",
|
|
"blockedBy": [
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
9,
|
|
10,
|
|
11,
|
|
12
|
|
],
|
|
"note": "GATE PASSED (no commit): fresh rig @6b46c485, deploy sealed 306ms 6/6 Applied, 180s subscription 0 Bad across a REAL surgical UNS-ref apply (rebuild=False, surgicalRawTags=1), UNS mirror live, panels 200, 0 ERR/FTL, teardown clean. Anomalies non-blocking: first-POST 404 ~40s after boot (retry), boot telemetry reconnect warnings, ScriptLogEntry dead-letters on sites. Not exercised: historian E2E (VPN), FetchAndCache, ACL-enabled path, alarm ratchet"
|
|
},
|
|
{
|
|
"id": 15,
|
|
"subject": "Task 15: Close-out — full sweep + Outcomes",
|
|
"status": "completed",
|
|
"note": "07fd17a3 (outcomes/evidence/annotations docs commit; this ledger line recorded in the immediately following commit, since a commit cannot carry its own SHA) preceded by 7c5a843a (review-round comment fixes). Build 0 errors / 896 pre-existing warnings. Full unit sweep 43/43 projects green: 10358 passed, 0 failed, 19 skipped (all pre-existing env-gated; AdminUI.Tests 1537/0-skipped and Configuration.Tests 190/0-skipped confirm Task 7's SQL-backed pins RAN against 10.100.0.35,14330). No failures, so no isolation re-run. CLAUDE.md correction: the ACL decision cache is sharded per API key (ApiKeyId ?? Principal), not per session.",
|
|
"blockedBy": [
|
|
1,
|
|
2,
|
|
3,
|
|
4,
|
|
5,
|
|
6,
|
|
7,
|
|
8,
|
|
9,
|
|
10,
|
|
11,
|
|
12,
|
|
13,
|
|
14
|
|
]
|
|
}
|
|
],
|
|
"closeOut": "All 15 tasks complete on branch perf/followups. Both release-condition LIVE GATES PASSED: S7 span reads vs the s7_1500 fixture at 10.100.0.35:1102 (57c66416 — 3 wire requests for 10 tags with spans on vs 10 with spans off; multi-var + cross-area confirmed; Timer/Counter exclusion NOT live-pinned, no TM/CT fixture area), and the docker-dev regression on the merged remainder (no commit — deploy sealed 306ms 6/6 Applied, a REAL surgical UNS-reference apply with rebuild=False streaming Good across an open 180s subscription, 0 ERR/FTL, clean teardown). Close-out sweep: build 0 errors, 43/43 test projects green, 10358 passed / 0 failed / 19 skipped (all pre-existing env-gated). 12 register items in docs/plans/2026-08-15-perf-roadmap-remainder.md §Follow-up register are annotated closed (append-only, with SHAs); HistorianGateway's cross-repo batch WriteLiveValues RPC and the synchronous NodeDeploymentState writes stay open. A NEW follow-up register for this round (ACL generation-rollover window, S7 cancellation/one-bad-decode coverage, historian hope-wait, AdminUI mid-run-blip + orphaned test DBs, MTConnect AsStream ownership, docker-dev first-POST 404) lives in the plan's ## Outcomes section — none blocking. Not exercised by either gate: historian E2E (needs VPN), FetchAndCache flip, ACL-enabled enforcement path, alarm-bearing surgical ratchet, load-scale throughput.",
|
|
"lastUpdated": "2026-08-17T15:05:00Z"
|
|
}
|