From 93704f64ab5810137f9ac4533b3230ee6d24979b Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Thu, 20 Aug 2026 11:33:56 -0400 Subject: [PATCH] docs(archreview): R3-02 status --- archreview/plans/STATUS.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/archreview/plans/STATUS.md b/archreview/plans/STATUS.md index 9944f1fb..b6d80770 100644 --- a/archreview/plans/STATUS.md +++ b/archreview/plans/STATUS.md @@ -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, 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.