Auto-prohibited ranges (#148) were previously visible only through an
internal AutoProhibitedRangeCount accessor used by tests. Production
operators had no way to see what the planner had learned without pulling
logs or inspecting driver state.
Changes:
- New public record `ModbusAutoProhibition(UnitId, Region, StartAddress,
EndAddress, LastProbedUtc, BisectionPending)` — operator-facing snapshot
shape. Lives in the addressing assembly's logical namespace alongside
the other public types.
- `ModbusDriver.GetAutoProhibitedRanges()` returns
`IReadOnlyList<ModbusAutoProhibition>` — a copy of the live prohibition
map. Lock-protected snapshot so consumers don't race with the re-probe
loop.
- RecordAutoProhibition tracks first-fire vs re-fire via the dictionary
insert path, leaving a hook to add structured logging once an ILogger
is plumbed through (currently elided to keep the constructor minimal
for testability — a future change can wire ILogger and emit a single
warning per first-fire).
Tests (1 new, additive to the 6 in ModbusCoalescingAutoRecoveryTests):
- GetAutoProhibitedRanges_Surfaces_Operator_Visible_Snapshot — confirms
the snapshot shape: empty before any failure, populated with correct
UnitId/Region/Start/End/BisectionPending after a failed coalesced read,
LastProbedUtc within the recent past.
Docs:
- docs/v2/modbus-addressing.md — new "Coalescing auto-recovery" subsection
consolidates the #148/#150/#151/#152 surface in one place. Documents
the diagnostic accessor + flags the in-process consumption pattern
(Server health endpoints today; Admin UI when an RPC channel exists).
239 + 1 = 240 unit tests green.
Caveat: the Admin UI surfacing (table render, "clear all prohibitions"
button) is intentionally NOT shipped here. Admin can't reach a live
ModbusDriver instance without a driver-diagnostics RPC channel that
doesn't exist yet — that's a larger architectural piece. For now the
data is queryable in-process by the Server's health endpoints; once an
RPC channel lands, Admin can wire the existing GetAutoProhibitedRanges
into a Blazor table without further driver changes.