From 3c6607d734e7c5d5d1278a690a44ebbed79abb9a Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Tue, 4 Aug 2026 13:30:56 -0400 Subject: [PATCH] =?UTF-8?q?docs(deferment):=20reconcile=20the=20register?= =?UTF-8?q?=20with=20reality=20=E2=80=94=20the=20tracker=20is=20empty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The register said "14 issues remain open" and recorded #491 as an open live gate with "no gate-passed commit exists". Both were false: the tracker has been at 0 open since 2026-08-04, and #491's gate passed that morning after finding a production-fatal defect the "code complete" reading had missed. Re-derived every count from its source of truth rather than from this file: the Gitea API (0 open; closure dates for all 14), a parse of every docs/plans/*.tasks.json (31 open tasks across 6 files), and a listing of code-reviews/ (10 unreviewed projects, 3 retained Wonderware modules). That surfaced three things reading the file could not: - §6.2 was missing a live plan file that §5 lists as an open gate, so the two sections disagreed on whether the work existed. - §5 cited that file at a date that does not exist in docs/plans/. - The gate's stated blocker has expired — it needed an operator sign-in, and docker-dev has since disabled AdminUI login, so it is runnable now. Also records a correction rather than a status flip: archreview 03/S4 ("primary gate default-allows on unknown role") is the same shape as a decision deliberately taken in PrimaryGatePolicy.ShouldRecordHistorizedValues, where an unknown role captures. Defensible there, not in a write gate — so closing 03/S4 must not generalise one rule across both. Third round running in which this file's own bookkeeping was what broke, after the dangling pre-amend SHAs and the truncation. The trailer now says so, and says to re-derive rather than re-read. Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo --- deferment.md | 138 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 126 insertions(+), 12 deletions(-) diff --git a/deferment.md b/deferment.md index dd01aa57..c6425d2c 100644 --- a/deferment.md +++ b/deferment.md @@ -13,9 +13,12 @@ > preserved as that audit** — they are the record of what was found, not a description of the tree today. > **§9 is the live status.** > -> **Current tree:** `master` @ `2a0461a1` (merges `914d70bf` + `2a0461a1`), 2026-07-30. Items closed since -> the audit are struck through or marked ✅ in place, so a reader can still see what was found and what -> became of it. +> **Current tree:** `master` @ `4bdce910`, 2026-08-04. Items closed since the audit are struck through or +> marked ✅ in place, so a reader can still see what was found and what became of it. +> +> ⚠️ **The tracker is EMPTY as of 2026-08-04 — 0 open issues.** Every issue this register enumerates has +> been closed. What is left is therefore *entirely* untracked: live gates that need hardware, one +> unexecuted plan, three carried-open archreview findings, and a review-coverage gap. See §0.1. --- @@ -36,7 +39,37 @@ how much they should worry you: Nothing here is a data-loss or outage defect. The sharpest edge is §3 — silent non-enforcement. -### 0.1 What is actually left (as at `2a0461a1`, 2026-07-30) +### 0.1 What is actually left (re-verified at `4bdce910`, 2026-08-04) + +> **Read this subsection, not the table below it.** The 2026-07-30 table that follows is preserved as the +> record of what the remediation left behind; every tracker item in it has since closed. The live picture +> is here. + +**The tracker is at 0 open issues.** Verified against the API, not inferred: the 14 issues §0.1 listed as +open on 2026-07-31 all closed between 2026-07-31 and 2026-08-04 — #520, #525, the eight MQTT follow-ups +(#508–#515), #489, #481, #468, #491 — as did the 11 filed after this register's audit (#526–#538). + +So everything below is **untracked work**. Nothing in it is a data-loss or outage defect. + +| What | Nature | Where | +|---|---|---| +| **4 live gates blocked on hardware/licence** — archreview R2-03 (VT Good→Bad on a data-fed rig), R2-10 (force breaker-OPEN), Galaxy `ScanStateProbeParityTests` (licence-gated), v2 GA exit criteria (FOCAS live-CNC smoke #54, OPC UA CTT pass, Ignition 8.3 cutover) | Cannot be closed from this box. Not decisions — inputs. | §5 | +| **1 deferred live-verify task** — `2026-06-14-driver-reconfigure-while-faulted` Task 3, subject literally "DEFERRED (skipped)" | Now runnable: docker-dev login is disabled, so `/run` verification needs no operator. | §5 | +| **G-7 residual** — Sql / MTConnect / Calculation / OpcUaClient have no Contracts-side `Inspect` | **The deploy gate is weaker than the authoring gate.** `TagConfigValidator` covers 11 of 12, so config arriving by **CSV import or API** — the paths that skip the UI — meets only the weaker gate. | §1.2 | +| **3 carried-open archreview findings** — the failure-visibility trio: 01/S-1 (`AddressSpaceApplier` swallows every sink failure; a deploy reports **Applied** while broken), 03/S4 (primary gate default-allows on unknown role), 06/S-1 (Galaxy optimistic write success) | No remediation branch ever targeted them. 01/S-1 is the sharpest: a green deploy that isn't. | §6.3 | +| **1 genuinely unexecuted plan** — `2026-05-29-adminui-followups`, **19 pending / 0 completed** | The only substantial engineering left. ⚠️ Its first step is an **overlap audit**, not code: several items look superseded by v3's `TagConfigEditorMap`. | §6.2 | +| **11 other open plan tasks** — 5 akka-hosting partials (likely v3-superseded), 4+1 followups-batch (open *by choice*), fixedtree Task 11, 1 manual smoke checklist | Small, and two of the groups are decisions already taken. | §6.2 | +| **Review-coverage gap** — 10 shipped projects never reviewed (Calculation, Historian.Gateway, Mqtt +Browser/Contracts, MTConnect +Contracts, Sql +Browser/Contracts) while **3 modules still review the retired Wonderware backend** | Re-verified 2026-08-04 against `code-reviews/`. Unchanged since the audit. | §6.3 | + +⚠️ **One correction worth carrying forward.** archreview **03/S4** — "primary gate default-allows on +unknown role" — is the *same shape* as a decision deliberately taken on 2026-08-04 in +`PrimaryGatePolicy.ShouldRecordHistorizedValues`, where an unknown role **captures**. That is right for +historization (a duplicate sample beats a hole in the trend, and the duplicate is bounded by promotion) +and wrong for a write gate. Closing 03/S4 must not sweep both under one rule. + +--- + +### 0.1-prev What the remediation left behind (as at `2a0461a1`, 2026-07-30) The remediation (§9) closed the two mechanical themes outright and converted the two judgement-call themes into tracked decisions. What remains: @@ -50,7 +83,7 @@ themes into tracked decisions. What remains: | **G-7** `EquipmentTagConfigInspector` coverage | ◐ **Narrowed + guarded** (2026-07-28): MQTT wired (it shipped an `Inspect` nobody called), and a reflection guard now fails the build if a reachable driver ships one and is not mapped. **Residual:** Sql / MTConnect / Calculation / OpcUaClient have no Contracts-side `Inspect` at all, so the deploy gate stays blind for them while the AdminUI validates them — see §1.2. | §1.2 | | ~~**13 `EquipmentTagsDarkBatch4` skipped tests**~~ | ✅ **Done** — 6 revived onto the raw/UNS shape, 3 folded into a widened live parity corpus, 4 deleted as retired. The reason constant is gone. **Skips now: `Runtime.Tests` 13 → 3, `OpcUaServer.Tests` 4 → 1** — all remaining are deliberate `EquipmentDeviceBindingRetired` tombstones. | §9 (2026-07-28, skips) | | 17 other tracker issues | Driver features + deferred work, unchanged by this remediation. | §2 | -| Open live gates | #491 continuous historization, #468 browser tree, archreview R2-03 / R2-10. *(The un-gated drift detector's gate closed by deletion — see #523.)* | §5 | +| Open live gates | ~~#491 continuous historization, #468 browser tree~~ ✅ **both PASSED since** (#468 `c2c3c522`, #491 `e77ea4aa` + the #537/#538 gate `4bdce910`); archreview R2-03 / R2-10 remain. *(The un-gated drift detector's gate closed by deletion — see #523.)* | §5 | ✅ **The tracker is now clean of stale-open issues** (2026-07-30). **#516**, **#518**, **#507** and **#523** were closed, each with a resolution comment recording what was actually done — which differs @@ -64,7 +97,8 @@ change: | **#507** | **Superseded, not migrated** — the requested migration was impossible, since both of the path's inputs are structurally empty in v3. | | **#523** | Done, with the consequence carried forward: **AbCip and FOCAS now have no tag-change signal at all.** | -**14 issues remain open** (verified against the tracker API 2026-07-31, not derived): #520 and #525 +~~**14 issues remain open**~~ ✅ **ALL 14 CLOSED as at 2026-08-04 — the tracker is empty.** Preserved as +found (verified against the tracker API 2026-07-31, not derived): #520 and #525 (the two remaining judgement calls), the eight MQTT follow-ups (#508–#515), #491, #489, #481, #468. Membership moved across three rounds: **#521 and #522 closed, #524 and #525 opened** (both residuals @@ -145,6 +179,14 @@ incomplete), 2 CANNOT VERIFY (correctly filed as hardware/fixture-gated). > periodic re-browse). #523 has since been done and closed too. After closing the four resolved issues on > 2026-07-30 the tracker shows **17 open, none stale**. Everything not marked below is unchanged. +> ✅ **SUPERSEDED 2026-08-04 — every issue in the table below is CLOSED, as is every issue filed after this +> audit (#526–#538). The tracker is at 0 open.** The table is retained because the *verdict* column is the +> durable part: four of these were wider or narrower than filed, and three were resolved differently from +> how they were asked for. Closure dates, from the API rather than inferred: #489, #481, #508–#515 and +> #525 on 2026-07-31; #520 and #468 on 2026-08-01; #491 on 2026-08-04. #491's gate then produced **#537** +> (no Primary gate on historization capture) and **#538** (one poison tag re-writes every healthy tag) — +> both filed and closed the same day, `e7fbe977` + `4bdce910`. + | # | Title (abbrev.) | Verdict | Key evidence | Kind | |---|---|---|---|---| | **518** ✅ | `IRediscoverable` + `IHostConnectivityProbe` have no consumer; CLAUDE.md wrong — **RESOLVED `09a401b8`: rediscovery consumed as an operator prompt; probe half split to #521. Stale-open on tracker.** | **CONFIRMED — worse than filed** | Only `+=` in `src/` are Galaxy self-wiring (`GalaxyDriver.cs:586`, `:221`). `GetHostStatuses()` has **zero call sites** outside the interface + implementations; `DriverHostStatuses` DbSet is referenced only by its declaration and a test. | Defect + doc error | @@ -345,11 +387,11 @@ mere env-var presence, so it cannot pass vacuously. | Gate | Status | Evidence | |---|---|---| | ~~**Tag-set drift detection** (shipped `e77c8a35`)~~ | ✅ **CLOSED BY DELETION** — removed under Gitea **#523** rather than gated. The gate it needed (a device whose tag set actually changes) required exactly the traffic the removal objected to. | §9, 2026-07-28 (#523) | -| **Continuous-historization value capture** (#491) | **OPEN** — code complete, unproven in production | `CLAUDE.md:710`; no gate-passed commit exists | -| **Wave-0 universal discovery browser** full tree render (#468) | **OPEN** — fixture-blocked | tracking doc §Wave 0; named as blocking BACnet browse | +| **Continuous-historization value capture** (#491) | ✅ **PASSED** `e77ea4aa` (2026-08-04) — and it found a **production-fatal defect the code-complete reading missed**: `ConfigureAwait(false)` in the Akka handler destroyed `Self`, the actor restarted, and the restart discarded the (empty-seeded) ref set. One value captured, then permanent silence. Two follow-ups filed and closed the same day: **#537** (capture had no Primary gate — both pair nodes wrote duplicates) and **#538** (a poison tag pinned the FIFO head, re-writing every healthy tag forever). | `docs/plans/2026-08-01-continuous-historization-live-gate.md`; `ad744734`, `e77ea4aa`, `e7fbe977`, `4bdce910` | +| **Wave-0 universal discovery browser** full tree render (#468) | ✅ **PASSED** `c2c3c522` (2026-08-01) — unblocked by **building** the missing sim capability (an `ab_server` patch) rather than waiting for hardware. The gate then found a decoder defect **350 unit tests agreed with**. | tracking doc §Wave 0 | | **archreview R2-03** — VT Good→Bad on a data-fed rig | **OPEN** — explicitly "live-blocked on this data-less rig" | `archreview/plans/STATUS.md` | | **archreview R2-10** — force breaker-OPEN live | **OPEN** — breaker-OPEN state never forced live | `archreview/plans/R2-10-*.tasks.json` | -| **Driver-reconfigure-while-faulted** Task 3 | **OPEN** — task subject literally "DEFERRED" | `2026-07-14-driver-reconfigure-while-faulted-plan.md.tasks.json` | +| **Driver-reconfigure-while-faulted** Task 3 | **OPEN** — task subject literally `"Task 3: Live /run verification — DEFERRED (skipped)"`, `blockedBy: [1]`. ⚠️ **The block no longer holds:** docker-dev runs the AdminUI with `Security__Auth__DisableLogin`, so `/run` verification needs no operator sign-in. This is the one gate on this list that is *runnable today*. | `2026-06-14-driver-reconfigure-while-faulted-plan.md.tasks.json` — ⚠️ **§5 cited `2026-07-14`, which does not exist**; corrected 2026-08-04 | | Galaxy `ScanStateProbeParityTests` | **OPEN** — licence-gated (one `$WinPlatform` on this box) | `docs/v2/Galaxy.ParityRig.md:180` | | **v2 GA exit criteria** — FOCAS live-CNC wire smoke (#54), OPC UA CTT/compliance pass, Ignition 8.3 redundancy cutover | **OPEN** — manual/hardware/external-tool | `docs/v2/v2-release-readiness.md:105-120` | | mesh Phase 4 | ✅ **PASSED** `1281aebf` | CLAUDE.md said open — **corrected**, §7.2 | @@ -388,6 +430,13 @@ bookkeeping, not backlog. ### 6.2 GENUINELY LIVE +> ✅ **Re-counted 2026-08-04 by parsing every `docs/plans/*.tasks.json`, not by reading this table.** The +> five rows below are confirmed unchanged, and the sweep found **one file this section missed**: +> `2026-06-14-driver-reconfigure-while-faulted-plan.md.tasks.json` (3 completed / 1 pending — the §5 live +> gate). Total open plan tasks across the tree: **31** — 19 of them in the single AdminUI file. Every +> other `.tasks.json` is fully closed; `2026-07-24-mesh-phase6` carries one task marked +> `resolved-no-flip`, which is a recorded decision, not an open item. + | File | Open | Note | |---|---|---| | **`2026-05-29-adminui-followups.md.tasks.json`** ⬅ **now the largest open item in `docs/plans/`** | **19 pending / 0 completed** | **The largest unexecuted plan in the tree.** Generic `CollectionEditor`; per-driver device/tag editors ×7; typed resilience form; `RoleMapper.Merge` + DB-backed LDAP→role mapping + `RoleGrants.razor` + FleetAdmin authz. **Several items look superseded by v3's `TagConfigEditorMap` — verify overlap before executing.** | @@ -395,6 +444,7 @@ bookkeeping, not backlog. | `2026-06-26-otopcua-fixedtree-followups.md.tasks.json` | 1 pending | Task 11 build + regression | | `2026-05-26-akka-hosting-alignment-plan.md.tasks.json` | 5 partial | F8/F9/F10/F13/F14 — oldest open items; **likely superseded by v3, verify** | | `2026-05-28-adminui-driver-pages-plan.md.tasks.json` | 1 partial | 10.4 manual smoke checklist | +| `2026-06-14-driver-reconfigure-while-faulted-plan.md.tasks.json` ⬅ **added 2026-08-04** | 1 pending | Task 3 live `/run` verify, self-described "DEFERRED (skipped)". **Runnable now** — see §5. | `docs/plans/2026-07-23-mesh-phase4-…tasks.json` Task 9 was the only `deferred`-flagged mesh task — **it has since landed** (`3a590a0c`), so that file is now stale too. @@ -408,6 +458,11 @@ bookkeeping, not backlog. `Driver.Calculation`, `Driver.Historian.Gateway`, `Driver.Mqtt` (+`.Browser`, `.Contracts`), `Driver.MTConnect` (+`.Contracts`), `Driver.Sql` (+`.Browser`, `.Contracts`). Meanwhile three modules review the **retired** Wonderware backend. + ✅ **Re-verified 2026-08-04 against the directory listing — unchanged, both halves.** The three + `Driver.Historian.Wonderware*` module directories are still present and still the only historian + review coverage, while the gateway backend that actually ships has none. Worth noting *which* 10 these + are: they are exactly the drivers added since the review sweep, i.e. the newest and least-exercised + code in the tree carries the least review. - **`archreview/`** — `00-OVERALL.md:60-79` carries an explicit "Carried open … no remediation branch targeted them" block. The largest coherent batch is the **failure-visibility trio**: 01/S-1 (`AddressSpaceApplier` swallows every sink failure, deploy reports Applied even when broken), 03/S4 @@ -1139,6 +1194,59 @@ and passed, so only reading the diff by hand found it. slc500/micrologix/plc5 compose profiles, which are not up on `10.100.0.35` (only the AbCip controllogix fixture is). Reproduced on a stashed tree before dismissing them. +### 2026-08-04 — reconciled against reality; the tracker is empty + +No code changed. This entry records a re-verification pass and the drift it corrected, prompted by the +question "what's left" — which this file existed to answer and, at the time it was asked, answered +**wrongly**. + +**The drift.** §0.1 asserted "14 issues remain open" and §5 recorded #491 as `OPEN — code complete, +unproven in production; no gate-passed commit exists`. Both were false: the tracker had been at **0 open +since 2026-08-04**, and #491's gate had passed that morning — after finding a production-fatal defect +that the "code complete" reading had specifically failed to anticipate. §2's row for 491 still read +`CANNOT VERIFY (needs VPN'd gateway)`. + +⚠️ **This is the third round in which this file's bookkeeping was the thing that broke** — after the +dangling pre-amend SHAs (round 1) and the truncation (round 2). The failure mode differs, but the shape +does not: **the register is only updated by the work it describes, so work that closes an item elsewhere +leaves the register asserting the item is open.** The two previous failures were mechanical and were +fixed with mechanical guards; this one is structural, and the honest guard is to re-derive rather than +re-read. Which is what this pass did. + +**Everything below was re-derived from the source of truth, not from this file:** + +| Claim | How re-derived | Result | +|---|---|---| +| Open issue count | Gitea API, `state=open` | **0** — corrected from 14 | +| Closure dates for the 14 | Gitea API per issue | #489/#481/#508–#515/#525 on 07-31; #520/#468 on 08-01; #491 on 08-04 | +| Open plan tasks | parsed **every** `docs/plans/*.tasks.json` | **31** across 6 files — and found a 6th file §6.2 had missed | +| Review coverage | listed `code-reviews/` | 10 projects unreviewed, 3 Wonderware modules retained — **unchanged** | + +**What the re-derivation found that reading the file would not have:** + +- **§6.2 was missing a file.** `2026-06-14-driver-reconfigure-while-faulted-plan.md.tasks.json` (1 + pending) appears in §5 as a live gate but never in §6.2's inventory of live plans, so the two sections + disagreed on whether it existed as work. +- **§5 cited that file at the wrong date** — `2026-07-14-…`, which does not exist in `docs/plans/`. + Anyone following the reference would have found nothing and concluded the gate was already closed. +- **That gate's stated blocker has expired.** Task 3 is a live `/run` verification, deferred when it + needed an operator to sign in. docker-dev has since run the AdminUI with login disabled, so it is + runnable unattended — the only item on §5's list that is. + +**One substantive correction carried into §0.1, not merely a status flip.** archreview **03/S4** — +"primary gate default-allows on unknown role" — describes the same shape as a decision *deliberately +taken* on 2026-08-04 in `PrimaryGatePolicy.ShouldRecordHistorizedValues`, where an unknown role +**captures**. Both readings are defensible in their own context (a duplicate historian sample is bounded +and self-correcting; an unauthorized write is not), so whoever closes 03/S4 must not generalise one rule +across both. Recorded now, while the reasoning is fresh, rather than left for a future reader to +rediscover from two files that never reference each other. + +**What is left is now entirely untracked**, which is itself the finding: 4 hardware/licence-gated live +gates, 1 runnable deferred gate, the G-7 residual (deploy gate weaker than the authoring gate for 4 +drivers), 3 carried-open archreview findings led by 01/S-1 (`AddressSpaceApplier` swallows sink failures +— a deploy reports Applied while broken), the 19-task AdminUI plan, and the review-coverage gap. See +§0.1 for the table. + --- --- @@ -1147,6 +1255,12 @@ controllogix fixture is). Reproduced on a stashed tree before dismissing them. Every `path:line` reference was read from source. Items marked CANNOT VERIFY require hardware, a VPN'd gateway, or a live rig and are listed as unproven rather than assumed.* -*Remediated 2026-07-27/28 (merge `914d70bf`) and 2026-07-30 (merge `2a0461a1`). §9 is the execution record -and the live status — where §1–§8 and §9 disagree, **§9 is current**. Path/line references in §1–§8 are as at `90bdaa44` and several no -longer resolve, by design: the code they pointed at was deleted.* +*Remediated 2026-07-27/28 (merge `914d70bf`), 2026-07-30 (merge `2a0461a1`), and reconciled against the +tracker + `docs/plans/` on 2026-08-04 at `4bdce910`. §9 is the execution record and the live status — +where §1–§8 and §9 disagree, **§9 is current**. Path/line references in §1–§8 are as at `90bdaa44` and +several no longer resolve, by design: the code they pointed at was deleted.* + +*⚠️ **Counts in this file go stale silently.** Three rounds running, the register's own bookkeeping was +what broke. Before trusting any number here — open issues, pending tasks, unreviewed modules — re-derive +it: `curl` the tracker API, parse `docs/plans/*.tasks.json`, list `code-reviews/`. Each is one command, +and each has caught this file being wrong.*