Skip to content

chore(deps)!: resolve dig-nat ^0.14 + dig-dht ^0.8 (cascade #1686) - #14

Merged
MichaelTaylor3d merged 1 commit into
mainfrom
chore/cascade-1686-dig-nat-0.14-dig-dht-0.8
Jul 27, 2026
Merged

chore(deps)!: resolve dig-nat ^0.14 + dig-dht ^0.8 (cascade #1686)#14
MichaelTaylor3d merged 1 commit into
mainfrom
chore/cascade-1686-dig-nat-0.14-dig-dht-0.8

Conversation

@MichaelTaylor3d

@MichaelTaylor3d MichaelTaylor3d commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

What changed

Bumps this crate's only two dig dependencies onto dig-nat = "0.14" and dig-dht = "0.8", and releases 0.6.0 → 0.7.0. No source file changed — this is a manifest + lockfile bump.

Why — the 0.x cascade rule

A 0.x MINOR is semver-incompatible: "0.13" means >=0.13.0, <0.14.0, so the previous requirements could never resolve the published 0.14.0 / 0.8.0. While this crate stayed on ^0.13/^0.7, dig-node's tree resolved two dig-nat and two dig-dht versions and hit a hard compile break:

error[E0308]: expected `dig_nat::relay::RelayStatus`, found `dig_nat::RelayStatus`
note: there are multiple different versions of crate `dig_nat` in the dependency graph

The 0.6.0 release was cut onto ^0.13/^0.7 before dig-nat 0.14 existed, so this second hop was unavoidable. For a 0.x dep bump, every node on every path from the dep to the final consumer must be bumped — a single un-bumped node forces duplicate resolution for the whole graph. This crate was one of the last two such nodes.

No code migration — verified, not assumed

  • dig-nat 0.14.0 is purely additive over 0.13.0. Diffing the public identifier set of src/lib.rs across the two published sources: zero removals, three additions (ChunkLensAssembler, ChunkLensError, MAX_RESOURCE_CHUNK_COUNT), plus a new RangeFrame method in src/mux.rs. Only lib.rs and mux.rs differ at all.
  • dig-dht 0.8.0's src/ is byte-identical to 0.7.0's (diff -rq reports no differences) — a manifest-only release carrying just its own dig-nat = "0.14" bump.
  • CandidateAddr is still not #[non_exhaustive], so the literal CandidateAddr { .. } construction in src/registry.rs continues to compile (no E0639).

All 61 tests pass unmodified, which is the substantive evidence that both additivity claims hold.

Version rationale — MINOR (0.6.0 → 0.7.0)

The rule: a dep bump over a re-exporting crate is breaking IFF the re-exported type is dep-OWNED; if it re-exports from a deeper crate both dep versions agree on, cargo unifies and a patch would be honest. Re-derived against the 0.14.0/0.8.0 sources rather than inherited from the prior bump:

Re-exported type Defined in Verdict
TraversalKind dig-nat src/method/mod.rs:46 dep-OWNED → breaking
ContentId dig-dht src/content.rs:36 dep-OWNED → breaking
AddressKind dig-dht src/record.rs:27 dep-OWNED → breaking
CandidateAddr dig-dht src/record.rs:58 dep-OWNED → breaking
ProviderRecord dig-dht src/record.rs:276 dep-OWNED → breaking
PeerId dig-tls src/identity.rs:16, merely re-exported through dig-nat lib.rs:93 unified → patch-only

Five of six are dep-owned → MINOR (0.x minor-position signals breaking-for-consumers). PeerId is the lone exception: dig-nat 0.13 and 0.14 both declare dig-tls = "0.3", so cargo unifies it and PeerId alone would have justified only a patch.

Correction to the 0.6.0 changelog narrative: it stated the four candidate-feed types live in "src/content.rs, src/record.rs" collectively. The actual split is ContentId in content.rs and AddressKind/CandidateAddr/ProviderRecord all three in record.rs. The ownership conclusion is unchanged; the file attribution is now precise, because a changelog carrying a loose type-identity claim becomes the rule a later cascade level cites.

Blast radius checked

This crate's public surface is unchanged in shape; only the identity of the six re-exported dep types moves (table above). Internal consumers of those types: src/registry.rs (CandidateAddr — incl. the literal construction), src/lib.rs (the re-exports), src/types.rs/engine.rs (PeerId, ContentId, TraversalKind as pure value types). The crate constructs or encodes none of dig-nat's mux wire types (RangeFrame, RangeRequest, Availability*), which is why the 0.12 #[non_exhaustive] cutover and the 0.14 chunk-lens additions cannot reach it. Downstream, the intended beneficiary is dig-node, whose duplicate-dig_nat resolution this unblocks.

Lock singularity — proven, not grepped

$ .claude/scripts/assert-lock-dep.sh dig-nat 0.14.0 Cargo.lock
OK: dig-nat resolves to exactly one version in Cargo.lock: 0.14.0

$ .claude/scripts/assert-lock-dep.sh dig-dht 0.8.0 Cargo.lock
OK: dig-dht resolves to exactly one version in Cargo.lock: 0.8.0

cargo update -p dig-nat -p dig-dht moved exactly two packages with zero transitive churn.

How verified (local, pre-CI)

  • cargo test --locked --all-features — 46 unit + 15 conformance + 0 doc, all pass, no source edits
  • cargo clippy --locked --all-targets --all-features -- -D warnings — clean
  • cargo fmt --check — clean
  • RUSTDOCFLAGS="-D warnings" cargo doc --locked --no-deps — clean
  • cargo llvm-cov nextest --locked --all --profile ci --fail-under-lines 8096.19% lines / 96.49% regions / 94.39% functions, 61 tests
  • cargo publish --dry-run --locked — packages and compiles from the packaged tarball; no [patch.crates-io] present

Refs DIG-Network/dig_ecosystem#1686

@MichaelTaylor3d
MichaelTaylor3d marked this pull request as ready for review July 27, 2026 10:11
The 0.6.0 release pinned `dig-nat = "0.13"` / `dig-dht = "0.7"` before
dig-nat 0.14 existed. A `0.x` minor is semver-INCOMPATIBLE, so `"0.13"`
means `>=0.13.0, <0.14.0` and could never resolve 0.14.0. While this
crate stayed on those requirements, dig-node's tree resolved TWO
`dig-nat` and TWO `dig-dht` versions and failed to compile:

    error[E0308]: expected `dig_nat::relay::RelayStatus`,
                  found `dig_nat::RelayStatus`
    note: there are multiple different versions of crate `dig_nat`

For a `0.x` dep bump, every node on every path from the dep to the final
consumer must be bumped; one un-bumped node forces duplicate resolution
for the whole graph. This crate is one of the last two such nodes.

No code migration was required, and that was verified at the published
sources rather than assumed: dig-nat 0.14.0's public identifier set gains
exactly `ChunkLensAssembler`, `ChunkLensError`,
`MAX_RESOURCE_CHUNK_COUNT` (plus a new `RangeFrame` method) and loses
nothing, and dig-dht 0.8.0's `src/` is byte-identical to 0.7.0's — a
manifest-only release carrying just its own `dig-nat = "0.14"` bump.
`CandidateAddr` is still not `#[non_exhaustive]`, so the literal
construction in `src/registry.rs` continues to compile.

BREAKING CHANGE: the re-exported dep types change identity for
consumers. Re-derived against the 0.14.0/0.8.0 sources rather than
inherited from the prior bump: five of the six types this crate
re-exports are dep-OWNED — `TraversalKind` (dig-nat
`src/method/mod.rs`), `ContentId` (dig-dht `src/content.rs`), and
`AddressKind` / `CandidateAddr` / `ProviderRecord` (all three in dig-dht
`src/record.rs`). `PeerId` is the lone exception: it is defined in
dig-tls `src/identity.rs` and merely re-exported through dig-nat, and
dig-nat 0.13 and 0.14 both require `dig-tls = "0.3"`, so cargo unifies
it and `PeerId` alone would have justified only a patch.

Refs DIG-Network/dig_ecosystem#1686

Co-Authored-By: Claude <noreply@anthropic.com>
@MichaelTaylor3d
MichaelTaylor3d force-pushed the chore/cascade-1686-dig-nat-0.14-dig-dht-0.8 branch from a11b68a to f9fb403 Compare July 27, 2026 10:11
@MichaelTaylor3d MichaelTaylor3d changed the title chore(deps): resolve dig-nat ^0.14 + dig-dht ^0.8 (cascade #1686) chore(deps)!: resolve dig-nat ^0.14 + dig-dht ^0.8 (cascade #1686) Jul 27, 2026
@MichaelTaylor3d
MichaelTaylor3d merged commit c3ac7e1 into main Jul 27, 2026
10 of 11 checks passed
@MichaelTaylor3d
MichaelTaylor3d deleted the chore/cascade-1686-dig-nat-0.14-dig-dht-0.8 branch July 27, 2026 10:15
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