## Why
Resuming an ID sequence from a persisted ID requires its allocation position before shuffling. Previously, IDs stored only their salt and shuffled value.
## What changed
- Store the allocation `ordinal` in `ModelFacingId`, expose `salt()` and `ordinal()`, and derive `JsonSchema`.
- Add `ModelFacingIdGenerator::starting_at()` and `next_ordinal()` so callers can resume with the original seed and salt at the next allocation position without a generator snapshot.
## Testing
Update serialization coverage for the allocation fields and add a test that resumes from a serialized ID across the three-digit pool boundary, matching the uninterrupted sequence.
GitOrigin-RevId: 6cbb725c0bd08356c0dc5458021b9bf58a489522
## Why
Decimal IDs of up to three digits fit in a single token. Issuing shorter IDs first keeps identifiers compact in model context.
## What changed
Add `codex-utils-model-facing-id` with deterministic, seed-based ID generation. Each salt prefixes the displayed ID and derives a separate sequence from the session seed. The generator shuffles decimal pools, exhausting `000`–`999` before issuing six-digit suffixes, then expanding in groups of three digits.
Support serializable, versioned snapshots that resume at the next unissued ID, plus suffix-only formatting for protocols that supply their own prefix.
## Testing
Add integration tests for pool exhaustion, stable outputs across pool boundaries, serialization and restore, salt-based seed derivation, invalid snapshots, and wraparound after the last `u64` ordinal.
GitOrigin-RevId: 80ffbf861106980b731d34a61ca2b9448d3bbb0d