ADR-012: forked-substrate design — contract-blind boundary, fidelity posture, port deltas
Follow-through on OQ-06/ADR-011: pin the fork's structural decisions (alkstore-substrate as a vendored path-dep crate, contract-blind API boundary with contract formulas computed engine-side and pinned equivalent by the contract suite, keep-the-kept-half API fidelity for cheap cherry-picks, the W-1/W-2/dead-man's-switch/W-4 port deltas decided per item, bootstrap re-keying off error-string matching, no rename migration, deliberate upstream tracking). Consistency sweep across the doc set for the fork: annotate ADR-003/ 005/009/010 and core-contract for superseded ownership facts, fix schedule-storage table naming (ADR-009 §5, queues.md), re-key ADR-010 §6's notifications hygiene to the at-attach cap the fork scope realizes, add OQ-11 (scaffold-time residue), and complete both ADR indexes. Independent review: 0 critical, warnings addressed.
This commit is contained in:
1 parent
befbe2e714
commit
2949612e2c
18 files changed
+491
-117
No files matched your search
@@ -135,9 +135,12 @@ no-renewal/expire-sweep model is not inherited):
|
||||
in v1.
|
||||
- Explicit `fail(err)` = immediate dead-letter (honker parity; it is
|
||||
the "stop retrying this" operator). `retry` at exhausted budget =
|
||||
dead-letter. Exhaustion via reclaim = dead-letter (the pre-claim
|
||||
sweep of already-exhausted reclaimable rows is an engine-side
|
||||
laziness optimization — SQLite rides honker's; pg re-derives).
|
||||
dead-letter. Exhaustion via reclaim = dead-letter. *(The pre-claim
|
||||
sweep of already-exhausted reclaimable rows — a laziness optimization
|
||||
in both upstream lineages — is engine-side and optional; SQLite rides
|
||||
the fork's re-derivation
|
||||
([ADR-011](011-sqlite-substrate-fork.md)), pg re-derives it
|
||||
([engine-postgres.md](../engine-postgres.md)).)*
|
||||
|
||||
### 3a. QueueOpts resolution: stamped at enqueue, per job
|
||||
|
||||
@@ -166,9 +169,14 @@ need a defined attachment point, and the contract pins one:
|
||||
- SQLite realization note: honker's `claim_batch` takes one uniform
|
||||
`timeout_s` per call, while per-job stamps make deadlines row-local —
|
||||
bridging that gap (post-claim re-stamp, per-row claiming, or another
|
||||
shape) is implementation work over honker's function surface and
|
||||
rides the same OQ-06 assessment as §5's zombie fix. The *contract*
|
||||
(deadline from the job's stamp) is engine-independent either way.
|
||||
shape) was implementation work over honker's function surface and
|
||||
rode the same OQ-06 assessment as §5's zombie fix. *(Resolved
|
||||
2026-10-05: the fork fired ([ADR-011](011-sqlite-substrate-fork.md));
|
||||
the claim statement is re-derived with per-row visibility from the
|
||||
stamps, in owned
|
||||
contract-blind substrate code ([ADR-012](012-forked-substrate-design.md)
|
||||
§2).) The *contract* (deadline from the job's stamp) is
|
||||
engine-independent either way.
|
||||
|
||||
### 4. Dead-letter: move, retention = never-expire by default, no redrive API
|
||||
|
||||
@@ -209,13 +217,13 @@ maintenance entry point):
|
||||
property: an expired *processing* row whose worker died is
|
||||
unreachable by claim (predicate requires future expiry), by
|
||||
pre-claim dead-lettering (same), and by `sweep_expired` (pending
|
||||
only) — the zombie hole, a real defect found in the reference read.
|
||||
This ADR fixes it at the contract level; the Postgres engine
|
||||
enforces it directly; the SQLite engine's realization over honker's
|
||||
machinery is implementation work **contingent on OQ-06** (a
|
||||
complement over honker's function surface, or the fork fires and
|
||||
the fix lands in owned code — the concrete fork candidate the
|
||||
quality read should weigh).
|
||||
only) — the zombie hole, a real defect found in the reference read
|
||||
(D-6 in the quality read's register). This ADR fixes it at the
|
||||
contract level; the Postgres engine
|
||||
enforces it directly; the SQLite engine's realization was
|
||||
implementation work **contingent on OQ-06** — *(resolved
|
||||
2026-10-05: the fork fired ([ADR-011](011-sqlite-substrate-fork.md))
|
||||
and the both-states sweep lands in owned code.)*
|
||||
- When `dead_letter_retention_s` is set, the same sweep also deletes
|
||||
dead rows past their retention (the only sweeper dead rows ever
|
||||
have — nothing runs without a caller).
|
||||
@@ -246,9 +254,14 @@ maintenance entry point):
|
||||
**out of the contract** (ADR-008 §8's disposition, resolved here by
|
||||
disposition): the notifications table is the SQLite wake
|
||||
mechanism's *transport* detail — consumers interact with wakes, not
|
||||
rows. Its hygiene is engine-internal (capped at attach, engine-side
|
||||
maintenance cadence, engine opts) — the fix for honker's unbounded
|
||||
`_honker_notifications` growth must not become a consumer's chore.
|
||||
rows. Its hygiene is engine-internal: **an at-attach pruning cap
|
||||
(engine opts)** — the mechanism the fork scope realizes
|
||||
([ADR-011](011-sqlite-substrate-fork.md)); no cadence, ambient or
|
||||
engine-side, contradicts this section's no-ambient-sweeper bullet.
|
||||
The fix for upstream's unbounded notifications growth must not become
|
||||
a consumer's chore. *(Annotated 2026-10-05: the earlier "engine-side
|
||||
maintenance cadence" wording was wrong — nothing in the fork scope
|
||||
realizes a cadence; the at-attach cap is the pin.)*
|
||||
|
||||
### 7. Result storage: cut-flag stands
|
||||
|
||||
@@ -277,15 +290,18 @@ consumer-inventory row.
|
||||
shape and keeps `queue(name)` a name, not a DDL operation — queue
|
||||
creation is not registry-gated, per
|
||||
[ADR-009](009-scheduler-collapse.md) §5). Per-queue config storage
|
||||
is likewise unnecessary (opts stamp onto job rows, §3a).
|
||||
is likewise stamped per §3a.
|
||||
- **SQLite**: honker's `_honker_*` table family in the caller's
|
||||
database file — storage-internal per
|
||||
[ADR-008](008-contract-v1-pinning.md) §4; no new tables minted by
|
||||
this ADR (job-stamped opts ride honker's existing columns and the
|
||||
contract's stated resolution rule, no schema change needed — this
|
||||
is exactly the seam the quality read (OQ-06) assesses). The
|
||||
family's exact fate rides that read: a fork re-owns the names,
|
||||
nothing consumer-visible changes.
|
||||
[ADR-008](008-contract-v1-pinning.md) §4. *(Annotated
|
||||
2026-10-05: the expectation that job-stamped opts would ride honker's
|
||||
existing columns with no schema change was falsified by the quality
|
||||
read — no stamp columns exist in the upstream schema (D-7). The
|
||||
family's fate is resolved: the fork ([ADR-011](011-sqlite-substrate-fork.md))
|
||||
re-owns the whole family as `__alkstore_*`, and the stamp columns +
|
||||
`claimed_at` are added by the re-derivation on contract v1
|
||||
([ADR-012](012-forked-substrate-design.md) §5). Nothing
|
||||
consumer-visible changes.)*
|
||||
|
||||
### 9. Error taxonomy: no delta
|
||||
|
||||
@@ -322,9 +338,9 @@ delta this track produces.
|
||||
consumers needing audit trails build them on the tx seam.
|
||||
- Honker's zombie fix, dead-row `get_job` visibility, and per-job
|
||||
visibility stamps over the uniform-claim-timeout function surface
|
||||
require either an over-machinery complement or a fork on the SQLite
|
||||
side — the fork calculus gains concrete candidates to weigh
|
||||
(OQ-06).
|
||||
required either an over-machinery complement or a fork on the SQLite
|
||||
side — resolved by the fork ([ADR-011](011-sqlite-substrate-fork.md),
|
||||
designed in [ADR-012](012-forked-substrate-design.md)).
|
||||
- The backoff curve's 1-hour cap and jitter formula are pinned
|
||||
constants — a consumer needing a different policy uses
|
||||
`retry(err, Some(d))` per attempt (correct, but manual).
|
||||
@@ -348,6 +364,8 @@ delta this track produces.
|
||||
extends, §5's rule §9 applies, §8's dispositions §6 resolves.
|
||||
- [ADR-009](009-scheduler-collapse.md) — the collapse machinery §6's
|
||||
recipe composes with.
|
||||
- OQ-06 — the SQLite-side fork candidates (§5, §3a realization note).
|
||||
- OQ-06 — the SQLite-side fork candidates (§5, §3a realization note) —
|
||||
resolved by the fork ([ADR-011](011-sqlite-substrate-fork.md),
|
||||
designed in [ADR-012](012-forked-substrate-design.md)).
|
||||
- [queues.md](../queues.md), [core-contract.md](../core-contract.md),
|
||||
engine specs — the specs carrying this depth.
|
||||
Reference in new issue
Block a user