Engine Authoring Boundary
Purpose
This document closes the first M13 question: after the M12 micro-extractions, what is the
stable boundary between the shared runtime substrate and engine-local semantics?
This is an internal authoring rule, not a public framework story.
Decision
The shared runtime owns only mechanically shared durability and bounded-state substrate.
Everything that defines domain meaning stays engine-local.
That means:
- use the extracted runtime crates where the seam is already proven
- keep new engine semantics local by default
- treat any new generic abstraction above the current substrate as suspect until repeated pressure proves otherwise
What The Shared Runtime Owns Today
The shared runtime currently owns only the modules that are already shared on main.
Shared and stable enough now
allocdb-retire-queue- bounded retirement queue discipline
- no domain meaning beyond ordered retirement bookkeeping
allocdb-wal-frame- WAL frame versioning
- frame header/footer validation
- checksum verification
- torn-tail and corruption detection at the frame level
allocdb-wal-file- append-only durable file handle
- replace/rewrite discipline
- truncation and reopen behavior
What these modules are allowed to know
Only substrate concerns:
- bytes
- lengths
- checksums
- file paths and file handles
- bounded queue mechanics
- ordering and truncation discipline
These modules must not know:
- command schemas
- result codes
- resource, bucket, pool, or hold semantics
- snapshot schemas
- engine-specific invariants
What Stays Engine-Local
Each engine still owns the parts that define the database itself.
Domain contract surface
Keep local:
- command enums
- command codecs above raw frame transport
- result codes and read models
- config surfaces tied to domain semantics
Persistence schema
Keep local:
- snapshot encoding and decoding
- snapshot file wrappers while file formats still differ
- engine-specific recovery error surfaces
State machine semantics
Keep local:
- apply rules
- invariants
- derived indexes
- logical-slot effects such as refill, expiry, revoke, reclaim, or fencing
- any internal command semantics above raw WAL framing
Recovery entry points
Keep local:
- top-level recovery APIs
- replay orchestration that depends on engine-specific command decoding
- operational logging tied to one engine's semantics
Authoring Rules For Future Work
Rule 1: Start local unless the seam is already proven
When adding a new engine or engine slice:
- use the shared runtime crates only for seams already extracted
- keep new runtime-adjacent code local until at least two engines want the same thing in the same shape
Rule 2: Do not generalize state-machine APIs
Do not introduce:
- generic state-machine traits
- generic apply pipelines
- generic snapshot schemas
- generic recovery entry points
Those layers still carry domain meaning and would create abstraction debt faster than maintenance relief.
Rule 3: Extract only below the semantic line
A module is a good runtime candidate only if it can stay below the line where domain meaning starts.
Good examples:
- bytes-on-disk framing
- bounded retirement bookkeeping
- file rewrite/truncate mechanics
Bad examples:
- "generic reserve/confirm/release" APIs
- "generic bucket/pool/resource" models
- "generic engine config" layers
Rule 4: Prefer duplication over dishonest abstraction
If a candidate seam requires:
- engine-specific branches
- feature flags that mirror engine names
- generic types that only one engine can actually use
then it is not ready.
Rule 5: New extractions need multi-engine pressure
Do not extract a new runtime module unless at least one of these is true:
- the code is already mechanically identical across engines
- the same fix or improvement is landing independently in multiple engines
- a new engine authoring pass clearly pays less copy-paste by using the shared layer
Current Boundary Map
Shared runtime
allocdb-retire-queueallocdb-wal-frameallocdb-wal-file
Deferred seams
snapshot_file- deferred because the seam is still only clean inside the
quota-core/reservation-corepair
- deferred because the seam is still only clean inside the
- bounded collections beyond
retire_queue- still need proof that the common surface is stable enough
- recovery helpers above file/frame mechanics
- still too tied to engine-local replay contracts
Explicit non-goals
- no public database-building library claim yet
- no renaming the repository around framework identity
- no generic engine kit above the current substrate
Practical Consequence
A future engine author should think in this order:
- write engine-local semantics first
- consume the existing shared runtime only for proven substrate
- copy new runtime-adjacent code locally if the seam is not already explicit
- extract later only if repeated pressure proves the boundary
That keeps the repository honest:
- shared where the code is actually shared
- local where the semantics are still the database
Next Step
With this boundary in place, the next M13 step is narrower:
- write the focused runtime-vs-engine contract note
- decide whether that contract already makes a reduced-copy proof likely enough
- only then choose whether
M14still needs a full fourth-engine or can use a smaller engine slice proof