docs(deferment): record the #521/#522 closures — both resolved differently from how they were filed
v2-ci / build (push) Successful in 5m1s
v2-ci / unit-tests (push) Failing after 15m17s

Also corrects two claims this register itself got wrong, which changed both decisions:

- §3.2 said DriverHostStatus was "deliberately re-created in the v3 initial migration, so
  deleting on inference would be wrong". The publisher it waited for cannot be written at
  all — Phase 4 leaves a driver-only node with no ConfigDb. "Deliberately re-created" meant
  carried forward mechanically.
- §3.3 said the Tier-C-only protections were dormant, implying Tier A/B ones ran. Nothing
  constructed MemoryTracking either, so the whole Core/Stability layer was dead — which is
  why 'pass real tiers' was never a flag flip.

Open count stays 17 (verified against the tracker API, not derived — the derivation was wrong
last round) but membership changed: #521/#522 closed, #524/#525 opened.

Claude-Session: https://claude.ai/code/session_015p7wGqy3YpZNCpDzTpGMKo
This commit is contained in:
Joseph Doherty
2026-07-30 04:58:25 -04:00
parent abda6f9ef8
commit 820abd1fa3
+67 -14
View File
@@ -29,9 +29,9 @@ how much they should worry you:
| # | Theme | Why it matters | Now | | # | Theme | Why it matters | Now |
|---|---|---|---| |---|---|---|---|
| **1** | **Three subsystems are fully authored, persisted, and shipped — and never executed.** Node ACLs, `IRediscoverable`/`IHostConnectivityProbe`, and `DriverTypeRegistry`. | An operator can author a rule, save it, deploy it green, and have it do **nothing**. §3 | ◐ `IRediscoverable` now consumed; the other two are **documented as inert** and tracked (#520, #521, #522) rather than fixed | | **1** | **Three subsystems are fully authored, persisted, and shipped — and never executed.** Node ACLs, `IRediscoverable`/`IHostConnectivityProbe`, and `DriverTypeRegistry`. | An operator can author a rule, save it, deploy it green, and have it do **nothing**. §3 | ◐ **Two of three now settled**: `IRediscoverable` consumed (#518), `IHostConnectivityProbe` re-transported to telemetry (#521), `DriverTypeRegistry` + the tier machinery **deleted** (#522). Only **node ACLs** remain authored-but-inert, tracked as #520 |
| **2** | **AdminUI authoring-dispatch gaps.** Calculation is offered in the driver picker but has no config form; three drivers have no device form; CSV + browse-commit dispatch maps miss the new drivers. | The "registered but unauthorable" class that has now bitten twice. §1.2 | ✅ **Closed** — G-1…G-6 fixed and guarded; G-7 remains | | **2** | **AdminUI authoring-dispatch gaps.** Calculation is offered in the driver picker but has no config form; three drivers have no device form; CSV + browse-commit dispatch maps miss the new drivers. | The "registered but unauthorable" class that has now bitten twice. §1.2 | ✅ **Closed** — G-1…G-6 fixed and guarded; G-7 remains |
| **3** | **17 open issues, all confirmed still open**, several broader than filed. | §2 | ◐ 4 resolved + closed, 4 new filed (one since closed) → **17 open**, none stale | | **3** | **17 open issues, all confirmed still open**, several broader than filed. | §2 | ◐ 6 resolved + closed, 6 new filed (one since closed) → **17 open**, none stale. Two of the six closures (#521, #522) resolved *differently from how they were filed* — see §3.2/§3.3 |
| **4** | **Bookkeeping drift.** 8 `.tasks.json` files show ~140 "pending" tasks for work that shipped; 5 CLAUDE.md status claims are stale. | Someone follows the tracker and rebuilds a shipped driver. §6, §7 | ✅ **Closed** — 13 plan files + 11 archreview gates written back | | **4** | **Bookkeeping drift.** 8 `.tasks.json` files show ~140 "pending" tasks for work that shipped; 5 CLAUDE.md status claims are stale. | Someone follows the tracker and rebuilds a shipped driver. §6, §7 | ✅ **Closed** — 13 plan files + 11 archreview gates written back |
Nothing here is a data-loss or outage defect. The sharpest edge is §3 — silent non-enforcement. Nothing here is a data-loss or outage defect. The sharpest edge is §3 — silent non-enforcement.
@@ -44,8 +44,8 @@ themes into tracked decisions. What remains:
| Item | Nature | Where | | Item | Nature | Where |
|---|---|---| |---|---|---|
| **#520** node ACLs authored + deployed but **never enforced** | Decision: wire it or retire the surface. Non-enforcement is now stated in docs and warned in the UI, so nobody can author a deny rule believing it works — but reads are still ungated. | §3.1 | | **#520** node ACLs authored + deployed but **never enforced** | Decision: wire it or retire the surface. Non-enforcement is now stated in docs and warned in the UI, so nobody can author a deny rule believing it works — but reads are still ungated. | §3.1 |
| **#521** `IHostConnectivityProbe` / `DriverHostStatus` dead surface | Decision: build the publisher or delete it. The table was deliberately re-created in the v3 initial migration, so deleting on inference would be wrong. | §3.2 | | **#521** `IHostConnectivityProbe` / `DriverHostStatus` dead surface **CLOSED** `abda6f9e` | Resolved by changing the *transport*, not by either option as filed — the publisher as designed was unbuildable after Phase 4. Host status now rides `DriverHealthChanged` to `/hosts`; table dropped. | §3.2 |
| **#522** driver stability tiers inert | Decision: pass real tiers or delete the machinery. Docs now say every driver runs Tier A. | §3.3 | | **#522** driver stability tiers inert **CLOSED** `abda6f9e` | Deleted. The inertness was broader than filed (nothing constructed `MemoryTracking` either), and the model's premise — an out-of-process Host to recycle — no longer exists. `DriverTier` kept. | §3.3 |
| ~~**#523** remove the periodic 5-min device re-browse~~ | ✅ **Done + closed on the tracker.** **AbCip and FOCAS now have no tag-change signal at all**; that is the accepted consequence, not an oversight. | §9 (2026-07-30, #523) | | ~~**#523** remove the periodic 5-min device re-browse~~ | ✅ **Done + closed on the tracker.** **AbCip and FOCAS now have no tag-change signal at all**; that is the accepted consequence, not an oversight. | §9 (2026-07-30, #523) |
| **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 | | **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) | | ~~**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) |
@@ -64,8 +64,13 @@ change:
| **#507** | **Superseded, not migrated** — the requested migration was impossible, since both of the path's inputs are structurally empty in v3. | | **#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.** | | **#523** | Done, with the consequence carried forward: **AbCip and FOCAS now have no tag-change signal at all.** |
**17 issues remain open**, all genuine: #519#522 (four judgement calls + a design consequence), #517, **17 issues remain open** (verified against the tracker API, not derived): #519, #520 (two judgement
the eight MQTT follow-ups (#508#515), #491, #489, #481, #468. calls), #524 + #525 (both split out of the #521/#522 work rather than folded in), #517, the eight MQTT
follow-ups (#508#515), #491, #489, #481, #468.
The count is unchanged at 17 but the *membership* is not — **#521 and #522 closed, #524 and #525 opened.**
Both new ones are residuals their parent issue's decision did not cover: a second dead table
(`DriverInstanceResilienceStatus`) and two now-consumerless `IDriver` members.
--- ---
@@ -212,9 +217,20 @@ highest-risk doc error found.
> ✅ **`IRediscoverable` half FIXED** (`09a401b8`) — consumed by `DriverInstanceActor` and surfaced as a > ✅ **`IRediscoverable` half FIXED** (`09a401b8`) — consumed by `DriverInstanceActor` and surfaced as a
> `/hosts` re-browse prompt. Advisory: the served address space is not rebuilt, because v3 authors raw tags > `/hosts` re-browse prompt. Advisory: the served address space is not rebuilt, because v3 authors raw tags
> through `/raw` browse-commit. > through `/raw` browse-commit.
> **`IHostConnectivityProbe` half UNRESOLVED** (Gitea **#521**) — `GetHostStatuses()` still has zero > **`IHostConnectivityProbe` half RESOLVED** (`abda6f9e`, Gitea **#521** closed) — but **not as this
> production call sites and nothing writes a `DriverHostStatus` row. Not deleted on inference: the table was > register or the issue framed it.** The choice was never "build the publisher or delete it": the publisher
> deliberately re-created in the v3 initial migration. > as designed — driver nodes upserting `DriverHostStatus` rows — is **unbuildable**, because per-cluster mesh
> Phase 4 gates `AddOtOpcUaConfigDb` on the `admin` role, so a driver-only node has no ConfigDb connection to
> write with. The design predates Phase 4 and nobody revisited it; "deliberately re-created in the v3 initial
> migration" turned out to mean *carried forward mechanically*, not *intended*.
> So the capability was kept and the **transport** changed: `DriverHealthChanged.HostStatuses` carries the
> probe result to `/hosts` over the Phase 5 telemetry stream, which needs no DB and survives the mesh split.
> The table is dropped (`DropDriverHostStatusTable`). Live-gated on docker-dev, **including the cross-mesh
> gRPC path** — site-a first showed `—`, which is also what a broken mapper produces, so it was rebuilt to
> prove the `has_host_statuses` presence flag round-trips rather than assuming version skew.
> ⏳ **A third table, same defect, found en route:** `DriverInstanceResilienceStatus` also has no writer and
> no reader — only its DbSet declaration — while the live data rides the `driver-resilience-status` channel.
> Documented in place, filed as Gitea **#524** rather than widening the schema change beyond the ask.
Gitea #518/#507. Nine drivers raise; nothing consumes. `DriverHostStatus` table exists Gitea #518/#507. Nine drivers raise; nothing consumes. `DriverHostStatus` table exists
(`OtOpcUaConfigDbContext.cs:48`, migration `20260715230637_V3Initial.cs:108`) with a doc-comment (`OtOpcUaConfigDbContext.cs:48`, migration `20260715230637_V3Initial.cs:108`) with a doc-comment
@@ -225,11 +241,23 @@ per-host connectivity table is permanently empty.
### 3.3 `DriverTypeRegistry` is vestigial ### 3.3 `DriverTypeRegistry` is vestigial
> **Still true; documented** (`88ce8df0`, Gitea **#522**). `docs/v2/driver-stability.md` now states its > **RESOLVED — DELETED** (`abda6f9e`, Gitea **#522** closed). `DriverTypeRegistry`, `MemoryTracking`,
> tier table is aspirational. A second staleness the audit missed is corrected there too: the > `MemoryRecycle`, `ScheduledRecycleScheduler`, `IDriverSupervisor` and the operator-authorable
> **separate-Windows-service hosting** that document describes for Tier C no longer exists either (Galaxy > `RecycleIntervalSeconds` knob are gone.
> moved to the mxaccessgw sidecar in PR 7.2; FOCAS went in-process with its managed wire client). No >
> runtime change — enabling recycle on two live drivers wants its own live gate. > ⚠️ **This register understated the inertness, exactly as the issue did.** Both said the *Tier-C-only*
> protections were dormant, implying the Tier A/B parts ran. They did not: **nothing constructed
> `MemoryTracking` at all** outside its own unit tests, so the whole `Core/Stability` recycle layer was dead.
> That changed the decision — "pass real tiers" was never a flag flip, it meant writing the wiring that never
> existed *and* arming it on two live drivers at once. Deletion won because the premise is gone, not merely
> unused: Tier C meant an out-of-process Host a supervisor could restart, and `IDriverSupervisor` had zero
> implementations because there is nothing left to implement against.
>
> **`DriverTier` itself survives and is load-bearing** — `GetTierDefaults` supplies the real per-capability
> timeout/retry/breaker policies. Only the isolation-and-recycle layer above it went.
> `WedgeDetector` shared the folder, is equally dead, and is **not** recycle machinery — restored rather than
> swept up in a decision that was not about it. `IDriver.GetMemoryFootprint`/`FlushOptionalCachesAsync` lose
> their only consumer here; documented and filed as Gitea **#525** rather than buried in a 12-driver sweep.
Independently verified for this report: `src/Core/…Core.Abstractions/DriverTypeRegistry.cs:20` is Independently verified for this report: `src/Core/…Core.Abstractions/DriverTypeRegistry.cs:20` is
referenced **only** by `tests/Core/…/DriverTypeRegistryTests.cs`. Nothing registers metadata at referenced **only** by `tests/Core/…/DriverTypeRegistryTests.cs`. Nothing registers metadata at
@@ -484,6 +512,31 @@ also `--no-ff`) carrying the items §8 did not cover.
| §7.2 `Phase7*``AddressSpace*` rename | ✅ **Done** — 4 live docs | `4624141a` | | §7.2 `Phase7*``AddressSpace*` rename | ✅ **Done** — 4 live docs | `4624141a` |
| §7.2 missing `Sql.md` / `Calculation.md` | ✅ **Done** | `f3cd685d` | | §7.2 missing `Sql.md` / `Calculation.md` | ✅ **Done** | `f3cd685d` |
**A third round merged 2026-07-30 as `abda6f9e`** (branch `fix/521-522-host-status-and-tiers`, 3 commits,
`--no-ff`) closing the two keep-or-delete decisions §8 deliberately left to the user.
| Round-3 item | Status | Commit |
|---|---|---|
| **#521** `IHostConnectivityProbe` | ✅ **Done — resolved differently from how it was filed.** Neither "build the publisher" nor "delete": the publisher as designed was **unbuildable** after Phase 4, so the capability was kept and the transport changed to the Phase 5 telemetry stream. Table dropped. | `30d0697c` |
| **#522** driver stability tiers | ✅ **Done — deleted.** The inertness was broader than either the issue or this register said: nothing constructed `MemoryTracking` either, so "pass real tiers" was never a flag flip. | `cbb88229` |
| Live gate on docker-dev | ✅ **Passed**, one fix (`1 hosts``1 host`) | `ce589569` |
**Both closures produced a residual that was filed rather than folded in** — a second dead table
(#524 `DriverInstanceResilienceStatus`) and two now-consumerless `IDriver` members (#525). Neither was
in scope; both would have widened a schema change or a 12-driver sweep past what was asked.
**Three things this round got right by not trusting the register:**
- §3.2 recorded that `DriverHostStatus` was *"deliberately re-created in the v3 initial migration, so
deleting on inference would be wrong."* Checking Phase 4 showed the publisher it was waiting for
**cannot be written at all** — a driver-only node has no ConfigDb. "Deliberately re-created" meant
*carried forward mechanically*.
- §3.3 (and #522) said the Tier-C protections were dormant, implying Tier A/B ones ran. Nothing
constructed the trackers at all.
- The live gate treated an ambiguous observation as ambiguous: site-a showed `—` for host status, which
is what version skew **and** a broken cross-mesh mapper both produce. Rebuilding site-a distinguished
them rather than assuming the benign reading.
⚠️ **This file was destroyed and restored during round 2 — see the 2026-07-30 entry at the end of §9.** ⚠️ **This file was destroyed and restored during round 2 — see the 2026-07-30 entry at the end of §9.**
It is the second time in two rounds that the register's own bookkeeping step damaged the register. It is the second time in two rounds that the register's own bookkeeping step damaged the register.