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

+27 -12
View File
@@ -187,8 +187,8 @@ TTL-bounded coordination locks, transactional-friendly:
no-work is a value, not an error); `renew` and `release` on the
lock handle. Release on explicit unlock or TTL expiry.
Re-acquirable after expiry (POC-pinned on Postgres; on SQLite it
rests on honker's machinery — the SQLite-side pin is in the
verification backlog below).
rests on the forked substrate's lock machinery — the SQLite-side pin
is in the verification backlog below).
- **Guarantee row** ([ADR-008](decisions/008-contract-v1-pinning.md)
§7): mutual exclusion bounded by TTL + renewal — after TTL expiry
exclusion lapses *silently* (no revocation event); holders must
@@ -285,8 +285,11 @@ added by [ADR-009](decisions/009-scheduler-collapse.md) §1):
- Engine-derived names in consumer namespaces carry the reserved
prefix (the outbox's backing queue is derived under the prefix —
honker's `_outbox:{name}` scheme is not inherited verbatim).
- SQLite: honker's `_honker_*` internal table family is storage-
internal (not consumer namespace); Postgres: engine tables are
- SQLite: the substrate's `__alkstore_*` internal table family is
storage-internal (not consumer namespace) — re-owned from upstream's
`_honker_*` by the fork ([ADR-011](decisions/011-sqlite-substrate-fork.md),
designed per [ADR-012](decisions/012-forked-substrate-design.md)).
Postgres: engine tables are
schema-scoped — one engine-owned schema
([ADR-010](decisions/010-queue-semantics-depth.md) §8) — the
*channel* namespace is this section's.
@@ -297,9 +300,11 @@ Contract properties POC-pinned on one engine only (or sketched rather
than surface-verified) — the contract test suite must pin both engines
before the engine specs are called `stable`:
- **Lock TTL/expiry re-acquisition on SQLite** — pinned on Postgres
(pg POC's lock probe); on SQLite it rests on honker's machinery
unverified.
- **Named-lock TTL/expiry re-acquisition on SQLite** — pinned on
Postgres (pg POC's lock probe); on SQLite it rests on the forked
substrate's lock machinery (its `lock_renew` verified in the quality
read; the re-acquire-does-not-refresh-TTL behavior is upstream's,
inherited deliberately) — pin it in the contract suite.
- **Wake semantics under `WakeReceiver` shapes** — POCs verified
wake delivery/coalescing through their own probe types; the pinned
`Wake { channel }` / recv forms (§3 of
@@ -307,21 +312,29 @@ before the engine specs are called `stable`:
suite's own property tests on both engines.
- **`save_offset_tx` exactly-once-within-a-business-tx shape** — both
POCs verified it through their *sketch* implementations (SQLite's
offset-save was a plain SQL upsert, not the full honker surface;
offset-save was a plain SQL upsert, not the forked substrate's full
surface;
the pg side likewise through its probe), so the property must be
re-pinned against the real engines' `save_offset_tx` in the
contract suite.
- **Concurrent `try_lock` loser/error behavior** on SQLite (the pg
side returns cleanly; honker's busy-path under lock contention is
the thing to pin).
side returns cleanly; the substrate's busy-path under lock
contention is the thing to pin).
- **Scheduler + depth properties on Postgres** — the SQLite side's
tick/leader/catch-up machinery rides honker's test-pinned
implementation; the pg engine's re-derived tick (boundary advance,
tick/leader/catch-up machinery inherits the forked substrate's
test-pinned implementation; the pg engine's re-derived tick (boundary
advance,
64-cap skip-forward, leadership-loss discipline) and the
[ADR-010](decisions/010-queue-semantics-depth.md) depth properties
(visibility reclaim consuming attempts, dead-letter moves, the
no-stranded-rows sweep) pin in the contract suite at
implementation.
- **Backoff-curve and stamp-resolution equivalence across engines** —
the equal-jitter curve ([ADR-010](decisions/010-queue-semantics-depth.md)
§3) and the opts-stamping resolution (§3a) are computed engine-side
per [ADR-012](decisions/012-forked-substrate-design.md) §2's
contract-blind boundary; the contract suite must pin both engines'
arithmetic to identical outputs.
## Design Decisions
@@ -334,6 +347,8 @@ before the engine specs are called `stable`:
| [008](decisions/008-contract-v1-pinning.md) | Contract v1 pinning | surface partition, `TxHandle` trait shape, `Wake` type, reserved strings, error taxonomy, config split, locks guarantee row |
| [009](decisions/009-scheduler-collapse.md) | Scheduler collapse (post-v1 extension) | queues + `schedule()`/`run_schedules`, `@every`-only v1, boundary guarantee row |
| [010](decisions/010-queue-semantics-depth.md) | Queue depth (post-v1 extension) | visibility/renewal, opts stamping, backoff curve, dead-letter, sweep, layout |
| [011](decisions/011-sqlite-substrate-fork.md) | Substrate fork | SQLite substrate owned (`__alkstore_*` naming); queue ops re-derived on contract v1 |
| [012](decisions/012-forked-substrate-design.md) | Fork design | contract-blind substrate boundary; engine-side formula arithmetic pinned equivalent by the contract suite |
## Open Questions