|
| 1 | +# Dependency-bump triage — bincode 3, rand 0.10, hkdf 0.13 |
| 2 | + |
| 3 | +**Date:** 2026-06-03 |
| 4 | +**Status:** landed |
| 5 | +**PRs:** #559 (bincode), #558 (rand), #555 (hkdf), #404 (feedback feature — flagged, not a bump) |
| 6 | + |
| 7 | +## Summary |
| 8 | + |
| 9 | +Three open Dependabot major-version bumps were evaluated for merge against |
| 10 | +current `main`. **All three are correctly held, not merged** — each is blocked |
| 11 | +by a hard constraint, not a fixable lint: |
| 12 | + |
| 13 | +| PR | Bump | Verdict | Blocker | |
| 14 | +|----|------|---------|---------| |
| 15 | +| #559 | bincode 1.3 → 3.0 | **Hold (pin 1.x)** | Canonical signed+hashed event encoding — format break invalidates the DAG | |
| 16 | +| #555 | hkdf 0.12 → 0.13 | **Hold** | Needs `sha2` 0.11, which only exists as `0.11.0-rc.5` (pre-release) | |
| 17 | +| #558 | rand 0.8 → 0.10 | **Hold** | `willow-crypto` is pinned to `rand_core` 0.6 by `x25519-dalek` 2 + `chacha20poly1305` 0.10 | |
| 18 | + |
| 19 | +A fourth red PR, **#404**, is *not* a dependency bump — it is a full feature |
| 20 | +crate (`crates/feedback/`, ~20 files). It is triaged separately at the bottom. |
| 21 | + |
| 22 | +All three Dependabot branches were 200–250 commits behind `main`, so their CI |
| 23 | +red was partly stale. Each bump was re-applied to current `main` and built |
| 24 | +locally to get an accurate verdict; the blockers below reproduce on today's tree. |
| 25 | + |
| 26 | +## #559 — bincode 1.3 → 3.0: format-stability boundary |
| 27 | + |
| 28 | +bincode's byte encoding is **the canonical representation of a signed event**, |
| 29 | +not an interchangeable serializer: |
| 30 | + |
| 31 | +- `crates/state/src/event.rs:600-602` — `bincode::serialize(&signable)` produces |
| 32 | + the bytes that are SHA-256'd into the `EventHash` *and* Ed25519-signed. The |
| 33 | + `EventHash` **is** the event's identity (`event.rs:547`). |
| 34 | +- `crates/state/src/event.rs:520-535` — `EventKind::discriminant()` depends on |
| 35 | + bincode 1.x encoding an enum variant index as a fixed-width little-endian |
| 36 | + `u32`. A sync test (`discriminant_matches_bincode_variant_index_low_byte`) |
| 37 | + pins this. |
| 38 | +- `crates/transport/src/lib.rs:159,182` — bincode is the wire framing. |
| 39 | +- bincode is also the on-disk encoding for persisted state (storage crate). |
| 40 | + |
| 41 | +bincode 2/3 changes the default encoding (fixed-int → varint, endianness) **and** |
| 42 | +removes the free `serialize`/`deserialize` functions (now `bincode::serde::*` |
| 43 | +with an explicit config). The encoding change alone re-hashes every event: |
| 44 | +existing `EventHash`es no longer match, old signatures no longer verify, the |
| 45 | +per-author DAG chain (`prev`/`deps` by hash) breaks, persisted state is |
| 46 | +unreadable, and peers on different bincode majors cannot interoperate. |
| 47 | + |
| 48 | +Moving to bincode 2/3 is therefore a deliberate **protocol-version migration** |
| 49 | +(canonical-encoding decision + format-version field + migration path), not a |
| 50 | +Dependabot auto-bump. **Decision: pin bincode 1.x.** Revisit only behind a |
| 51 | +spec'd protocol-version change. |
| 52 | + |
| 53 | +## #555 — hkdf 0.12 → 0.13: blocked on pre-release RustCrypto |
| 54 | + |
| 55 | +`willow-crypto` sits on one coherent RustCrypto generation: `sha2` 0.10 + |
| 56 | +`hkdf` 0.12 + `hmac` 0.12 (all `digest` 0.10), alongside `chacha20poly1305` 0.10 |
| 57 | +and `x25519-dalek` 2. |
| 58 | + |
| 59 | +hkdf 0.13 pulls `hmac` 0.13 / `digest` 0.11, so `Hkdf::<Sha256>` then needs a |
| 60 | +`digest` 0.11 hash. The CI errors (`CoreProxy` / `HashMarker` / `FixedOutput` |
| 61 | +not satisfied for `Sha256VarCore`) are exactly that mismatch. The fix would be |
| 62 | +`sha2` 0.11 — but the registry only offers `0.11.0-rc.5`; stable is `0.10.9`. |
| 63 | +Pulling a pre-release hash crate into a security-critical path is not acceptable. |
| 64 | + |
| 65 | +**Decision: hold until the RustCrypto `digest` 0.11 generation ships stable** |
| 66 | +(`sha2`/`hmac`/`hkdf` move together). |
| 67 | + |
| 68 | +## #558 — rand 0.8 → 0.10: blocked on rand_core generation split |
| 69 | + |
| 70 | +The tree already carries `rand` 0.8.5, 0.9.4, and 0.10.1 — `willow-identity` |
| 71 | +and `willow-worker` are on 0.9 cleanly. The bump's problem is `willow-crypto` |
| 72 | +(and the bundled `willow-agent`), which use `rand` 0.8. |
| 73 | + |
| 74 | +`willow-crypto`'s `OsRng` must satisfy `rand_core` 0.6 to feed `x25519-dalek` 2 |
| 75 | +(`StaticSecret`/`EphemeralSecret`) and `chacha20poly1305` 0.10. Bumping crypto |
| 76 | +to rand 0.10 moves it to `rand_core` 0.10; rustc then can't find a `RngCore` |
| 77 | +impl those crates accept (the compiler even suggests |
| 78 | +`chacha20poly1305::aead::rand_core::RngCore`). crypto cannot leave `rand_core` |
| 79 | +0.6 until `x25519-dalek` and `chacha20poly1305` publish stable next-gen |
| 80 | +releases on `rand_core` 0.9+. |
| 81 | + |
| 82 | +**Decision: hold.** (A narrower bump of only `willow-agent`'s non-crypto RNG to |
| 83 | +0.9 is possible but is a different change than this PR, which bundles crypto.) |
| 84 | + |
| 85 | +## Tradeoffs / alternatives considered |
| 86 | + |
| 87 | +- **Force the bumps with pinned pre-release crates** (`sha2 0.11.0-rc.5`, |
| 88 | + `rand_core` shims). Rejected: pre-release crypto in a P2P security app; and a |
| 89 | + rand_core shim cannot bridge `x25519-dalek` 2's trait bounds. |
| 90 | +- **bincode 2/3 with `bincode::serde` + `legacy()` config** to preserve the 1.x |
| 91 | + encoding. Plausible *future* path, but still an API migration touching every |
| 92 | + call site and a risk to the canonical hash; out of scope for an auto-bump. |
| 93 | +- **Leave the PRs open, red.** Rejected: they sit red indefinitely and re-churn |
| 94 | + on every Dependabot run. Closing with rationale is cleaner — Dependabot |
| 95 | + re-opens automatically when a compatible version appears. |
| 96 | + |
| 97 | +## #404 — in-app feedback (NOT a dependency bump) |
| 98 | + |
| 99 | +#404 adds a full `crates/feedback/` worker crate plus worker-actor wiring and a |
| 100 | +spec/plan. Its red check is a `mio`-in-wasm build error (`crate::sys::*` |
| 101 | +unresolved on `wasm32`), most likely stale-base noise — but it is a substantial |
| 102 | +unrelated feature from a separate session, not a bump. It needs its own review |
| 103 | +and a current-base CI run before any merge decision. Triaged out of this pass. |
| 104 | + |
| 105 | +## Outcome |
| 106 | + |
| 107 | +Merged this pass (green, low-risk): #664 (relay upgrade bundle), #557 (iroh |
| 108 | +0.98.2), #556 (rmcp 1.6), #666 (taiki-e/install-action 2.80). |
| 109 | + |
| 110 | +Held with rationale (this report + per-PR comment): #559, #558, #555. |
| 111 | +Deferred for separate review: #404. |
0 commit comments