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>
This commit is contained in:
@@ -0,0 +1,176 @@
|
||||
---
|
||||
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 5–9):
|
||||
```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.
|
||||
Reference in New Issue
Block a user