# pack-io v0.1.0 — Scaffold

**The repository bootstrap.** v0.1.0 is the scaffolding milestone — it does not ship codec logic. What it ships is everything underneath the codec: the manifest, the lint and format profiles, the dual-license headers, the CI matrix that will gate every subsequent release, the `cargo-deny` and `cargo-audit` policies, the documentation skeleton, and one public symbol (`pack_io::VERSION`) so downstream code can already start tracking what it is compiled against.

## What is pack-io?

A compact binary wire format for Rust. It exists because no Rust crate today owns **speed + schema evolution + zero-copy deserialization** as a single coherent contract — `bincode` lacks evolution, `rkyv` needs alignment discipline at every use site, `postcard` is embedded-focused. `pack-io` combines them under a small, deterministic wire format that a reader can implement from a normative spec instead of from the source.

The common-case API is one line each direction — `encode(&value)` and `decode::<T>(&bytes)` — and that path is the fast path. Schema versions, evolution helpers, and the zero-copy view API live behind feature flags so the default build stays small.

## What's in 0.1.0

### `pack_io::VERSION` — the only public symbol today

A compile-time `&'static str` mirroring `CARGO_PKG_VERSION`. It is the one piece of public surface this release exposes — useful when a downstream needs to log or assert the codec version without parsing the manifest at runtime.

```rust
fn main() {
    println!("pack-io {}", pack_io::VERSION);
    assert!(pack_io::VERSION.starts_with("0."));
}
```

Documented with three runnable examples and covered by two unit tests plus one doctest. The constant is `const`, so it can be used in compile-time contexts:

```rust
const _: () = {
    let v = pack_io::VERSION.as_bytes();
    // pack-io stays in the 0.x line until the wire format freezes at 1.0.
    assert!(!v.is_empty() && v[0] == b'0');
};
```

### Crate-level lint and safety profile

`src/lib.rs` opts into the REPS-mandated lint set from line one — there is no "we will turn this on later" phase:

- `#![forbid(unsafe_code)]` — the safe-decode contract is enforced by the compiler, not by convention.
- `#![deny(missing_docs)]` — every public item must carry a doc comment.
- `#![deny(clippy::todo)]`, `#![deny(clippy::unimplemented)]` — no placeholder logic ships.
- `#![deny(clippy::print_stdout)]`, `#![deny(clippy::print_stderr)]`, `#![deny(clippy::dbg_macro)]` — no diagnostic noise in library code.
- `#![cfg_attr(not(feature = "std"), no_std)]` — `no_std` builds work out of the box; the default build enables `std`.
- `#![cfg_attr(docsrs, feature(doc_cfg))]` — `docs.rs` renders feature-gated APIs with the correct annotations once they land.

### Feature-flag surface (declared, populated as roadmap phases land)

| Feature  | Default | Description |
|----------|---------|-------------|
| `std`    | yes     | Standard library. Off → `no_std`. |
| `derive` | no      | `#[derive(Serialize, Deserialize)]` proc-macros. _(populated at 0.4)_ |
| `schema` | no      | Schema-versioning and evolution helpers. _(populated at 0.5)_ |
| `serde`  | no      | Optional `serde` interop shims. |

The flag set is declared now so downstream crates can wire `pack-io` into their feature graph without rewriting their `Cargo.toml` at every roadmap step. All flags are additive.

### CI workflow

`.github/workflows/ci.yml` runs the full gate on every push and PR to `main` / `dev`:

- **Test matrix** — Linux, macOS, Windows × stable, MSRV (1.85). Each combination runs `cargo fmt --check`, `cargo clippy --all-targets --all-features -- -D warnings`, `cargo test --all-features`, and `RUSTDOCFLAGS=-D warnings cargo doc --no-deps --all-features`.
- **Loom job** — a placeholder runs the `loom_codec` integration test under `RUSTFLAGS=--cfg loom`; once the codec lands in `0.2` this will model-check the stateless decoder for race-condition coverage.
- **Security job** — `cargo audit` against the RustSec advisory database, and `cargo deny check` against the project's licence / source / version-ban policy.

All gates are green at this tag on every matrix cell.

### Supply-chain policy

`deny.toml` allows the MIT / Apache-2.0 family plus the standard permissive licences a foundational crate is likely to encounter (BSD-2/3-Clause, ISC, Unicode-3.0 / DFS-2016, Zlib, MPL-2.0, CC0-1.0, 0BSD). Unknown registries and unknown git sources are denied. Wildcard versions are denied. Duplicate-major-versions are warned, not denied — common in transitive trees and a hard `deny` here would be noise without value.

### Benchmark target

`benches/codec_bench.rs` ships as a placeholder Criterion harness that benchmarks the `VERSION` constant lookup. It exists so the `[[bench]]` entry in `Cargo.toml` builds cleanly on every roadmap phase; real encode / decode microbenchmarks land alongside the codec in `0.2`. The placeholder is intentionally trivial — it is not a comparative claim.

### Documentation

- [`README.md`](https://github.com/jamesgober/pack-io/blob/main/README.md) — positioning against `bincode` / `rkyv` / `postcard`, the Tier-1 / Tier-2 / Tier-3 layering, the invariant list, the roadmap snapshot, and the full local pre-merge checklist.
- [`docs/API.md`](https://github.com/jamesgober/pack-io/blob/main/docs/API.md) — reference for `pack_io::VERSION`, the target Tier-1 / Tier-2 / Tier-3 surface (each item marked _planned: vX.Y_), the schema-evolution attribute surface, the error enum, the feature-flag table, and the cross-platform notes.
- [`CHANGELOG.md`](https://github.com/jamesgober/pack-io/blob/main/CHANGELOG.md) — Keep a Changelog 1.1.0 format, with proper version links.

## Invariants (held from this release)

These are the contract the codec is being built to. They hold today (vacuously — there is no codec yet) and continue to hold for every release in the `0.x` series:

- **Round-trip integrity** — `decode(encode(v)) == v` for every supported type, under any input.
- **Determinism** — the same value always produces the same bytes; no map-iteration-order leaks, no time-dependence, no platform-dependence.
- **Safe decode** — no panic, no unbounded allocation, no read past input, on any byte sequence.
- **Wire-format stability** — frozen at `1.0`; any `1.x` decoder reads any `1.x`-or-earlier encoding.

The first three are enforced by the `proptest` round-trip / determinism / adversarial-decode harnesses that land alongside the codec in `0.2`. The fourth is enforced by the wire-format normative document at `0.3` and the API freeze at `0.7`.

## Breaking changes

**None.** This is the first release.

## Verification

Run on Windows x86_64, Rust stable + 1.85 (MSRV); identical commands pass on Linux (WSL2 Ubuntu) and via the configured CI matrix on macOS:

```bash
cargo fmt --all -- --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-features
cargo build --no-default-features            # no_std build
RUSTDOCFLAGS="-D warnings" cargo doc --no-deps --all-features
cargo audit
cargo deny check
```

All green. Test counts at this tag:

- Default features: **2 unit tests** + **1 doctest**.
- All features (`--all-features`): **2 unit tests** + **1 doctest**.
- `no_std` build (`--no-default-features`): compiles clean.

## What's next

- **0.2.0 — Foundation.** Public types (`Encoder`, `Decoder`, `Serialize`, `Deserialize`, `SerialError`). Tier-1 `encode` / `decode` over primitive types (integers as varints, bool, deterministic-canonical f32/f64, `String`, `Vec<u8>`, fixed-size arrays, tuples, `Option`, `Result`). Round-trip + determinism + adversarial-decode `proptest` for every primitive.

## Installation

```toml
[dependencies]
pack-io = "0.1"

# no_std build:
pack-io = { version = "0.1", default-features = false }
```

MSRV: Rust 1.85 (2024 edition).

## Documentation

- [README](https://github.com/jamesgober/pack-io/blob/main/README.md)
- [API Reference](https://github.com/jamesgober/pack-io/blob/main/docs/API.md)
- [CHANGELOG](https://github.com/jamesgober/pack-io/blob/main/CHANGELOG.md)

---

**Initial release.**
**Changelog:** [`CHANGELOG.md`](https://github.com/jamesgober/pack-io/blob/main/CHANGELOG.md#010---2026-05-28).
