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:
glm-5.3-flash committed 2026-10-05 05:00:55 +00:00
1 parent befbe2e714
commit 2949612e2c
18 files changed
+491 -117

No files matched your search

+20 -14
View File
@@ -26,7 +26,9 @@ made under; the ADRs carry the WHY.
write on both engines ([ADR-007](decisions/007-transactional-seam.md));
rollback drops the job row with no ghosts.
- **Exactly-once claim**: `FOR UPDATE SKIP LOCKED` (pg, POC-pinned
under 4×4 concurrency) / honker's machinery (SQLite). At-least-once
under 4×4 concurrency) / the forked substrate's single-statement
claim (SQLite, re-derived on [ADR-010](decisions/010-queue-semantics-depth.md)
§3a — [ADR-011](decisions/011-sqlite-substrate-fork.md)). At-least-once
*work*; exactly-once *processing* needs the ack + visibility model.
- **Wake-driven consumption**: the pg engine's default is LISTEN-driven
claim with a re-poll safety net; SQLite's is watcher wake with
@@ -181,11 +183,12 @@ Collapsed into queues: no `Scheduler` handle, no schedule objects.
stamped onto the enqueued job per
[ADR-010](decisions/010-queue-semantics-depth.md) §3a; the queue
mechanism's guarantees apply, no separate delivery machinery.
- Schedule storage is engine-internal (SQLite: honker's
`_honker_scheduler_tasks`; Postgres: the engine-owned schema) — not
a consumer namespace; queues are names, not registered objects, so a
schedule may target a queue nothing has claimed yet. Schedule names
validate like queue names (non-empty, reserved-prefix rejected).
- Schedule storage is engine-internal (SQLite: the forked substrate's
`__alkstore_scheduler_tasks` table; Postgres: the engine-owned
schema) — not a consumer namespace; queues are names, not registered
objects, so a schedule may target a queue nothing has claimed yet.
Schedule names validate like queue names (non-empty,
reserved-prefix rejected).
## Namespaces / schema layout (ADR-010 §8)
@@ -197,11 +200,11 @@ Collapsed into queues: no `Scheduler` handle, no schedule objects.
table** — no per-queue tables/schemas; pg-boss's partition-per-queue
opt-in is not inherited (one table + partial indexes matches honker's
proven shape and keeps `queue(name)` a name, not a DDL operation).
- **SQLite**: honker's `_honker_*` family — storage-internal
([ADR-008](decisions/008-contract-v1-pinning.md) §4); no new tables
minted by this design; the family's fate resolved with OQ-06 — the
fork ([ADR-011](decisions/011-sqlite-substrate-fork.md)) re-owns the
names (`__alkstore_*`); nothing consumer-visible changes.
- **SQLite**: the forked substrate's `__alkstore_*` table family —
storage-internal ([ADR-008](decisions/008-contract-v1-pinning.md)
§4); the fork ([ADR-011](decisions/011-sqlite-substrate-fork.md))
re-owns the names from upstream (`_honker_*`); nothing
consumer-visible changes.
- Partial indexes pinned identically on both engines: partial indexes
matching the claim hot path; dead rows outside it; single clock
source (second-precision timestamps); savepoint-guarded
@@ -209,9 +212,10 @@ Collapsed into queues: no `Scheduler` handle, no schedule objects.
## Reference material
- **honker's queue design** — the SQLite-side incumbent design
reference (`/workspace/honker`; ownership resolved by
[ADR-011](decisions/011-sqlite-substrate-fork.md) — forked, queue ops
- **honker's queue design** — the SQLite-side lineage design reference
(`/workspace/honker`; ownership resolved by
[ADR-011](decisions/011-sqlite-substrate-fork.md) — forked per
[ADR-012](decisions/012-forked-substrate-design.md), queue ops
re-derived on this design).
Full read: `docs/research/reference-honker-machinery.md` (schema,
claim/visibility/retry/dead-letter mechanics with file/line cites;
@@ -243,6 +247,8 @@ Collapsed into queues: no `Scheduler` handle, no schedule objects.
| [008](decisions/008-contract-v1-pinning.md) | Contract v1 | queue skeleton + EnqueueOpts pinned; depth was this doc's design space |
| [009](decisions/009-scheduler-collapse.md) | Scheduler collapse | queues + `schedule()` + runner; `@every`-only; boundary guarantee row |
| [010](decisions/010-queue-semantics-depth.md) | Queue depth | visibility/heartbeat rules, backoff curve, dead-letter, no-stranded-rows sweep, schema layout |
| [011](decisions/011-sqlite-substrate-fork.md) | Substrate fork | SQLite-side queue ops re-derived in owned code; `__alkstore_*` naming |
| [012](decisions/012-forked-substrate-design.md) | Fork design | contract-blind substrate boundary; fidelity posture; port deltas |
## Open Questions