|
| 1 | +# Reservation Runtime Seam Evaluation |
| 2 | + |
| 3 | +## Purpose |
| 4 | + |
| 5 | +This document closes `M11-T05` by evaluating the shared-runtime boundary after the third engine |
| 6 | +proof: |
| 7 | + |
| 8 | +- `allocdb-core` |
| 9 | +- `quota-core` |
| 10 | +- `reservation-core` |
| 11 | + |
| 12 | +The question is no longer whether there is an engine family here. That is now proven strongly |
| 13 | +enough. The question is whether the repository has crossed the line from "family of engines" to |
| 14 | +"extract a reusable runtime now." |
| 15 | + |
| 16 | +## Decision |
| 17 | + |
| 18 | +Do not extract a broad shared runtime crate yet. |
| 19 | + |
| 20 | +Do prepare the first tiny internal extraction slice now. |
| 21 | + |
| 22 | +The right outcome after the third engine is: |
| 23 | + |
| 24 | +- still no `dsm-runtime` or public database-building library on `main` |
| 25 | +- still keep command surfaces, snapshot schemas, recovery entry points, and state-machine logic |
| 26 | + engine-local |
| 27 | +- now treat `retire_queue` as an immediate extraction candidate |
| 28 | +- keep `wal`, `wal_file`, and `snapshot_file` as the next likely candidates only after the first |
| 29 | + micro-extraction lands cleanly |
| 30 | + |
| 31 | +So the third engine changed the answer from "defer everything" to "defer the big runtime, but start |
| 32 | +one tiny internal extraction." |
| 33 | + |
| 34 | +## What The Third Engine Proved |
| 35 | + |
| 36 | +The engine thesis is now materially stronger than it was after `quota-core`. |
| 37 | + |
| 38 | +All three engines now demonstrate the same trusted-core discipline: |
| 39 | + |
| 40 | +- bounded in-memory hot-path structures |
| 41 | +- WAL-backed durable ordering |
| 42 | +- snapshot plus WAL replay through the live apply path |
| 43 | +- logical `request_slot` |
| 44 | +- bounded retry and retirement state |
| 45 | +- fail-closed recovery on corruption or monotonicity violations |
| 46 | + |
| 47 | +That is enough to say `allocdb` contains a real deterministic-engine family, not just one lease |
| 48 | +allocator plus one adjacent experiment. |
| 49 | + |
| 50 | +## What Is Now Mechanically Shared |
| 51 | + |
| 52 | +### `retire_queue` |
| 53 | + |
| 54 | +`retire_queue` is now the strongest extraction candidate. |
| 55 | + |
| 56 | +It is byte-identical across: |
| 57 | + |
| 58 | +- `crates/allocdb-core/src/retire_queue.rs` |
| 59 | +- `crates/quota-core/src/retire_queue.rs` |
| 60 | +- `crates/reservation-core/src/retire_queue.rs` |
| 61 | + |
| 62 | +This is the first module that is no longer just "similar." It is the same substrate in all three |
| 63 | +engines. |
| 64 | + |
| 65 | +### `wal` |
| 66 | + |
| 67 | +`wal.rs` is byte-identical between: |
| 68 | + |
| 69 | +- `crates/quota-core/src/wal.rs` |
| 70 | +- `crates/reservation-core/src/wal.rs` |
| 71 | + |
| 72 | +That is a stronger seam than `M10` had, but it is still not universal across all three engines |
| 73 | +because `allocdb-core` carries a richer record surface and recovery/reporting contract. |
| 74 | + |
| 75 | +### `wal_file` |
| 76 | + |
| 77 | +`wal_file.rs` is now extremely close between `quota-core` and `reservation-core`. |
| 78 | + |
| 79 | +The remaining delta is small and concrete: |
| 80 | + |
| 81 | +- `reservation-core` refreshes the append handle after truncation |
| 82 | +- the test fixtures differ only in engine-local payloads |
| 83 | + |
| 84 | +This is close to extractable, but still wants one more deliberate pass rather than a speculative |
| 85 | +generic crate. |
| 86 | + |
| 87 | +### `snapshot_file` |
| 88 | + |
| 89 | +The runtime discipline is effectively the same between `quota-core` and `reservation-core`. |
| 90 | + |
| 91 | +Most visible diffs are test-fixture and domain-shape differences. The remaining constructor/path |
| 92 | +surface still differs from `allocdb-core`, so this is a later extraction candidate, not the first |
| 93 | +one. |
| 94 | + |
| 95 | +## What Stayed Engine-Specific |
| 96 | + |
| 97 | +The third engine did not make these safer to extract. |
| 98 | + |
| 99 | +### Snapshot schema |
| 100 | + |
| 101 | +Do not extract the snapshot schema layer. |
| 102 | + |
| 103 | +`reservation-core` widened the divergence: |
| 104 | + |
| 105 | +- active-hold rebuild only for `held` records |
| 106 | +- deadline-based expiry semantics |
| 107 | +- hold/pool state that has nothing to do with quota buckets or lease reservations |
| 108 | + |
| 109 | +The persistence discipline is shared. The schema is not. |
| 110 | + |
| 111 | +### Recovery orchestration |
| 112 | + |
| 113 | +Do not extract the top-level recovery API yet. |
| 114 | + |
| 115 | +The replay skeleton is recognizably similar, but the third engine made the semantic hooks more |
| 116 | +obvious, not less: |
| 117 | + |
| 118 | +- overdue-hold expiry on later request slots |
| 119 | +- held-only rebuild behavior on restore |
| 120 | +- torn-tail proof around expiry boundaries |
| 121 | +- engine-specific replay and mutation contracts |
| 122 | + |
| 123 | +There may be helper seams later, but the public recovery entry points are still engine-local. |
| 124 | + |
| 125 | +### State-machine substrate above collections |
| 126 | + |
| 127 | +Do not extract state-machine traits or generic apply plumbing. |
| 128 | + |
| 129 | +The shared truth is still at the discipline level: |
| 130 | + |
| 131 | +- bounded state |
| 132 | +- deterministic apply |
| 133 | +- logical time |
| 134 | +- retry retirement |
| 135 | + |
| 136 | +The actual mutation logic diverged further: |
| 137 | + |
| 138 | +- `allocdb-core` is identity-heavy and fence-heavy |
| 139 | +- `quota-core` is arithmetic-heavy and refill-heavy |
| 140 | +- `reservation-core` is lifecycle-heavy and expiry-heavy |
| 141 | + |
| 142 | +That divergence is healthy. It means the engines are real. |
| 143 | + |
| 144 | +## Why A Broad Runtime Is Still Premature |
| 145 | + |
| 146 | +A broad extraction would still create cost too early: |
| 147 | + |
| 148 | +- more crate boundaries |
| 149 | +- more generic traits and type plumbing |
| 150 | +- more internal APIs to stabilize |
| 151 | +- more coordination every time an engine evolves |
| 152 | + |
| 153 | +The third engine improved the evidence, but not enough for a full runtime crate: |
| 154 | + |
| 155 | +- one module is now fully mechanical across all three |
| 156 | +- two to three more modules are close only within the smaller quota/reservation pair |
| 157 | +- snapshot, recovery, config, command, and state-machine layers still diverge in important ways |
| 158 | + |
| 159 | +So the right move is smaller than "extract the runtime." |
| 160 | + |
| 161 | +## Recommended Next Step |
| 162 | + |
| 163 | +Close `M11` after this readout. |
| 164 | + |
| 165 | +Then start one narrowly scoped extraction slice: |
| 166 | + |
| 167 | +1. extract `retire_queue` into one tiny internal shared crate or module |
| 168 | +2. prove that no engine behavior changes |
| 169 | +3. only after that, reassess `wal`, `wal_file`, and `snapshot_file` |
| 170 | + |
| 171 | +Do not start with: |
| 172 | + |
| 173 | +- snapshot schemas |
| 174 | +- recovery entry points |
| 175 | +- command codecs |
| 176 | +- generic state-machine traits |
| 177 | +- a public library story |
| 178 | + |
| 179 | +## Library Thesis Status |
| 180 | + |
| 181 | +The third engine strengthened the thesis, but it did not yet produce a reusable "database-building |
| 182 | +library." |
| 183 | + |
| 184 | +The honest status is: |
| 185 | + |
| 186 | +- there is now enough common substrate to justify the first tiny internal extraction |
| 187 | +- there is still not enough stable shared shape to claim a general DB-construction framework |
| 188 | + |
| 189 | +That is progress, but it is not the same thing as "the library is ready." |
0 commit comments