docs: live-gate record for #541 on docker-dev (PASS; found the 0-tags defect)

This commit is contained in:
Joseph Doherty
2026-08-05 20:26:00 -04:00
parent dd900f970a
commit b25279dbbd
@@ -0,0 +1,94 @@
# Live gate — skipped-tag visibility (Gitea #541)
**Date:** 2026-08-05
**Rig:** local `docker-dev/` (OrbStack), MAIN pair `central-1` / `central-2`, AdminUI `http://localhost:9200`
**Build under test:** `fix/541-skipped-tag-visibility`
**Result: PASS**, and the gate found one defect that unit tests did not (§4).
## What needed proving
The unit suites pin the ledger semantics, the publish fingerprint, the proto round-trip and the
view-model. None of them prove the thing an operator actually depends on: that the **Tags** column on
`/hosts` renders the right cell, in the right colour, with actionable detail, against a driver that is
genuinely skipping tags on a real deployment.
## Method
The rig already carried eleven driver instances. Three of the thirteen tags on the `pymodbus` Modbus
driver had their `TagConfig.region` rewritten to `NoSuchRegion` — the realistic shape of a bad blob —
then MAIN was redeployed via `POST /api/deployments`. Backup of the original thirteen blobs taken
first; all three restored and redeployed at the end (§5).
## Results
Driver logs confirmed the skips reached the driver:
```
[WRN] Modbus tag config did not map to a definition; skipping. Driver=MAIN-modbus RawPath=pymodbus/plc/Probe3
[WRN] Modbus tag config did not map to a definition; skipping. Driver=MAIN-modbus RawPath=pymodbus/plc/Probe4
[WRN] Modbus tag config did not map to a definition; skipping. Driver=MAIN-modbus RawPath=pymodbus/plc/Probe5
```
`/hosts` then rendered — note every other column on the `pymodbus` row reads perfectly healthy, which
is the entire point:
| Driver | Status | Errors/5 min | Last error | Last read | **Tags** | Chip |
|---|---|---|---|---|---|---|
| `pymodbus` | HEALTHY | 0 | — | advancing | **3 / 13 SKIPPED** | `chip-warn` (amber) |
| `sql-oracle-fixture` | HEALTHY | 0 | — | advancing | **1 / 1 SKIPPED** | `chip-bad` (red) |
| `sql-postgres-fixture` | HEALTHY | 0 | — | advancing | **1 / 1 SKIPPED** | `chip-bad` (red) |
| `gate-modbus-renamed` | HEALTHY | 0 | — | advancing | **1 / 1 SKIPPED** | `chip-bad` (red) |
| `abcip-browse` | HEALTHY | 0 | — | advancing | 5 tags | none |
| `adsfa` (Calculation) | HEALTHY | 0 | — | — | 0 tags | none |
| `opcua1` | FAULTED | 1 | (config error) | — | — | none |
| `rtu-gate` | FAULTED | 1 | Connection refused | — | — | none |
Tooltip on the amber chip, verbatim:
> 3 of 13 authored tag(s) are not being polled. They report BadNodeIdUnknown and the driver's state
> does not reflect them. pymodbus/plc/Probe3: TagConfig did not map to a definition ·
> pymodbus/plc/Probe4: … · pymodbus/plc/Probe5: …
and on a red one:
> This driver is polling NONE of its 1 authored tag(s). …
**Three of the four skipping drivers were not planted.** `sql-oracle-fixture`, `sql-postgres-fixture`
and `gate-modbus-renamed` were already misconfigured on this rig and had been silently skipping their
tags for an unknown length of time, each reporting Healthy with zero errors. The column surfaced them
on its first run — an unplanned but fairly direct demonstration of the defect being real rather than
theoretical.
Restoring the three blobs and redeploying returned `pymodbus` to `13 tags` with no chip, which also
exercises the clear-on-clean-rebuild path live.
## 4. Defect the gate found — `0 tags` on a driver that never built a table
The first pass rendered **`0 tags`** for `opcua1` and `rtu-gate`. Both are FAULTED, both have **two
authored tags** in the ConfigDb, and neither ever completed `InitializeAsync` — so their ledgers had
never committed and `Snapshot()` returned `SkippedTagReport.Empty`.
A zero report is a **positive claim** — *"this driver skipped nothing"* — and making it on behalf of a
driver that never got as far as looking is precisely the quiet inaccuracy #541 exists to remove. Not
caught by unit tests because every one of them drove a driver through a completed build first.
Fixed by making `ISkippedTagReporter.GetSkippedTags()` and `SkippedTagLedger.Snapshot()` return
**null until the first committed build**, so the column shows the same em-dash it already used for a
driver that cannot report at all. Both are *no answer*; neither is *nothing skipped*. Pinned by three
new `SkippedTagLedgerTests` cases plus a corrected FOCAS assertion. Re-gated on a rebuilt image: both
faulted drivers now render `—`, while `adsfa` — which genuinely has zero authored tags and **did**
build — correctly still renders `0 tags`. That pair is the discriminating case.
## 5. Rig left as found
The three `pymodbus` blobs were restored from the pre-change backup and MAIN redeployed; `/hosts`
shows `13 tags`. The three pre-existing skipping drivers were left exactly as they were — they are the
rig's own configuration, not this gate's.
## Not proven here
- The `+N more not shown` truncation note (needs a deployment skipping more than
`SkippedTagLedger.MaxSample` = 20 tags; unit-covered only).
- The central-side proto path — the rig's central pair is fused admin+driver, so the health snapshot
never crossed the Phase 5 gRPC telemetry stream. `TelemetryProtoMapCentral`/`Node` are unit-covered
round-trip only.