feat(control): the canonical control-method catalog (#1147)#1
Conversation
WIP: populating the canonical control-method catalog (epic #1110 T2, #1147). Co-Authored-By: Claude <noreply@anthropic.com>
Populate dig-node-control-interface with the FULL dig-node control surface as
the ONE SSOT (epic #1110 T2, closes dig_ecosystem#1147). Captures every method
from dig-node-service/src/control.rs (owned) + dig-node-core (delegated peers +
subscriptions) + the two OPEN pairing-bootstrap methods — 29 methods total,
superseding dig-rpc-protocol's partial Control-tier enum + the extension's
hand-rolled TS client.
- method.rs: ControlMethod enum (name/from_name/requires_auth/is_pairing_admin/
routing/category/summary/ALL).
- error.rs: ControlErrorCode taxonomy (-32030/-32031/-32032 + the JSON-RPC set)
+ the ControlError envelope ({code, message, data:{code, origin}}).
- envelope.rs: JSON-RPC 2.0 request/response + RequestId.
- params.rs / results.rs: a typed params struct per method (bound via ControlCall
to its method + typed result) + field-for-field result payloads.
- traits.rs: ControlClient (client-facing: build request / parse response) +
ControlHandler (node-facing: implement to serve, with a routing dispatcher).
- kats.rs: conformance KATs — golden request/response byte-vectors, the error
envelope, and an end-to-end route through a mock ControlHandler.
- SPEC.md + README (full-interface reference) filled in from the skeleton.
Coverage 95.6% lines. Version 0.1.0 -> 0.2.0 (MINOR — additive over the skeleton).
Co-Authored-By: Claude <noreply@anthropic.com>
MichaelTaylor3d
left a comment
There was a problem hiding this comment.
loop-reviewer verdict: PASS
Reviewed @ 00f39be against the live dig-node control surface (dig-node-service/src/control.rs + dig-node-core/src/lib.rs handle_rpc + meta.rs::ErrorCode). Fresh, read-only context.
Fidelity (the correctness gate) — verified method-by-method
- 29 methods, all correct. Every wire name, param field, and result shape in
method.rs/params.rs/results.rsmatches dig-node's actual handlers:- Param names cross-checked against source:
cap_bytes,store,upstream,filter,channel,until,client_name,token_id,pairing_id,store_id,peer— all exact. - Result shapes cross-checked:
status(running/service/version/commit/protocol/uptime_secs/addr/upstream/cache/…/sync),config.get,hostedStores.pin({store_id,root,pinned,fetch}),sync.trigger({store_id,root,status,size_bytes,served_root}),peers.connect/disconnect,subscribe/unsubscribe/listSubscriptions,pairing.request({pairing_id,pairing_code,expires_ms}),pairing.poll({status,token?}) — all field-for-field. control.peers.disconnectcorrectly INCLUDED (served by core, missing from the service's declaredCONTROL_METHODS— a dig-node drift tracked on #1128/T7, not a bug here).- Pairing bootstrap wire names correctly bare
pairing.request/pairing.poll(notcontrol.*), matchingmeta.rs.
- Param names cross-checked against source:
- Error registry byte-identical —
ControlErrorCodecodes (-32700/-32600/-32601/-32602/-32000/-32030/-32031/-32032), UPPER_SNAKE names, and origins (boundary/node/shell) matchmeta::ErrorCodeexactly; envelope{code,message,data:{code,origin}}matchescontrol_error. - Traits sound —
ControlCallbinds params↔method↔result at compile time;ControlHandler::dispatch→dispatch_methodroutes every method to its typed handler withMethodNotFound/InvalidParamsmapping;ControlClientbuild/parse pure. - KATs effective — golden request vectors, byte-stable golden response round-trips, error-envelope vector, and end-to-end routing through a mock handler; would catch any shape drift.
- Docs — README + SPEC document all 29 methods (name/params/result); wasm seam noted for T5 (SPEC §8).
Gates
33 unit/KAT + 1 doc-test green; cargo fmt --check clean; cargo clippy --all-targets --all-features -D warnings clean; version 0.1.0→0.2.0 (correct MINOR, additive over skeleton). Beautiful-code: forbid(unsafe_code), warn(missing_docs), narrative module docs, intent-revealing names, no cruft — reads like a book.
Non-gating note (resolved, not blocking)
ControlErrorCode omits -32004 (RESOURCE_NOT_AVAILABLE_AT_ROOT) and -32010 (UPSTREAM_ERROR) from meta::ErrorCode. This is CORRECT for a control-only crate: those are data-plane (dig.* content-read) codes; no control.* handler emits them (control errors are only -32030/31/32 + the JSON-RPC set). The module doc scopes itself to "every error code a dig-node control method emits." Intentional and defensible.
Unblocks T3 (wallet module), T5 (JS binding), T6/T7. No changes required.
Epic #1110 T2 — closes dig_ecosystem#1147.
What
Populates dig-node-control-interface with the FULL dig-node control surface as the ONE SSOT — the core deliverable of the crate. 29 methods captured, mapped 1:1 to the live dig-node surface.
Catalog (mapped to dig-node)
dig-node-service/src/control.rsCONTROL_METHODS): status, config.get/setUpstream, log.setLevel, cache.get/setCap/clear, hostedStores.list/pin/unpin/status, sync.status/trigger, updater.status/setChannel/pause/resume/checkNow, pairing.list/approve/revoke.dig-node-core/src/lib.rshandle_rpc): peerStatus, peers.connect, peers.disconnect, subscribe, unsubscribe, listSubscriptions.This is the FULL surface — NOT dig-rpc-protocol's partial Control-tier enum, and it folds in the extension's hand-rolled
controlApi.ts/cacheApi.ts/peersApi.ts. Drift note:control.peers.disconnectexists in dig-node-core but is MISSING from the service'sCONTROL_METHODSlist — the catalog includes it (T7 should reconcile the service list).Deliverables
ControlMethodenum: name/from_name/requires_auth/is_pairing_admin/routing/category/summary/ALL.ControlErrorCode(-32030/-32031/-32032 + JSON-RPC set) +ControlErrorenvelope{code, message, data:{code, origin}}— byte-identical to dig-node's meta::ErrorCode.ControlClient(client-facing: build request / parse response) +ControlHandler(node-facing: one typed method per control method + a routingdispatch).ControlCallto method + result) + field-for-field typed results.ControlHandler.Verification
cargo test: 33 unit/KAT + 1 doc = all green.cargo llvm-cov: 95.65% regions / 94.88% lines (≥80% gate).cargo fmt --checkclean;cargo clippy -D warningsclean;cargo buildclean.Version
0.1.0 → 0.2.0 (MINOR — additive over the skeleton).
Blast radius
New crate content only (skeleton → real). Producers/consumers (dig-node T7, extension/CLI/hub T8–T10, dig-rpc removal T6, JS binding T5, wallet module T3) are SEPARATE downstream tasks — this PR touches only this crate. No existing symbol edited (the skeleton's
controlplaceholder module is replaced by the real modules).Co-Authored-By: Claude