ADR-017: contract versioning — core crate's semver is the contract version (OQ-10 resolved)

This commit is contained in:
glm-5.3-flash committed 2026-10-06 07:29:09 +00:00
1 parent 8c8fec5cb8
commit eba77909a7
9 files changed
+473 -51

No files matched your search

+73 -30
View File
@@ -1,6 +1,6 @@
---
status: draft
last_updated: 2026-10-06
last_updated: 2026-10-06 (OQ-10 resolved)
---
# alkstore — Open Questions
@@ -30,15 +30,13 @@ carried-metadata keys, global-FIFO ordering row, `StreamEvent` shape,
`publish_with_key_tx`, `trim_to`); **OQ-08 resolved** (2026-10-06,
[ADR-016](decisions/016-deployment-honesty.md) — no runtime
capability surface; the honest boundary lives in compile-time engine
identity + the documented deployment matrix).
Next: **OQ-10** (versioning discipline
for contract extensions; note ADR-011 changes its substrate-side facts
for SQLite — the forked machinery lives in-tree inside the engine
crate per [ADR-013](decisions/013-fold-substrate-into-sqlite.md), so
the engine/core contract pairing is what the discipline must track;
OQ-08's resolution also narrowed its surface — no capability struct
to govern),
OQ-11 (fork follow-through items — substrate-side, non-consumer-facing).
identity + the documented deployment matrix); **OQ-10 resolved**
(2026-10-06, [ADR-017](decisions/017-contract-versioning.md) — the
core crate's semver is the contract version; four change classes
with amend-in-place terminating at first release; the pairing
tracked by manifest pin + version-stamped contract suite + docs).
Next: **OQ-11** (fork follow-through items — substrate-side,
non-consumer-facing).
Resolved questions stay listed with their resolution; they are not
deleted.
@@ -71,7 +69,8 @@ deleted.
effectively requires). Decision recorded in
[ADR-001](decisions/001-crate-split.md) — including the reasoning
that superseded the inventory's single-crate lean.
- **Cross-references**: OQ-03, OQ-10.
- **Cross-references**: OQ-03, OQ-10 (resolved —
[ADR-017](decisions/017-contract-versioning.md)).
### OQ-03: Driver story — sqlx, tokio-postgres, or per-engine drivers? *(== OQ-ST-03)*
@@ -135,7 +134,9 @@ narrowed to the pinning work its own record already scoped.)*
expiry); the scheduler row is explicitly transferred to OQ-09's
resolution. A verification backlog (core-contract.md §Verification
backlog) tracks the one-engine-pinned properties.
- **Cross-references**: OQ-01, OQ-10, OQ-09, OQ-08; OQ-13 (the one
- **Cross-references**: OQ-01, OQ-10 (resolved —
[ADR-017](decisions/017-contract-versioning.md), the discipline
these v1 extensions now fall under), OQ-09, OQ-08; OQ-13 (the one
gap the v1 pinning's own Phase 1 review found in it), OQ-12 (the
sibling depth gap — resolved, [ADR-015](decisions/015-streams-depth.md)).
@@ -270,25 +271,68 @@ narrowed to the pinning work its own record already scoped.)*
fork-scaffold task (its opening section), not before it and not as a
gate on writing it.
- **Cross-references**: OQ-08 (the contract surface the engine maps
the substrate under), OQ-10 (the engine's versioning discipline now
carries the fold's provenance duties in-tree), ADR-011, ADR-012,
ADR-013.
the substrate under), OQ-10 (the engine's versioning discipline
now carries the fold's provenance duties in-tree — and its
class-4 non-events rule is what keeps substrate cherry-picks from
being contract events;
[ADR-017](decisions/017-contract-versioning.md)), ADR-011,
ADR-012, ADR-013.
### OQ-10: How do engine crates track core-contract version changes?
### OQ-10: How do engine crates track core-contract version changes? — **RESOLVED**
- **Origin**: [overview.md](overview.md),
[ADR-001](decisions/001-crate-split.md)
- **Status**: open
- **Status**: resolved (2026-10-06, Phase 1 —
[ADR-017](decisions/017-contract-versioning.md))
- **Priority**: medium
- **Resolution**: open. The core crate's trait surface is a contract
the engine crates must track ([ADR-001](decisions/001-crate-split.md) negative consequence). What
is the versioning/sync discipline — semver-bump-only-when-
contract-changes, engines pin core ranges, a contract-compatibility
test suite the engines run against the core's trait definitions?
What happens to a released engine crate when core makes a contract
breaking change?
- **Cross-references**: OQ-04 (the contract being versioned — now
including its first post-v1 extensions, ADR-009/ADR-010), OQ-02.
- **Resolution**: Pinned by [ADR-017](decisions/017-contract-versioning.md):
**the core crate's semver is the contract version — no parallel
versioning surface** (the OQ's three candidate mechanisms compose
rather than rival: semver discipline → the change-class rule,
engine range pins → the manifest carrier, the contract suite →
the compatibility instrument). (1) One-normative-owner rule
applied to the version question: the crate is a contract artifact
and nothing else, so its version ledger *is* the contract ledger,
and its changelog cites the ADR of every contract change (no
silent contract changes — the semantic-break guard, since
guarantee-row breaks are not compiler-visible). (2) **Four change
classes**: amend-in-place (the ADR-014/015 precedent — terminates
*permanently* at the core crate's first release; ADR-009/010,
though framed "post-v1," factually fall in this class and ship in
the initial contract v1 text); additive extension (the
ADR-009/010 *shape*, post-release — core minor, row-first
discipline); breaking change (signatures *and* semantic breaks —
the act-differently measure generalized to change
classification; core major); non-events (engine-internal change —
structurally guaranteed by ADR-012 §2's contract-blind boundary:
substrate cherry-picks cannot be contract events). (3)
`#[non_exhaustive]` on the consumer-read value types (`Error`,
`StreamEvent`, `Job`, `Schedule`, `Wake`) — mechanically making
additions there minor and enforcing the catch-all matching
posture; the consumer-constructed opts structs are exempt
(non_exhaustive bans struct-literal construction), so their
field additions are breaking (class 3), priced deliberately;
trait methods stay the honest lockstep cost. (4) The pairing
tracked by three carriers of one
fact: the engine's manifest pin (`alkstore = "1.y"`), the
version-stamped contract suite (the backlog matures into the
OQ's option-(c) compatibility instrument), and engine-crate docs.
(5) **Released engines on a breaking change: nothing forced** —
the released engine serves its pinned contract majors until
archived; the new major gains its own engine line, migration is
the consumer's deliberate two-line bump; and no
default-trait-method shims to dodge adoption (the "no trait-
default drift" line, stated). Engine semver stays independent
(it versions the engine's own surface).
- **Cross-references**: OQ-04 (the contract being versioned — its
first post-v1 extensions, ADR-009/010, resolved pre-release into
contract v1's initial text), OQ-02, OQ-08 (the narrowing — no
capability struct to govern),
[ADR-011](decisions/011-sqlite-substrate-fork.md)/
[ADR-012](decisions/012-forked-substrate-design.md)/
[ADR-013](decisions/013-fold-substrate-into-sqlite.md) (the fold
that removed the substrate's versioning surface), OQ-11 (the
cherry-pick procedure governing the substrate-side non-events).
## Theme: Deployment and capabilities
@@ -448,7 +492,6 @@ narrowed to the pinning work its own record already scoped.)*
## Deferred / Blocked
None currently. Every open OQ above is actionable Phase 1 work
(versioning discipline, fork-scaffold
follow-through) with its evidence base complete — no
external arrivals are being waited on.
None currently. The one remaining open OQ above (OQ-11) is
actionable Phase 1 work (fork-scaffold follow-through) with its
evidence base complete — no external arrivals are being waited on.