commonware-storage 2026.7.0

Persist and retrieve data from an abstract store.
Documentation
# Storage testing

Use the deterministic runtime's storage backend for storage tests. It permits reproducible I/O, crashes, corruption, and recovery without real disk access.

## Basic operations

```rust
#[test]
fn test_storage_operations() {
    let runner = deterministic::Runner::default();
    runner.start(|context| async move {
        let (blob, _) = context
            .open("partition_name", &0u64.to_be_bytes())
            .await
            .expect("open blob");

        blob.write_at(0, vec![1, 2, 3, 4]).await.expect("write");
        let data = blob.read_at(0, 4).await.expect("read").coalesce();
        assert_eq!(data.as_ref(), &[1, 2, 3, 4]);
        blob.sync().await.expect("sync");
    });
}
```

## Recovery and corruption

Persist data, drop the database, and initialize it again to test clean recovery. To simulate an interrupted write, resize a blob after writing it; to simulate corruption, overwrite a checksum or truncate data. Reinitialize and verify that replay recovers to the last valid item.

```rust
let (blob, size) = context.open(&partition, &name).await.unwrap();
blob.resize(size - 1).await.unwrap();
blob.sync().await.unwrap();

let journal = Journal::init(context, cfg).await.unwrap();
assert_eq!(journal.size().await.unwrap(), expected_size);
```

## What to cover

- Empty and single-item stores, maximum sizes, and offset overflow.
- Restart after a clean sync and after an unclean shutdown.
- Truncated, corrupted, and missing data.
- Multiple readers or writers and blob pruning.
- Metrics for tracked, synced, and pruned data.
- Hash-based conformance tests for intentionally stable storage formats.

Errors from mutable operations, including `put`, `delete`, and `sync`, are unrecoverable. A caller must not use that database again after such an error.