Skip to content

Scoped-commands wave: scope-driven addressing UI, keepalive instance state, pause-aware miss-detection - #13

Merged
mbreissi merged 1 commit into
mainfrom
feat/core-0.5-adoption
Jul 28, 2026
Merged

Scoped-commands wave: scope-driven addressing UI, keepalive instance state, pause-aware miss-detection#13
mbreissi merged 1 commit into
mainfrom
feat/core-0.5-adoption

Conversation

@mbreissi

Copy link
Copy Markdown
Contributor

edge-console's leg of the core 0.5.0 scoped-commands wave
(edgecommons/edgecommons docs/platform/DESIGN-scoped-commands.md, §2.3 + §6).

Closes #12

Gateway — 0.5.0 adoption

  • Builds and tests clean against the core Rust library at rust-lib/v0.5.0; Cargo.lock
    records the edgecommons bump (0.3.0 → 0.5.0). CI checks out core's default branch, whose
    HEAD is the 0.5.0 release, so no workflow change was needed.
  • No register call sites to migrate. The gateway registers no command handlers of its own
    (it is a command client), so the breaking (verb, scope, handler) registration surface
    does not reach this repo.
  • Descriptor normalization clones command entries wholesale, so the new scope field survives
    to the browser — now pinned by tests for both the array and the {"verbs": [...]} wrapper form.
  • The state keepalive's per-instance state token was being dropped by instance-status
    normalization. It is now forwarded verbatim (blank/non-string tokens excluded) — the plumbing
    D-SC-8 needs.

Protocol

  • CommandCapability.scope widens to "component" | "instance" | "both".
  • InstanceStatus gains the optional state, plus instanceState() / isPausedInstance() for
    the CONNECTING/ONLINE/BACKOFF/PAUSED vocabulary. An unknown token resolves to
    undefined, so consumers fall back to connected alone.

UI — scope-driven addressing (§2.3)

The Panel tab derives its addressing UI from each verb's declared scope, which is authoritative
over the widget-level scope markers:

Declared scope Selector Invocation
instance mounts always names the selected instance
component never involved never carries instance
both mounts, plus a Whole component option the option sends no instance
absent today's widget-scope heuristics, unchanged unchanged

"Whole component" is offered only when every instance-addressable widget in the view declares
both — offering it while a widget requires an instance would let the operator put that widget
into an addressing its verb rejects. A whole-component choice is dropped when the operator opens a
view that requires an instance.

UI — keepalive instance state (D-SC-8)

  • The Instances tab renders the state vocabulary with badge/tone mapping (online/green,
    connecting/blue, backoff/red, paused/gray), marking PAUSED as expected quiet. The panel
    instance selector shows it too.
  • Pause-aware quiet handling. Verified how miss-detection keys on instances: it does not.
    The staleness ladder (gateway Model::sweep, and fleetIssues on the client) keys on the
    component's own state keepalive, which keeps ticking while one of its connections is paused —
    so a pause cannot trip staleness, and no gate is needed there. The surface that did read a
    deliberate pause as a fault is the Health tab's aggregate connection state; it now excludes
    paused instances from the connected ratio, reports them separately, and reads an all-paused
    component as Paused rather than Disconnected.
  • Absent/unknown state keeps today's connectivity-only rendering everywhere.

Docs

reference/data-types.md (the InstanceStatus state table + a new command-capability section
documenting scope and the addressing it drives), reference/messaging-interface.md (how an
instance is addressed on a command, and what the state class carries),
explanation.md (why a pause never trips the ladder), user-guide.md (Instances and Panel tabs),
and docs/design/PHASE3-DESCRIPTOR-PANELS.md.

Validation

Gate Result
cargo test -p edge-console-gateway 79 passed (+4 new)
npm test — protocol 86 passed (+3 new)
npm test — ui 548 passed across 44 files (+19 new)
npm run coverage (90/80/85/90 thresholds) statements 93.27%, branches 84.17%, functions 92.5%, lines 95.34%
npm run lint clean
npm run build (protocol → ui → gateway) clean

…state

Adopts the core 0.5.0 scoped-commands release (DESIGN-scoped-commands.md).

Gateway
- Builds against edgecommons 0.5.0; Cargo.lock records the bump. The gateway
  registers no command handlers of its own, so the breaking (verb, scope,
  handler) registration surface needed no call-site migration.
- Descriptor normalization keeps command entries verbatim, so each verb's new
  `scope` reaches the browser; tests pin that for both the array and the
  {verbs: []} wrapper form.
- The state keepalive's per-instance `state` token is forwarded through
  instance-status normalization (it was dropped before), blank/non-string
  tokens excluded.

Protocol
- CommandCapability.scope widens to component | instance | both.
- InstanceStatus gains the optional `state`, plus instanceState() /
  isPausedInstance() for the CONNECTING/ONLINE/BACKOFF/PAUSED vocabulary;
  unknown tokens resolve to undefined so consumers fall back to `connected`.

UI
- The Panel tab derives its addressing from each verb's declared scope:
  `instance` mounts the selector and always sends the selected instance;
  `component` never involves the selector and never sends one; `both` adds an
  explicit "Whole component" option that sends no instance. A verb with no
  declared scope keeps today's widget-scope heuristics. "Whole component" is
  offered only when every instance-addressable widget in the view declares
  `both`, and is dropped when the operator opens a view that requires an
  instance.
- The Instances tab renders the keepalive state with badge/tone mapping and
  marks PAUSED as expected quiet; the instance selector shows it too.
- Pause-aware quiet handling: the console's miss-detection ladder keys on the
  component keepalive, never on instances, so a paused instance cannot trip it.
  The surface that did read a pause as a fault was the Health tab's aggregate
  connection state, which now excludes paused instances from the connected
  ratio and reports an all-paused component as Paused rather than Disconnected.
- Absent/unknown state keeps the connectivity-only rendering everywhere.

Docs: data-types (InstanceStatus state table, command-capability shape and the
addressing it drives), messaging-interface (how an instance is addressed, state
class), explanation (why a pause never trips staleness), user guide (Instances
and Panel tabs), and the Phase-3 descriptor design.
@mbreissi
mbreissi merged commit 9cd8760 into main Jul 28, 2026
2 checks passed
@mbreissi
mbreissi deleted the feat/core-0.5-adoption branch July 28, 2026 00:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Render keepalive instance state; pause-aware miss-detection

1 participant