Southbound conformance: PAUSED code, eight-measure health, schema alias, renderable panels - #6
Merged
Merged
Conversation
… panels, hierarchical browse Applies the amended SOUTHBOUND.md conventions (core adapter-core-enablers train): - repoll while paused now refuses with the top-level code PAUSED instead of BAD_ARGS (wire-visible change; docs/AGENTS/DESIGN registers updated). - southbound_health emits the exact eight-measure set: writeErrors (device-path write failures only, drained on emit like readErrors; the encode step is split from the device write so caller-side errors never count) and signalsSubscribed (the served configured/polled inventory while connected, 0 while disconnected) join the previous six. - The panel trio is raised to the renderable descriptor floor: summary.rows, commandSummary.verbs (replacing fields/actions), signalGrid with signalsVerb + subscriptionsVerb (-> sb/signals) + readVerb, treeBrowser with browseVerb / mode hierarchical / rootRef / widget-level instance scope; no writeVerb. - sb/browse gains the hierarchical treeBrowser mode over the same configured inventory: presence of ref selects it, depth/maxRefs clamp to 1..4 / 1..1000, mixing with cursor/max (or depth/maxRefs without ref) is BAD_ARGS. The #/$defs/instance schema alias already landed on main (b9834ef). 130 tests pass, coverage 95.67% (gate 90%). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014iQDskU2E1HLStYHoZrSTn
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Applies the amended SOUTHBOUND.md southbound conventions (the core
adapter-core-enablerstrain) to the Modbus reference adapter. Per-item status:Checklist status
1.
PAUSEDrefusal code — MIGRATED.repollon a paused instance now refuses with top-level codePAUSEDinstead ofBAD_ARGS. This is a wire-visible breaking change: any client pinningBAD_ARGSfor the paused-repoll case must move toPAUSED. Updated together:command_service.repoll(),tests/test_commands.py,docs/reference/messaging-interface.md(error-code table +repollentry),AGENTS.mdinvariants, and theDESIGN.mdD-M2/D-M3 registers (which previously pinned the old code as the breaking-change record).2. Eight-measure
southbound_health— MIGRATED. Was six measures; now exactlyconnectionState, publishLatencyMs, pollLatencyMs, readErrors, staleSignals, reconnects, writeErrors, signalsSubscribed.writeErrors(Count, 60, drained on emit likereadErrors): DEVICE-PATH failures only.command_service._write_onenow splits the encode step from the device write, so allow-list refusals, unresolvable refs, missing values, and caller-side encode errors never count — only a write that passed validation + the allow-list and was then rejected by the device (or lost to a dead link) does. Per-entry reply granularity and theWRITE_FAILEDbatch semantics are unchanged.signalsSubscribed(Count, 1, gauge): Modbus is a polling adapter, so this is the configured/polled inventory the session serves while connected,0while disconnected (ClientMetrics.set_signals_serving, fed from the instance config indevice.py).tests/test_health.py) anddocs/reference/metrics.mdupdated in the same change.3.
#/$defs/instanceschema alias — CONFORMED-ALREADY.config.schema.jsonalready carries"instance": {"$ref": "#/$defs/device"}(landed on main in b9834ef, PR #5). No change.4. Panel descriptor floor — MIGRATED. The trio existed but was below the renderable floor (bare
signalGrid/treeBrowser,summarywith afieldskey,commandSummarywith anactionskey). Now:summary.rows(label/value),commandSummary.verbs,signalGridwithsignalsVerbandsubscriptionsVerb(both →sb/signals; the second is a descriptor-compat alias the shipped console reads — nosb/subscriptionswire verb exists) +readVerb→sb/read,treeBrowserwithbrowseVerb/mode: "hierarchical"/rootRef: "root", and widget-levelscope: "instance"on every command-backed widget. No widget advertises awriteVerb(none did before either). Kept the repo's existing view set/ids (overview/signals/diagnostics). Scope note: the diagnostics panel's pre-existingkeyValueListwidget is this repo's own extra view — kept (with an id/title), not expanded, since the floor doesn't cover it.5. Hierarchical
sb/browse— MIGRATED. The repo registered atreeBrowserpanel butsb/browseserved only pages. Added the hierarchical form per the python template reference, over the same configured inventory the paged mode serves: presence ofrefselects it;ref: "root"returns the device node withcontainsrefs to the (flat) signal inventory; a signal id is a known leaf (refs: []); an unknown ref isBAD_ARGS;depthclamps 1..4,maxRefs1..1000; mixingref/depth/maxRefswithcursor/max, ordepth/maxRefswithoutref, isBAD_ARGS. Paged behavior unchanged.Validation
pyproject.tomladdopts;python -m pytestfrom the repo's own venv with the editable siblingedgecommonslib perCLAUDE.md).Follow-ups (out of scope per the migration spec)
.../control/*topics to the UNS inbox (standing Phase-5 item) — N/A here; this adapter already serves the UNS command inbox.registerScoped/setCommandAvailability(requires a core version bump).🤖 Generated with Claude Code
https://claude.ai/code/session_014iQDskU2E1HLStYHoZrSTn