Task
dig-node-control-interface declares -32000 as DispatchFailed / "DISPATCH_FAILED", a number
inside the -32000..-32019 node read/serve band that dig-rpc-protocol owns and already
assigns to ServerError / "SERVER_ERROR". Two published crates give one wire number two machine
names. Decide which declaration survives here and act on it.
The survivor is dig-rpc-protocol: SYSTEM.md designates it the error taxonomy's single source of
truth, and -32000 is in its band, not this crate's.
Evidence
This crate, v0.24.0 (published, crates.io):
src/error.rs:17 -- the module table row: | `-32000` | DispatchFailed | shell | the node failed to dispatch |
src/error.rs:53-54 -- the variant
src/error.rs:123 -- ControlErrorCode::DispatchFailed => -32000
src/error.rs:145 -- => "DISPATCH_FAILED"
src/error.rs:186 -- description
src/error.rs:235 -- present in ALL
The owner, dig-rpc-protocol 0.10.2 (published, crates.io):
src/error.rs:113 ServerError = -32000
src/error.rs:267 => "SERVER_ERROR"
src/error.rs:373 present in ALL
src/error.rs:71 -- the band table: | `-32000..-32019` | node read/serve + staging |
This crate's own normative bands are elsewhere. SPEC.md:1071-1072 documents -3204x as the
wallet band; the control-ingress band is -3203x. -32000 is not in either.
It is DORMANT, and that is the finding, not a reason to skip it
Measured across all 92 ecosystem submodules with git grep (control-tested against a known hit):
- Zero producers. Nothing anywhere mints
ControlErrorCode::DispatchFailed.
- Zero consumers. Nothing branches on it -- including
dig-app, which depends on this crate
(Cargo.toml, crates/dig-app-core/Cargo.toml).
- The three repos depending on this crate are
dig-node (dig-node-service, dig-wallet),
dig-app, and itself.
So today the declaration is vacuously harmless: the property "no client sees two names at
-32000 because of this crate" holds only because the variant is never minted. It is one call site
away from being live, and it sits in a band whose allocator cannot see it -- which is precisely the
shape that produced the -32044 incident this crate's own guard exists to catch
(dig-node/crates/dig-node-service/src/meta.rs:1310-1345: one integer meaning both "retry after a
wait" and "retrying cannot help", about money moving).
Context
Split out of DIG-Network/dig-node#496, which reconciled the OTHER half of
this: dig-node's shell published DISPATCH_FAILED at -32000 while its own read path published
SERVER_ERROR at the same number from 11 sites, so both names reached the same client on the same
port. That is fixed in dig-node by sourcing SERVER_ERROR from dig-rpc-protocol
(DIG-Network/dig-node#518). This crate is the third declaration, and it was
not visible from the dig-node side of that work.
dig-node is not blocked on this ticket -- it mints no ControlErrorCode::DispatchFailed.
Scope
Pick one, in this crate, and record the reasoning in SPEC.md:
- Remove the variant. Clean, since it has zero producers and zero consumers. It is a public
enum variant on a published 0.x crate, so removal is a compatible-in-practice but
semver-visible change -- a minor bump under 0.x rules, and every consumer's exhaustive match
on ControlErrorCode must still compile. Verify that against the three dependents above.
- Keep it but move it to a number inside a band this crate owns, if a control-plane dispatch
failure genuinely needs its own condition distinct from SERVER_ERROR. State what distinguishes
them; if nothing does, prefer (1).
Not acceptable: leaving two published crates declaring one number under two names because nothing
currently mints it. That is the state this ticket exists to end.
Evidence bar
A guard that prevents recurrence must sweep what is drawn, not a hand-maintained list -- e.g.
assert over ControlErrorCode::ALL that no code falls inside a band dig-rpc-protocol declares,
resolved from dig_rpc_protocol::ErrorCode::ALL at test time rather than from a copied table. A
gate over an enumeration can only ever check the enumeration.
Cross-links: DIG-Network/dig-node#496 ·
DIG-Network/dig-node#518 ·
https://github.com/DIG-Network/dig_ecosystem/issues/136
Task
dig-node-control-interfacedeclares-32000asDispatchFailed/"DISPATCH_FAILED", a numberinside the
-32000..-32019node read/serve band thatdig-rpc-protocolowns and alreadyassigns to
ServerError/"SERVER_ERROR". Two published crates give one wire number two machinenames. Decide which declaration survives here and act on it.
The survivor is
dig-rpc-protocol:SYSTEM.mddesignates it the error taxonomy's single source oftruth, and
-32000is in its band, not this crate's.Evidence
This crate, v0.24.0 (published, crates.io):
src/error.rs:17-- the module table row:| `-32000` | DispatchFailed | shell | the node failed to dispatch |src/error.rs:53-54-- the variantsrc/error.rs:123--ControlErrorCode::DispatchFailed => -32000src/error.rs:145--=> "DISPATCH_FAILED"src/error.rs:186-- descriptionsrc/error.rs:235-- present inALLThe owner,
dig-rpc-protocol0.10.2 (published, crates.io):src/error.rs:113ServerError = -32000src/error.rs:267=> "SERVER_ERROR"src/error.rs:373present inALLsrc/error.rs:71-- the band table:| `-32000..-32019` | node read/serve + staging |This crate's own normative bands are elsewhere.
SPEC.md:1071-1072documents-3204xas thewallet band; the control-ingress band is
-3203x.-32000is not in either.It is DORMANT, and that is the finding, not a reason to skip it
Measured across all 92 ecosystem submodules with
git grep(control-tested against a known hit):ControlErrorCode::DispatchFailed.dig-app, which depends on this crate(
Cargo.toml,crates/dig-app-core/Cargo.toml).dig-node(dig-node-service,dig-wallet),dig-app, and itself.So today the declaration is vacuously harmless: the property "no client sees two names at
-32000because of this crate" holds only because the variant is never minted. It is one call siteaway from being live, and it sits in a band whose allocator cannot see it -- which is precisely the
shape that produced the
-32044incident this crate's own guard exists to catch(
dig-node/crates/dig-node-service/src/meta.rs:1310-1345: one integer meaning both "retry after await" and "retrying cannot help", about money moving).
Context
Split out of DIG-Network/dig-node#496, which reconciled the OTHER half of
this: dig-node's shell published
DISPATCH_FAILEDat-32000while its own read path publishedSERVER_ERRORat the same number from 11 sites, so both names reached the same client on the sameport. That is fixed in dig-node by sourcing
SERVER_ERRORfromdig-rpc-protocol(DIG-Network/dig-node#518). This crate is the third declaration, and it was
not visible from the dig-node side of that work.
dig-node is not blocked on this ticket -- it mints no
ControlErrorCode::DispatchFailed.Scope
Pick one, in this crate, and record the reasoning in
SPEC.md:enum variant on a published
0.xcrate, so removal is a compatible-in-practice butsemver-visible change -- a minor bump under
0.xrules, and every consumer's exhaustivematchon
ControlErrorCodemust still compile. Verify that against the three dependents above.failure genuinely needs its own condition distinct from
SERVER_ERROR. State what distinguishesthem; if nothing does, prefer (1).
Not acceptable: leaving two published crates declaring one number under two names because nothing
currently mints it. That is the state this ticket exists to end.
Evidence bar
A guard that prevents recurrence must sweep what is drawn, not a hand-maintained list -- e.g.
assert over
ControlErrorCode::ALLthat no code falls inside a banddig-rpc-protocoldeclares,resolved from
dig_rpc_protocol::ErrorCode::ALLat test time rather than from a copied table. Agate over an enumeration can only ever check the enumeration.
Cross-links: DIG-Network/dig-node#496 ·
DIG-Network/dig-node#518 ·
https://github.com/DIG-Network/dig_ecosystem/issues/136