๐Ÿšง Early alpha Under active construction. Everything here may change without notice โ€” except the appcast URL. That one's forever.

Aetower

Docs

Bincode v1 โ†’ v2 Migration Plan

Status

Open. Tracked via the RUSTSEC-2025-0141 ignore in deny.toml.

Why this exists

bincode v1 (1.3.x) is the format used for history.db snapshot blobs in aetower-persistence. Upstream has shipped v2 with breaking wire-format changes. Cargo-deny will flag bincode v1 indefinitely until either:

  1. The dependency is upgraded to v2 with an on-disk migration, or
  2. The serialization format is replaced (e.g. with postcard or serde_json for the snapshot blob).

A silent dependency bump would corrupt every user's history.db. This document exists so the ignore in deny.toml is anchored to a real plan, not a comment.

Where bincode is used

Four call sites โ€” all in rust/crates/aetower-persistence/src/lib.rs:

SiteDirectionPurpose
lib.rs:1381deserializeHot path: decode PersistedSnapshotEnvelope for format_version >= SNAPSHOT_FORMAT_VERSION (currently 2).
lib.rs:1386deserializeLegacy fallback: decode a bare SystemSnapshot for older format_version values.
lib.rs:1394serializeWrite path: encode the envelope on store_snapshot.
lib.rs:1583serializeTest fixture: produces a v1-style legacy blob to verify the fallback path still works.

SNAPSHOT_FORMAT_VERSION is incremented whenever the envelope or its contents change in a breaking way. The fallback at site 2 exists because user databases predate the envelope wrapper.

Constraints

Proposed migration

Bump SNAPSHOT_FORMAT_VERSION to 3 and introduce a new column or magic byte that identifies the new encoding, so the loader can route between formats per row rather than relying on a single global flag.

Two acceptable target encodings:

  1. postcard โ€” compact, schema-driven, serde-compatible. Smaller than v1 bincode on typical snapshots. No on-disk header changes required beyond the format-version bump.
  2. bincode v2 โ€” preserves the existing semantics but requires the new encode/decode derives and a configuration object. Less invasive in the long term; more invasive at the migration boundary.

Either way the migration runs as a background maintenance pass that rewrites a bounded number of rows per tick until all format_version < 3 rows are gone. The existing aetower-persistence maintenance plumbing (maintain_with_policy, cancellable_maintenance) already provides a model for this.

Acceptance criteria

Out of scope

Aetower is a free early-alpha download for macOS 14+ (Apple silicon).

Download for macOS