ic-memory 0.10.0

Durable stable-memory allocation governance for Internet Computer canisters
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
# Changelog

## 0.10.0

This is an intentional current-format hard cut. No fallback decoder, missing-
field default, compatibility alias, or migration shim was added.

### Recovery hardening

- Fail closed when either present physical commit slot has an invalid marker or
  checksum. Recovery no longer falls back to an older generation, which could
  otherwise forget a newer allocation, retirement, or schema-history fact.
- Keep deterministic recovery for identical duplicate slots and select the
  highest generation only after every present slot validates.
- Add regressions proving a corrupt latest generation cannot roll allocation
  history back and a corrupt inactive slot cannot be silently overwritten.

### Decode and policy hardening

- Require every non-elided optional field in current durable CBOR records to be
  present. Explicit CBOR `null` remains the encoding of `None`; omission now
  fails closed instead of being interpreted as empty state.
- Apply caller-supplied default-runtime policy only to external declarations.
  The private `ic_memory.ledger.v1` allocation remains governed exclusively by
  ic-memory's internal namespace and range policy.

### State-model hard cut

- Changed `AllocationState::Retired` to
  `AllocationState::Retired { generation }` and removed the separate nullable
  `AllocationRecord::retired_generation` field and accessor. A retired record
  without a generation, or a live record with retirement metadata, is now
  unrepresentable.
- Removed the obsolete `MissingRetiredGeneration` and
  `UnexpectedRetiredGeneration` integrity errors.
- Replaced nullable diagnostic field pairs with explicit states:
  `CommitSlotDiagnostic` is now `Empty`, `Valid`, or `Invalid`;
  `CommitStoreDiagnostic::recovery` and
  `DiagnosticRangeAuthority::effective_authority` are `Result` values;
  corrupt stable-cell errors live in `DiagnosticStableCellStatus::Corrupt`;
  and `DiagnosticCheck` is now an enum carrying failure/not-run messages.
- Removed `DiagnosticCheckStatus`; `DiagnosticCheck` itself is the status.
- Replaced the current fixture set in place. Earlier pre-1.0 allocation-record
  and diagnostic shapes are intentionally rejected; there is no legacy decoder
  or in-crate migration path.

### Release checks and documentation

- Add WebAssembly test-target compilation to CI.
- Fix packaged README image and documentation links, and align recovery and
  capability wording across the safety guide and whitepaper.
- Keep stable keys and memory IDs unchanged while intentionally replacing the
  pre-0.10.0 allocation-ledger encoding.

## 0.9.0

This is an intentional hard-cut release. Removed APIs have no deprecated
forwarders, compatibility aliases, or legacy modules.

### Reduced public surface

- Removed the unused generic `AllocationSession`, `AllocationSessionError`,
  `StorageSubstrate`, and `LedgerAnchor` APIs. Persistence owners now use the
  opaque `CommittedAllocations` capability directly when authorizing their own
  storage-open path.
- Stopped exporting implementation-only physical recovery machinery:
  `ProtectedGenerationSlot`, `DualProtectedCommitStore`, `CommitSlotIndex`,
  `AuthoritativeSlot`, and `select_authoritative_slot`.
- Kept the concrete `DualCommitStore`, committed-generation DTOs, recovery
  errors, and diagnostics public for current stable-cell integrations.
- Narrowed `CommitStoreDiagnostic::from_store` to the concrete
  `DualCommitStore` instead of an extension trait.
- Added a repository-wide pre-1.0 hard-cut rule and removed redundant serde
  defaults from optional diagnostic fields so no annotation resembles an
  earlier-shape compatibility path.

### Durability clarification

- Clarified that both redundant commit slots are serialized inside one
  `ic-stable-structures::Cell` in the default runtime. ICP message execution
  provides atomic stable-memory commit and rollback; the embedded slot
  checksums provide fallback only from localized corruption when the enclosing
  record remains decodable.
- Preserved the 0.8 durable ledger, stable-cell, payload-envelope, and CBOR
  formats. Upgrading from 0.8 requires no stable-memory migration.

## 0.8.1

### Decode and ingestion hardening

- Reject trailing bytes after persisted CBOR ledger payloads and stable-cell
  ledger records instead of accepting a valid value prefix.
- Revalidate decoded `AllocationDeclaration` values when they enter the static
  declaration registry.
- Revalidate decoded `MemoryManagerAuthorityRecord` values when they enter the
  static range registry, and expose an explicit `validate()` method for other
  ingestion boundaries.
- Revalidate `AllocationRetirement` values before staging a retirement
  generation, and expose an explicit `validate()` method for decoded requests.

## 0.8.0

This is an intentional hard-cut release. It does not retain deprecated shims,
legacy macro forms, compatibility aliases, or renamed API forwarding methods.

### Breaking authority model

- Split allocation state into two distinct opaque types:
  - `ValidatedAllocations` is pre-commit validation state and cannot open
    storage. Its generation accessor is now `base_generation()`.
  - `CommittedAllocations` is the post-persistence capability accepted by
    `AllocationSession` and the default runtime's open path.
- Replaced `BootstrapCommit` with `PendingBootstrapCommit`. Generic persistence
  owners must durably write the mutated ledger record before calling
  `confirm_persisted()` to obtain `CommittedAllocations`.
- Removed `validated_allocations()`. The default runtime now exposes only
  `committed_allocations()`, published after its stable-cell write succeeds.
- Changed `AllocationSession::new` to require `CommittedAllocations` and renamed
  its state accessor from `validated()` to `committed()`.
- Renamed `RuntimeOpenError::StableKeyNotValidated` to
  `StableKeyNotCommitted`. `MemoryIdMismatch::validated_id` is now
  `committed_id`.

### Explicit authority registration

- Removed every implicit-authority form of `ic_memory_range!`,
  `ic_memory_declaration!`, and `ic_memory_key!`. Range and key declarations now
  require the same explicit stable `authority = "..."` value.
- Rejected all external `ic_memory.*` declarations and external attempts to use
  the reserved `ic-memory` authority identity.
- Replaced caller-controlled internal authority strings with private runtime
  provenance.
- Renamed `declaring_crate` fields and accessors to `authority` on static and
  diagnostic declaration APIs. No serde field alias is retained.
- Changed `StaticMemoryDeclaration::new` and
  `StaticMemoryRangeDeclaration::new` to return validation errors.

Before:

```rust,ignore
ic_memory::ic_memory_range!(start = 120, end = 129);
ic_memory::ic_memory_key!("app.users.v1", UsersStore, 120);
```

After:

```rust,ignore
ic_memory::ic_memory_range!(
    authority = "app",
    start = 120,
    end = 129,
);

ic_memory::ic_memory_key!(
    authority = "app",
    key = "app.users.v1",
    ty = UsersStore,
    id = 120,
);
```

### Manual bootstrap migration

Manual persistence owners must now make persistence confirmation explicit:

```rust,ignore
let pending = AllocationBootstrap::new(record.store_mut())
    .initialize_validate_and_commit(&genesis, declarations, &policy, committed_at)?;

persist_record(&record)?;
let committed = pending.confirm_persisted();
let session = AllocationSession::new(storage, committed);
```

Calling `confirm_persisted()` before the owning record is durably written
violates the protocol.

### Validation and storage hardening

- Validated reservation DTO invariants before invoking caller policy.
- Made `MemoryManagerRangeAuthority` deserialization validate every imported
  record and reject overlaps.
- Tightened committed ledger chronology: retirement must follow the final
  observation, schema history must begin at allocation creation, and schema
  changes cannot postdate the final observation.
- Validated retirement slot descriptors in `AllocationRetirement::new`.
- Removed all `ic_memory.*` governance allocations from published application
  capabilities while preserving them in durable ledger recovery state.

### Dependencies and packaging

- Replaced the unmaintained `serde_cbor` dependency with maintained `ciborium`.
  Current CBOR fixtures remain byte-for-byte stable without a compatibility
  decoder or legacy format path.
- Removed the `stable_structures` dependency re-export. Downstream code now
  imports `ic-stable-structures` directly.
- Reduced the published package from roughly 2.1 MiB compressed to about
  203 KiB by excluding an unused large decorative image.

---

## 0.7.5

### Runtime hardening

- Made default-runtime bootstrap return `RuntimeLockPoisoned` if the deferred
  eager-init hook queue lock is poisoned, instead of panicking.
- Made the default doctor report surface eager-init hook lock failures as a
  failed diagnostic check instead of panicking.
- Removed reachable production `expect(...)` paths from default ledger-cell
  initialization, stable-cell capacity sizing, and ledger schema-history
  staging.
- Added fallible `LedgerPayloadEnvelope::try_encode()` and used it from ledger
  commit paths so envelope length failures return `LedgerCommitError`.
- Replaced internal declaration-claim `unreachable!` arms with explicit
  validation and staging errors.

---

## 0.7.4

### Public API hygiene

- Hid constructor-bypassing fields on `AllocationRetirement`,
  `MemoryManagerAuthorityRecord`, and `SchemaMetadata`, replacing them with
  read accessors.
- Simplified `StaticMemoryRangeDeclaration::new` so the range authority comes
  only from the validated `MemoryManagerAuthorityRecord`.
- Made implementation modules private, keeping the intended public API on the
  crate root and updating exported macros to use root-level helpers.

### Code hygiene

- Centralized stable-cell ledger-record decoding for runtime reads and
  diagnostics.
- Consolidated static registry lock and sealed-state handling.
- Shared claim-conflict record lookup between validation and staging.
- Added strict unknown-field rejection to diagnostic export DTOs.
- Added a deterministic transition matrix test that checks committed ledger
  invariants across many declaration, reservation, and retirement sequences.

---

## 0.7.3

### Runtime hardening

- Kept the default runtime's internal ledger allocation in the durable ledger
  while removing it from the published/openable validated allocation set.
- Made public default-runtime opens reject `ic_memory.*` governance stable keys.
- Preflighted default ledger-cell writes so oversized records or failed stable
  memory growth return a bootstrap error before calling `Cell::set`.
- Revalidated full reservation declarations before staging reservation
  generations.
- Made static range declaration authority mismatches fail in release builds.
- Marked public error enums as non-exhaustive so future patch releases can add
  variants without breaking downstream wildcard matches.

---

## 0.7.2

### Diagnostics

- Added a default `MemoryManager` doctor report that combines stable-cell
  status, commit recovery, recovered ledger export, registered declarations,
  range authority, validation preflight, and live memory sizes.
- Documented default-runtime diagnostic behavior, including the fact that the
  doctor runs deferred `eager_init!` hooks before bootstrap and that custom
  policy diagnostics remain the framework adapter's responsibility.

---

## 0.7.1

### Diagnostics

- Added optional live backing-memory size diagnostics for allocation records,
  including a default `MemoryManager` export helper that reports each
  `VirtualMemory::size()` in WebAssembly pages and bytes.
- Added a default `MemoryManager` commit-recovery diagnostic helper that can
  inspect protected ledger slots without requiring successful bootstrap.
- Revalidated decoded `MemoryManager` range-authority records so reversed
  ranges and the `255` sentinel cannot enter imported authority tables.
- Made raw stable-cell payload decoding classify empty memory as `NotStableCell`
  instead of relying on callers to preflight it.
- Removed duplicated internal constants for diagnostic metadata bounds and
  WebAssembly page size.

---

## 0.7.0

### Whitepaper and Lean model

- Added the `ic-memory` whitepaper, covering the stable-memory allocation
  governance problem, protocol model, allocation invariants, durable commit
  protocol, operational guidance, and current non-goals.
- Added a compact Lean model for the core allocation-safety argument, including
  checked lemmas for stable-key slot uniqueness, physical-slot key uniqueness,
  retired allocation tombstones, post-commit open authority, and generation
  monotonicity.
- Added mdBook/Nix/Lake scaffolding for building the Markdown whitepaper and
  Lean model without committing a PDF artifact.

### Protocol cleanup

- Removed the current-version compatibility range abstraction and the remaining
  ledger/envelope version-routing scaffold from recovery and commit.
- Simplified the durable ledger, envelope, diagnostics, slot descriptor, and
  schema metadata shapes by dropping unused physical-format, ledger schema,
  envelope version, descriptor substrate/version, and schema-fingerprint fields.
- Made committed generation parent links mandatory, using `0` for the first
  generation instead of accepting an absent parent value.
- Refreshed the current golden wire fixtures for the cut-down durable format.

---

## 0.6.2

### Protocol mutation coverage

- Added nested CBOR unknown-field regression tests for decoded
  `AllocationHistory`, `AllocationRecord`, `AllocationSlotDescriptor`, and
  `GenerationRecord` values inside the crate-owned ledger payload.
- Added a stable-cell wrapper regression test proving unknown top-level fields
  in `StableCellLedgerRecord` decode fail closed before the record can be used
  as a ledger anchor DTO.
- Clarified `LedgerPayloadEnvelope` rustdoc: decoding the envelope classifies
  protocol bytes only and does not establish allocation authority.

---

## 0.6.1

### Audit hardening

- Added `serde(deny_unknown_fields)` to `LedgerCommitStore`, closing the last
  authority-bearing durable DTO wrapper that could otherwise ignore future
  top-level CBOR fields during rollback.
- Added a regression test that mutates the `LedgerCommitStore` CBOR shape with
  an unknown top-level field and verifies that decode fails closed.
- Added compile-fail tests that lock the public API boundary around
  `RecoveredLedger` and `ValidatedAllocations`, proving downstream safe Rust
  cannot call their crate-private constructors.
- Made late `eager_init` registration fail closed after default runtime
  bootstrap instead of silently queueing a hook that will never run.
- Clarified that explicit genesis initialization APIs are privileged
  empty-store/import paths; normal users should prefer the default runtime or
  the golden bootstrap flow.
- Improved `ic_memory_key!` open failure text so it covers missing bootstrap,
  unvalidated keys, and key/id mismatches.

---

## 0.6.0

### Protocol authority boundary

- Added a logical ledger payload envelope inside each physically committed
  generation. Physical dual-slot recovery still selects the highest valid
  committed generation first; only then does `ic-memory` decode the logical
  envelope and route the ledger payload by schema/format metadata.
- Added `RecoveredLedger` as the crate-owned proof that a ledger crossed
  physical recovery, payload-envelope routing, compatibility checks, and
  committed-integrity validation.
- Changed `validate_allocations()` to require `RecoveredLedger` instead of raw
  `AllocationLedger`, so untrusted/manual ledger DTOs cannot mint
  `ValidatedAllocations`.
- Removed the public caller-supplied compatibility range surface from normal
  recovery and commit APIs. `LedgerCommitStore` now uses the crate-owned current
  protocol path.
- Added recovery tests for payload-envelope classification, unsupported
  envelope versions, and envelope/ledger metadata drift.
- Added reviewable v1 hex wire fixtures for payload envelopes, full commit
  stores, dual-slot recovery states, stable-cell records, and slot descriptors,
  with tests that decode, validate, recover, and re-encode them.
- Marked authority-bearing durable DTO structs with `serde(deny_unknown_fields)`
  so future fields fail closed instead of being silently ignored by older
  readers.
- Removed the custom payload encoding namespace. The logical ledger payload is
  the current `ic-memory` CBOR format inside the logical envelope.
- Removed custom allocation-slot substrates from the 0.6 authority model.
  Allocation slots are `ic-stable-structures::MemoryManager` `u8` IDs only,
  with ID 255 rejected as the sentinel.
- Removed public codec selection from the commit/bootstrap path. The durable
  ledger codec is crate-owned CBOR, so downstream crates cannot introduce a
  parallel ledger format.

---

## 0.5.1

### Audit hardening

- Made `ValidatedAllocations` an opaque non-serializable capability. It no
  longer derives serde traits and can only be produced by crate validation and
  bootstrap paths.
- Added deep validation for decoded DTOs before they can become allocation
  authority. Stable-key grammar and `MemoryManager` slot descriptor invariants
  are rechecked during snapshot validation and committed-ledger integrity
  validation.
- Raised the `validate_allocations()` authority boundary so the historical
  ledger must pass current compatibility and committed-integrity validation
  before it can produce `ValidatedAllocations`.
- Added stable-cell ledger preflight for the default runtime so corrupt
  `ic-stable-structures::Cell` storage is classified as a bootstrap error
  before `Cell::init` would otherwise panic while decoding the ledger record.
- Made the default runtime range-policy contract explicit: registered
  `ic_memory_range!` claims are enforced before caller-supplied policy, while
  framework adapters can omit user ranges and enforce application space in
  their own policy.
- Pinned the default developer and CI toolchain to Rust 1.95.0 while keeping
  the crate MSRV at Rust 1.85.0 through `package.rust-version` and an MSRV CI
  check.
- Updated crates.io metadata to describe `ic-memory` as a Memory ID registry
  wrapper for `ic-stable-structures`.

---

## 0.5.0

### Runtime registration

- Added a generic multi-crate runtime registration layer for downstream crates
  such as IcyDB, including range declarations, `ic_memory_key!`,
  `ic_memory_range!`, `eager_init!`, default `MemoryManager` bootstrap, and
  validated runtime opening without Canic.
- Moved the normal documentation path to the macro-based runtime API and moved
  lower-level ledger/bootstrap guidance to `ADVANCED.md`.
- Left TLS eager initialization out of `ic-memory`; framework helpers such as
  Canic's `eager_static!` should wrap ordinary `thread_local!` values and use
  `ic_memory_key!` / `ic_memory_range!` for allocation registration.

---

## 0.4.1

### Ledger hardening

- Split allocation staging behavior into `ledger::stage`, keeping the public
  staging API stable while reducing the size of `ledger::mod`.
- Replaced saturating generation diagnostic counts with explicit fail-closed
  errors when declaration or reservation counts exceed the durable `u32` limit.
- Documented that empty validated and reservation generations are intentional
  generation boundaries.
- Documented and tested reserved-record retirement semantics.
- Documented the expected allocation-ledger size bounds behind the current
  clone-on-stage implementation.

---

## 0.4.0

### Breaking cleanup

- Bumped from the already-published `0.3.0` to `0.4.0` because this release
  removes public APIs that were redundant or unused.
- Removed the unused `NamespaceAuthority` and `RangeAuthority` policy traits.
  Direct `MemoryManagerRangeAuthority` methods are the supported range-policy
  API.
- Removed the redundant `AllocationSlotDescriptor::memory_manager_checked`
  constructor alias. Use `AllocationSlotDescriptor::memory_manager`.
- Removed the redundant `MemoryManagerRangeAuthority::to_records` export alias.
  Use `authorities()` for the stable read-only diagnostic/export surface.

### Documentation

- Clarified that `AllocationBootstrap` is the golden path for whichever layer
  owns an `ic-memory` ledger store, not specifically for Canic.
- Documented framework-owned, library-owned, and application-owned bootstrap
  modes, plus the rule that exactly one owner should bootstrap a given ledger
  store.
- Updated the README golden path to use
  `AllocationBootstrap::initialize_validate_and_commit`.

---

## 0.3.0

### Native IC substrate

- Made `ic-stable-structures = "0.7.2"` a normal dependency instead of an
  optional feature-gated dependency.
- Made `serde_cbor = "0.11"` a normal dependency.
- Removed the `ic-stable-structures` feature; `stable_cell` support now always
  compiles and its ledger-anchor exports are always available.
- Added `CborLedgerCodec` as the built-in CBOR codec for `AllocationLedger`
  commit payloads.
- Clarified that the native ledger stack is `MemoryManager` ID 0 ->
  `ic-stable-structures::Cell<StableCellLedgerRecord, _>` ->
  `LedgerCommitStore` -> dual protected committed `AllocationLedger` payloads.
- Kept collection construction out of scope: `ic-memory` governs allocation
  ownership and does not wrap every `ic-stable-structures` collection.

---

## 0.2.0

### Breaking / API hardening

- Bumped from the already-published `0.1.0` to `0.2.0` because this release
  tightens public DTO construction and hides fields that were public in
  `0.1.0`.
- Made invariant-bearing durable DTO fields private where feasible, including
  allocation declarations, ledger histories, ledger records, physical commit
  slots, and slot descriptors.
- Added checked constructors and accessors for public allocation DTOs so callers
  do not need struct literals for normal use.
- Added `AllocationLedger::new_committed` for strict committed-ledger
  construction.
- Removed the unused public generation DTO API from the crate surface.
- Gated corrupt-write simulation helpers behind `#[cfg(test)]`; production code
  can no longer call them.

### Safety and validation

- Added schema metadata validation to declaration staging, reservation staging,
  and committed-ledger integrity validation.
- Centralized historical claim-conflict detection for declaration validation,
  declaration staging, and reservation staging while preserving existing public
  error variants.
- Preserved the core invariant: a stable key cannot move physical slots, and an
  active physical slot cannot be reused by another stable key.

### Structure and maintenance

- Split `slot` internals into descriptor, `MemoryManager`, and range-authority
  modules while keeping crate-level re-exports stable.
- Split ledger records, errors, and integrity checks out of the main ledger
  module.
- Kept staging and commit behavior public-compatible; no Canic-specific policy
  was added.

### Documentation

- Updated README, crate docs, rustdoc, and SAFETY docs for the current checked
  constructor/accessor API.
- Added a concise golden-path sketch showing recovery, declaration,
  validation, commit, and only-then-open ordering.
- Clarified stable-key permanence, reservation behavior, tombstones, checksum
  limits, non-goals, and the boundary between generic `ic-memory`
  infrastructure and Canic/IcyDB examples.

---

## 0.0.7

### Documentation

- Added stable-key formatting guidance to the README, including grammar rules,
  valid examples, and namespace conventions.
- Documented representative `canic.core.*` and `icydb.*` stable-key patterns.
- Clarified that stable keys are permanent logical allocation identities and
  should not be changed when only schema metadata changes.
- Updated README examples to show the open-stack range-authority model,
  package-record composition, and optional closed-policy coverage checks.

---

## 0.0.6

### Added

- Added `MemoryManagerRangeAuthority`, `MemoryManagerAuthorityRecord`, and
  `MemoryManagerRangeMode` for generic `MemoryManager` range authority policy
  and diagnostics.
- Added range-authority builders and validators, including ID-bound helpers,
  mode-aware validation, complete coverage checks, and `from_records` for
  composing records from multiple packages.
- Added concise `MemoryManager` declaration helpers on
  `AllocationDeclaration` and `DeclarationCollector`, including labeled,
  unlabeled, schema-aware, and builder-style variants.
- Added `MemoryManagerIdRange::all_usable`.

### Changed

- Made `MemoryManagerIdRange` serializable for diagnostic authority records.
- Added explicit range-authority errors for overlaps, invalid ranges, missing
  coverage, records outside a coverage target, mode mismatch, and invalid
  diagnostic strings.
- Updated examples to use the concise `MemoryManager` range and declaration
  helpers.

### Policy model

- Clarified that range authority is policy/diagnostic metadata only; durable
  allocation remains the core `stable_key -> allocation_slot` ledger model.
- Clarified that `Reserved` and `Allowed` do not allocate IDs.
- Clarified the open-stack model: packages publish only the ranges they own, and
  a final composition layer uses `from_records` to catch cross-package overlaps.
  Final closed policies may add application `Allowed` ranges or complete
  coverage checks, but intermediate frameworks should not claim the remaining ID
  space by default.

---

## 0.0.3

- Repositioned documentation around stable-memory slot drift.
- Added safety model documentation.
- Hardened physical/logical generation recovery.
- Added strict committed-ledger lifecycle tests.
- Made `MemoryManager` slot construction checked by default.