Skip to content

feat(control): DIG auto-update beacon RPC proxy (control.updater.*)#35

Merged
MichaelTaylor3d merged 1 commit into
mainfrom
feat/515-updater-rpc
Jul 14, 2026
Merged

feat(control): DIG auto-update beacon RPC proxy (control.updater.*)#35
MichaelTaylor3d merged 1 commit into
mainfrom
feat/515-updater-rpc

Conversation

@MichaelTaylor3d

@MichaelTaylor3d MichaelTaylor3d commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Summary

Beacon epic #504, work-unit #515: dig-node proxies the DIG auto-update beacon (dig-updater, v0.6.0) status/control over the existing control.* WS/HTTP surface, so the extension/hub Updates UI (#516) can drive it.

  • control.updater.status — reads the beacon's world-readable status.json (SPEC §13.2) directly off disk and returns it verbatim; a graceful {"installed": false} when absent (never an error). Read directly (not via the CLI) since this is polled frequently.
  • control.updater.setChannel / control.updater.pause / control.updater.resume — shell the elevation-gated dig-updater CLI (the node service already runs privileged, so it satisfies that elevation check the same way an Administrator/root operator would).
  • control.updater.checkNow — shells dig-updater check --now for a synchronous on-demand pass.

A thin proxy only — no beacon trust/install/verify logic is reimplemented; both the status file and every CLI --json result are forwarded as opaque JSON (the beacon's own schema-versioned wire contract is designed precisely for this). Gated by the existing #432 control-token auth (same control.* namespace, same token — zero new auth surface).

The dig-updater CLI is resolved by an absolute path — an explicit env override, else beside this running dig-node binary (the shared bin dir digstore/dig-node/dig-dns already use), else a per-OS conventional install root — never a bare name through PATH (matching the beacon's own install-path discipline, SPEC §8.3).

Blast radius checked

  • crates/dig-node-service/src/control.rsdispatch_control's match arms (new control.updater.* cases only; every existing arm/test untouched).
  • crates/dig-node-service/src/meta.rsmethods() catalogue (additive entries; openrpc_drift_guard.rs's is_shell_only already treats any control.* prefix as shell-only, so no drift-guard changes needed).
  • crates/dig-node-service/src/lib.rs — one new pub mod updater;.
  • New module crates/dig-node-service/src/updater.rs — no existing callers (net-new surface).
  • tests/server.rs — two new tests appended to the existing CONTROL-plane section; no existing test touched.

Test plan

  • Unit (src/updater.rs, 8 tests): status.json present/absent/corrupt, the default per-OS status-dir convention, param validation, binary-resolution override + missing-file handling, every mutation's NOT_SUPPORTED when no CLI resolves.
  • Wired child-process integration (tests/beacon_cli_process.rs, 6 tests): a fake_beacon_cli fixture binary (built alongside the test target, tests/fixtures/fake_beacon_cli.rs) stands in for the real dig-updater CLI's --json I/O contract — exercises a REAL spawn for setChannel/pause/resume/checkNow, plus declined and malformed-output paths.
  • Wired e2e over the real HTTP server (tests/server.rs, 2 tests): control.updater.status/checkNow without a token → -32030 UNAUTHORIZED; a full status round-trip (absent → present, forwarded verbatim) plus a real setChannel mutation against the fixture, all over the actual axum server.
  • cargo fmt --check clean, cargo clippy --all-targets --all-features -D warnings clean, full crate cargo test green (162 lib + 6 + 47 + others, 0 failures).
  • Coverage: cargo llvm-cov could not run locally (a pre-existing environment-only MSVC/CMake libz-sys build failure that reproduces identically on pristine main — not introduced by this change); CI's Linux coverage gate is unaffected. New code is exercised by 16 dedicated tests across every branch (installed/not-installed/corrupt, success/declined/malformed, missing-param).

Version bump

Minor (0.29.00.30.0) — feat: additive new RPC methods, no existing behavior changed.

Refs #515, #504.

Co-Authored-By: Claude noreply@anthropic.com

Surfaces the dig-updater beacon's status/control over the existing control.*
WS/HTTP surface (same #432 control-token auth), so the extension/hub Updates
UI (#516) can show + drive it:

- control.updater.status reads the beacon's world-readable status.json
  (dig-updater SPEC §13.2) directly off disk and returns it verbatim;
  {"installed": false} when absent (never an error).
- control.updater.setChannel / .pause / .resume shell the already
  elevation-gated dig-updater CLI (this service runs privileged, so it
  satisfies that elevation check the same way an Administrator/root
  operator would).
- control.updater.checkNow shells `dig-updater check --now` for a
  synchronous on-demand pass.

A thin proxy only — no beacon trust/install/verify logic is reimplemented.
The CLI is resolved by an absolute path (override, beside dig-node, or a
conventional install dir), never a bare name through PATH. Both the status
file and the CLI's --json output are forwarded as opaque JSON.

Tests: unit coverage for status.json present/absent/corrupt + binary
resolution + param validation (src/updater.rs); a real-child-process
integration suite against a fake_beacon_cli fixture exercising every CLI
outcome (success/declined/malformed) (tests/beacon_cli_process.rs); wired
e2e over the real HTTP server proving the auth gate + a real mutation
(tests/server.rs). SPEC.md §7.13 documents the new methods.

Closes #515.

Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d MichaelTaylor3d marked this pull request as ready for review July 14, 2026 01:04
@MichaelTaylor3d MichaelTaylor3d changed the title feat: dig-node updater RPC proxy — beacon status/control over control WS (#515) feat(control): DIG auto-update beacon RPC proxy (control.updater.*) Jul 14, 2026
@MichaelTaylor3d MichaelTaylor3d merged commit 4584e42 into main Jul 14, 2026
14 checks passed
@MichaelTaylor3d MichaelTaylor3d deleted the feat/515-updater-rpc branch July 14, 2026 01:26
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.

1 participant