docs(archreview): R3-02 status

This commit is contained in:
Joseph Doherty
2026-08-20 11:33:56 -04:00
parent 62c5bc3aad
commit 93704f64ab
+36
View File
@@ -499,3 +499,39 @@ and the 12-item action list are in `00-OVERALL.md`.
**Round-3 plans: NOT yet written.** Next step is one plan per action-list item (R3-01…), house format, **Round-3 plans: NOT yet written.** Next step is one plan per action-list item (R3-01…), house format,
as round 2 did. as round 2 did.
---
## R3-02 — the stale-Good family (branch `fix/r3-02-stale-good-family`)
Plan: [`R3-02-stale-good-family-plan.md`](R3-02-stale-good-family-plan.md) (19 tasks; per-task red-before
evidence in that file's **Execution notes**). Closes OVERALL action item #2 — **03/S15**, **05/STAB-19**,
**05/STAB-18**, **02/S14** — by stating the quality contract once and pinning it per seam.
**Landed (T1–T18, one commit each; branched off `72329eab`, merged master `d79d51dd` mid-flight):**
| Task | What |
|---|---|
| T1 | `Core.Abstractions.InputQuality` (`WorstOf`/`IsUsable`) — the one worst-of-input rule; `ScriptedAlarmEngine.WorstInputStatus` re-pointed at it (its never-pushed skip stays alarm-local) |
| T2–T5 | **MQTT (05/STAB-18)**: initial push of cached snapshots on every (re)subscribe (plain + Sparkplug); `MqttConnection.ConnectionLost` → stale observed refs to `BadNoCommunication`, value retained; end-to-end driver test through a real socket drop; `docs/drivers/Mqtt.md` |
| T6–T10 | **03/S15**: `IOpcUaAddressSpaceSink.WriteStatuses` (status-only, value retained) + node manager + both sinks; `OpcUaPublishActor.AttributeStatusBatchUpdate`; `DriverHostActor.FanCommsLossToValueNodes`; the recovery audit (`_commsLatched` + `otopcua.driver.comms_latched_refs`); the identical-value recovery contract test + silent-resubscribe control |
| T11 | `DriverInstanceActor.PostStop` announces comms loss (gated on having reached Connected), so an operator Restart / supervision respawn latches Bad — recovery rides R3-03's re-provision |
| T12–T14 | **05/STAB-19**: mux adapter forwards the real status code; Calculation holds on Bad, propagates the worst input status, status-keyed dedup; evaluator read cache carries real status + timestamps |
| T15–T16 | **02/S14**: `IVirtualTagEvaluator` snapshot overload (default-implemented) + Roslyn pass-through; `VirtualTagActor` holds on Bad, inherits the worst input status, `(value, status)` dedup, reassert carries the status |
| T17 | The contract stated once in `docs/DriverLifecycle.md` §"The quality contract"; pointers from `Raw.md`, `Uns.md`, `ScriptEditor.md`, `drivers/Calculation.md`, `drivers/Mqtt.md`; one `CLAUDE.md` bullet |
| T18 | Full unit sweep — every project green; `Runtime.Tests` run 5× (see flake note below) |
**Client-visible behaviour changes** (called out in the docs task): value nodes of a comms-lost driver
now go **Bad with the last value retained**; MQTT tags go Bad on a broker drop rather than at the 90 s
watchdog; calc tags and virtual tags **hold** while an input is Bad and report that input's sub-code, so
a script that relied on receiving `null` for a dead input no longer runs while it is Bad.
**Test-suite state at `62c5bc3a`:** full-solution unit sweep green. `Runtime.Tests` 672 passed / 3
skipped on four separate runs; one further run showed a **single** failure whose name was lost to an
output filter — consistent with the known #500 flake profile (~13 %/run) and not reproduced in four
subsequent full runs. No pre-existing red on the base commit.
**NOT done here — T19, the live gate**, which is the merge-blocking rig session (docker-dev + the Modbus
`standard` fixture: constant HR[5] proves the force-republish, HR[100] is the positive control; plus the
deadband falsification leg, the operator-restart leg, and the MQTT retained-replay leg). Recipe in the
plan's §Live gate.