Files
settled-reach/docs/architecture/sprint-36-bincode-audit.md
T
jpmschweitzerandClaude Sonnet 4.6 e11a9c308a feat(engine): generate_brands pipeline — 10K minor brands from templates (#829)
New generate_brands binary reads 126 brand archetype templates
(wiki/economics/archetypes/brand_templates.toml), assigns halo+volume pairs
to all 48 hand-authored corps, outputs wiki/economics/corporations/generated_brands.toml.

Result: 10,000 brand_product rows, 26,750 brand_inputs, all 48 corps covered.
Brand structural validation V-B01..V-B06 passes. Generated file is gitignored
(regenerated on each `make economy-db` run).

make economy-db now runs generate-brands before import_economics.py.
import_economics.py merges generated_brands.toml alongside hand-authored brands.toml.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 13:15:03 +02:00

177 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Bincode v1 → v2 Migration — Risk Audit (Sprint 36)"
description: "Audit of bincode usage in the server crate, risk assessment, and migration recommendation for ticket #636."
type: architecture
status: final
ticket: "#636"
author: "Tyre"
created: 2026-04-19
updated: 2026-04-19
---
# Bincode Migration — Risk Audit
**Ticket:** #636 (Migrate bincode v1.x to v2.x)
**Advisory:** RUSTSEC-2025-0141 (bincode v1.3.3 unmaintained)
**Author:** Tyre
**TL;DR:** **bincode is an orphan dependency — nothing in the server crate actually calls it. Remove it outright. The "migration" is a four-line change.**
---
## 1. What the audit found
Grep-audit of the **entire repository**, not just `server/src/`:
```bash
grep -rn "use bincode\|bincode::" server/ tests/ tooling/ --include="*.rs"
# → 0 hits
```
Cargo manifest references:
```bash
grep -rn "bincode" server/ --include="*.toml" --include="*.lock"
# → server/Cargo.toml:19 bincode = "1"
# → server/Cargo.lock:329 [[package]] name = "bincode" version = "1.3.3"
# → server/Cargo.lock:1311 " bincode"," — under settled-reach-server deps
# → server/audit.toml:6 ignore = ["RUSTSEC-2025-0141"]
```
No Rust source file in **any** crate (`server/`, `tests/`, `tooling/`) contains the string `bincode`. The lockfile entry under `tooling/test-client` shows bincode transiting through `rmp-serde` or a sibling — **not** from direct use.
**Conclusion:** `bincode = "1"` in `server/Cargo.toml` was added in anticipation of save-load / Rust-Rust sync (see `docs/workshops/v01-gap-analysis/round1-tyre.md`, `docs/workshops/save-load-architecture/workshop-brief.md`) but **the implementation path chose `rmp-serde` / MessagePack instead** (see `server/src/bridge/types.rs` — tests use `rmp_serde::to_vec_named` and `rmp_serde::from_slice`, line 1052 onward).
Bincode is a dead dependency.
## 2. Recommended migration: DELETE, don't bump
### 2.1 The actual changes
**server/Cargo.toml** — remove line 19:
```diff
-bincode = "1"
```
**server/audit.toml** — remove the ignore (lines 59):
```diff
-[advisories]
-# RUSTSEC-2025-0141: bincode v1.3.3 is unmaintained.
-# Migration to bincode v2 or an alternative is tracked in ticket #636.
-# This ignore can be removed once #636 is resolved.
-ignore = ["RUSTSEC-2025-0141"]
```
(If removing the whole `[advisories]` section leaves `audit.toml` empty, either delete the file or leave the file with just a header comment — check `.config/cargo-audit/` or the Makefile for how `cargo audit` is invoked.)
**server/Cargo.lock** — regenerate by running `cargo check` in `server/`. Verify `bincode` no longer appears.
### 2.2 Verification
```bash
# 1. No source regressions:
grep -rn "bincode" server/ tests/ tooling/ --include="*.rs"
# Expected: 0 hits.
# 2. Clean build:
cargo check --workspace --all-features
# 3. Clean tests:
cargo test --workspace
# 4. Audit is green without the ignore:
cargo audit
# Expected: no RUSTSEC-2025-0141 mention.
# 5. cargo-deny (once #726 lands):
cargo deny check
```
### 2.3 Risk assessment
| Risk | Likelihood | Impact | Mitigation |
|------------------------------------------------|------------|--------|------------|
| Hidden `use bincode` I missed | Near-zero | Build break | Covered by §2.2 step 1 grep + `cargo check` |
| Proc-macro or build.rs pulling bincode | Near-zero | Build break | No `build.rs` in server crate; no proc-macro deps use it |
| Transitive need (some crate depends on it) | Zero | N/A | Transitive deps come through lockfile without a manifest entry |
| Future save-load work expects it in manifest | Low | Re-add | If save-load lands with bincode later, re-add `bincode = "2"` then — fresh v2 install, no migration |
**All four risks are trivially mitigated. Net risk: ~0.**
---
## 3. If the team decides to keep bincode — the v1 → v2 cheat sheet
Included for completeness even though §2 is the recommendation. If save-load (#553, D-085) or a future Rust↔Rust server-sync feature decides to use bincode, adopt it fresh at v2 with these signature changes:
### 3.1 The core API difference
**v1 (current, unmaintained):**
```rust
// Relies on serde Serialize/Deserialize derives.
let bytes: Vec<u8> = bincode::serialize(&value)?;
let value: MyType = bincode::deserialize(&bytes)?;
```
**v2 (stable):**
```rust
// New "Encode"/"Decode" derives, explicit config.
use bincode::{config, encode_to_vec, decode_from_slice};
let cfg = config::standard();
let bytes: Vec<u8> = encode_to_vec(&value, cfg)?;
let (value, _used): (MyType, usize) = decode_from_slice(&bytes, cfg)?;
```
**Derive change:** v2 introduced its own `#[derive(bincode::Encode, bincode::Decode)]` traits. If the type must stay serde-compatible (required for us — we use `rmp-serde` and `ron` side-by-side), use the compat shim:
```rust
use bincode::serde::{encode_to_vec, decode_from_slice};
let bytes = encode_to_vec(&value, config::standard())?;
let (value, _) = decode_from_slice::<MyType, _>(&bytes, config::standard())?;
```
This keeps `#[derive(Serialize, Deserialize)]` as the only derives on the data types — no dual-derive required. That matters because the same types cross the MessagePack boundary via `rmp-serde`.
### 3.2 Config
v2 makes encoding config explicit. `config::standard()` uses variable-int, little-endian — matches v1 default for our types (no floats in the save shape today, so endian parity is not critical). For perfectly-byte-identical output to v1, use `config::legacy()`. **Any new adoption should use `config::standard()`** — don't inherit v1 quirks.
### 3.3 Known gotchas (for future reference)
- v2 does **not** auto-handle untagged serde enums in the compat layer (pre-v2.0.1); if we adopt it and hit an untagged enum, use `bincode::serde::Compat`.
- v2's `decode_from_slice` returns the byte count consumed — v1 silently ignored trailing bytes. Useful for streaming multi-message frames; irrelevant for one-shot save files.
- The `bincode::options()` builder from v1 (`with_fixint_encoding()` etc.) is gone — replaced by `config::Configuration`.
- Binary format is **not** compatible across v1 ↔ v2. Any v1-written blob is unreadable by v2. (This is moot for us — we have none.)
### 3.4 Touch points if we were actually migrating
None. Literally no source file imports or uses it.
---
## 4. For Dudley — execution checklist
1. Delete `bincode = "1"` from `server/Cargo.toml`.
2. Delete the `RUSTSEC-2025-0141` ignore block from `server/audit.toml`.
3. `cargo check --workspace` — regenerates `Cargo.lock`.
4. `cargo test --workspace` — must pass.
5. `cargo audit` — must not print RUSTSEC-2025-0141 anymore.
6. Commit:
```
fix(deps): remove unused bincode dependency (#636)
RUSTSEC-2025-0141 no longer relevant — bincode was declared but
never imported. Drop the crate and the audit ignore. Future
save-load work that wants bincode should adopt v2 fresh.
```
**Estimated effort:** ~15 minutes including verification.
## 5. What this means for docs
One doc to update: `docs/sprints/sprint-27/server.md` line 93 mentions the audit ignore. Either leave it (it's historical notes) or strike through. Not blocking.
---
**Audit status:** Complete. Recommendation: remove bincode entirely. If the team prefers "migrate now, don't remove" (symbolic commitment to the migration path), say the word and I'll spec that instead — but it costs more with zero benefit given the usage survey.