docs: open Phase 1 — architecture spec set over the Phase 0 evidence
docs/architecture/ now exists: README index, overview, five component specs (core-contract, engine-sqlite, engine-postgres, queues, deployment), ADR-001..007 carrying the Phase 0 resolved decisions (crate split, feature scope, per-engine drivers, dependency ownership, wake contract, tx seam), and the centralized open-questions tracker promotion: OQ-ST-01..08 mirror to OQ-01..08 one-to-one with statuses/resolutions carried; new Phase 1 questions append (OQ-09 scheduler collapse, OQ-10 contract versioning). Open Phase 1 work: OQ-04 contract pinning (high), OQ-05 queue semantics depth (high), OQ-06 honker-core quality read (high; fork-trigger gate), OQ-08 capability surface, OQ-09, OQ-10. Erratum fixed in phase-0 OQ-ST-04 (thread-affinity friction is SQLite-side, previously garbled as pg-side) and a stale scheduler- boundary pointer corrected in consumer-inventory.md. Two review passes run (findings: OQ-promotion numbering faithfulness, ADR back-reference sync) — all critical/warning findings resolved.
This commit is contained in:
1 parent
db73678090
commit
4391f6e879
17 files changed
+1812
-14
No files matched your search
@@ -0,0 +1,217 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-10-04
|
||||
---
|
||||
|
||||
# alkstore — Open Questions
|
||||
|
||||
Centralized tracker. IDs `OQ-NN` are stable — never renumber; append.
|
||||
The Phase 0 register's questions (`OQ-ST-01..08` in
|
||||
`docs/research/phase-0.md`) are promoted here faithfully: **OQ-01..08
|
||||
mirror OQ-ST-01..08 one-to-one**, keeping their Phase 0 statuses
|
||||
(a resolved register question stays listed here as resolved, with the
|
||||
ADR that carries its decision). New Phase 1 questions append from
|
||||
OQ-09. Suggested resolution order: **OQ-04 first** (the contract
|
||||
surface everything else hangs off), then OQ-09/OQ-10 (scoped to
|
||||
OQ-04's outcome), then OQ-05/OQ-08 (OQ-05 has an independent design
|
||||
track; OQ-08 depends only on the trait's shape, OQ-04).
|
||||
|
||||
Resolved questions stay listed with their resolution; they are not
|
||||
deleted.
|
||||
|
||||
## Theme: Scope
|
||||
|
||||
### OQ-01: Scope boundary — which honker features are in-scope? *(== OQ-ST-01)*
|
||||
|
||||
- **Origin**: [consumer-inventory.md](../research/consumer-inventory.md),
|
||||
[ADR-002](decisions/002-feature-scope.md)
|
||||
- **Status**: resolved (2026-10-04, Phase 0)
|
||||
- **Priority**: medium
|
||||
- **Resolution**: Answered by the consumer inventory — scope votes
|
||||
shrink to named rows, not the whole honker feature list. First-class:
|
||||
notify/listen (pinned), streams (operator-authority record). In
|
||||
scope: named locks, queues + outbox (documented), scheduler
|
||||
(documented-thin). Cut-flags: rate limits, result storage. Out:
|
||||
honker's exclusion lines. Decision recorded in
|
||||
[ADR-002](decisions/002-feature-scope.md).
|
||||
- **Cross-references**: OQ-07, OQ-04.
|
||||
|
||||
### OQ-02: Crate scope — one store crate, or reactive-core + engines? *(== OQ-ST-02)*
|
||||
|
||||
- **Origin**: [overview.md](overview.md)
|
||||
- **Status**: resolved (2026-10-04, operator decision; Phase 0)
|
||||
- **Priority**: medium
|
||||
- **Resolution**: Reactive-core crate + per-engine engine crates; the
|
||||
split isolates the engines' asymmetry of work and keeps engine
|
||||
binaries single-driver (which the libsqlite3-sys collision
|
||||
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.
|
||||
|
||||
### OQ-03: Driver story — sqlx, tokio-postgres, or per-engine drivers? *(== OQ-ST-03)*
|
||||
|
||||
- **Origin**: [overview.md](overview.md)
|
||||
- **Status**: resolved (2026-10-04, POC-backed both engines; Phase 0)
|
||||
- **Priority**: medium
|
||||
- **Resolution**: Per-engine drivers — rusqlite + honker-core 0.5.0
|
||||
(SQLite; bridged seam), tokio-postgres 0.7.18 + deadpool-postgres
|
||||
0.14.2 (Postgres), under OQ-02's crate split. Decisions recorded in
|
||||
[ADR-003](decisions/003-sqlite-driver.md) and
|
||||
[ADR-004](decisions/004-postgres-driver.md); measurements in
|
||||
`docs/research/poc-sqlite-posture-findings.md` and
|
||||
`docs/research/poc-pg-posture-findings.md`.
|
||||
- **Cross-references**: OQ-02, OQ-05, OQ-06.
|
||||
|
||||
### OQ-07: SQLite-side scope — loadable extension? *(== OQ-ST-07)*
|
||||
|
||||
- **Origin**: [ADR-002](decisions/002-feature-scope.md)
|
||||
- **Status**: resolved (cut-only, 2026-10-04; Phase 0)
|
||||
- **Priority**: low
|
||||
- **Resolution**: The loadable-extension surface is out: every
|
||||
identified consumer is in-process Rust attaching to its own
|
||||
connection (the honker-core `attach_honker_functions` shape). Folded
|
||||
into OQ-01's scope resolution and [ADR-002](decisions/002-feature-scope.md)
|
||||
(explicitly, so the slot's disposition is visible — the Phase 0
|
||||
register carried it as its own entry).
|
||||
- **Cross-references**: OQ-01.
|
||||
|
||||
## Theme: Core contract
|
||||
|
||||
### OQ-04: Contract pinning — the exact trait surface and its semantics *(== OQ-ST-04)*
|
||||
|
||||
*(Retitled in promotion: OQ-ST-04's framing — "the reactive
|
||||
abstraction — what does the unified notify surface look like?" —
|
||||
narrowed to the pinning work its own record already scoped.)*
|
||||
|
||||
- **Origin**: [core-contract.md](core-contract.md),
|
||||
[ADR-006](decisions/006-wake-and-delivery-contract.md),
|
||||
[ADR-007](decisions/007-transactional-seam.md)
|
||||
- **Status**: open (de-risked; both engine sides POC-verified — this is
|
||||
paper work over a complete evidence base)
|
||||
- **Priority**: high
|
||||
- **Resolution**: open. The decisions that bound it are made
|
||||
([ADR-006](decisions/006-wake-and-delivery-contract.md): opaque-wake + re-read, the delivery-guarantee table, the
|
||||
reserved namespace's existence; [ADR-007](decisions/007-transactional-seam.md): caller-held `TxHandle`
|
||||
with `*_tx` methods). What remains to pin, per the honker-rs surface
|
||||
as starting artifact against the inventory rows:
|
||||
- Which surface parts are contract v1 and which are engine-extension
|
||||
(queue depth, scheduler surface, lock semantics details).
|
||||
- `TxHandle` representation: `dyn` + per-engine downcast (POC
|
||||
sketch, works, two recorded frictions) vs generic/enum handle.
|
||||
- The reserved/meta namespace: exact strings (Postgres
|
||||
reconnect-wake channel like `__listener_reconnected__`), and
|
||||
whether SQLite-side internal names carry an equivalent prefix.
|
||||
- Error taxonomy: what callers can match on per mechanism (e.g.
|
||||
`PayloadTooLarge` is POC-verified pg-side; SQLite's notify has no
|
||||
8000-byte limit — is the error universal?).
|
||||
- Naming/grouping of the honker-rs surface where renames clarify
|
||||
(e.g. what `listen()` returns — a wake receiver? a subscription
|
||||
handle?).
|
||||
- The `Store::open` config shape — what engine-configuration
|
||||
(durability knobs, pool sizing, listener posture) is consumer
|
||||
surface vs engine crate docs.
|
||||
- Verification backlog for properties the POCs pinned on one engine
|
||||
only — e.g. lock TTL/expiry re-acquisition is POC-pinned on
|
||||
Postgres but rests on honker's machinery on SQLite; the contract
|
||||
test suite must pin the SQLite side too.
|
||||
- Delivery-guarantee rows for locks and scheduler (the guarantee
|
||||
table in [ADR-006](decisions/006-wake-and-delivery-contract.md) covers notify/streams/queues; lock-vs-TTL-race
|
||||
and scheduler-tick guarantees need either rows there or an
|
||||
explicit "scheduler is queues" absorption via OQ-09).
|
||||
- **Cross-references**: OQ-01, OQ-10, OQ-09, OQ-08.
|
||||
|
||||
## Theme: Queues and scheduling
|
||||
|
||||
### OQ-05: Queue semantics depth — retry/backoff/dead-letter/sweep design *(== OQ-ST-05)*
|
||||
|
||||
- **Origin**: [queues.md](queues.md)
|
||||
- **Status**: open (posture resolved: re-derived on both engines with
|
||||
the pg-boss schema family as design reference and honker's queue
|
||||
design as the SQLite-side one — ADR-004/ADR-005)
|
||||
- **Priority**: high
|
||||
- **Resolution**: open. The transactional and claim properties (the
|
||||
hard driver-coupled part) are POC-pinned on both engines. Remaining:
|
||||
the semantics-depth design — retry policy shape (attempts, backoff
|
||||
curve), visibility-timeout/renewal mechanics, dead-letter
|
||||
move-vs-flag and retention, sweep/maintenance design
|
||||
(`sweep_expired` cadence and owner), and whether result-storage's
|
||||
cut-flag gets reconsidered as part of this surface (it is
|
||||
queue-adjacent tooling).
|
||||
- **Cross-references**: OQ-09, OQ-06.
|
||||
|
||||
### OQ-09: Is the scheduler a first-class mechanism, or queues + `schedule()`?
|
||||
|
||||
- **Origin**: [queues.md](queues.md) (spin-out of OQ-05's Phase 0
|
||||
framing, where the scheduler's boundary question lived)
|
||||
- **Status**: open
|
||||
- **Priority**: medium
|
||||
- **Resolution**: open. The inventory found the scheduler need real but
|
||||
thin (the family-wide "who sweeps/renews/reaps" problem), and
|
||||
mechanically scheduler = cron/`@every` enqueueing into named queues
|
||||
+ leader election + a tick. If design confirms the collapse, the
|
||||
contract surface is queues + `store.schedule(cron, queue)` with the
|
||||
scheduler mechanism absorbed; if consumers need
|
||||
inspectable/pausable schedule objects (`add/pause/resume/update/
|
||||
list/remove`), it stays a first-class mechanism (the full honker
|
||||
shape). Decided against the inventory rows, not the whole honker
|
||||
menu.
|
||||
- **Cross-references**: OQ-05, OQ-04.
|
||||
|
||||
## Theme: Engines and dependencies
|
||||
|
||||
### OQ-06: honker-core quality read — does the default posture hold? *(== OQ-ST-06)*
|
||||
|
||||
- **Origin**: [ADR-005](decisions/005-dependency-ownership.md),
|
||||
[engine-sqlite.md](engine-sqlite.md)
|
||||
- **Status**: open
|
||||
- **Priority**: high (fork trigger is a gate on the SQLite engine's
|
||||
dependency posture)
|
||||
- **Resolution**: open. ADR-005 fixed the calculus and the trigger: the
|
||||
Phase 1 quality read of honker-core 0.5's watcher/transactional core
|
||||
(Writer/Readers/SharedUpdateWatcher/attach_*) — looking for defects
|
||||
the POCs wouldn't surface, unsafe assumptions in the watcher
|
||||
failure-handling, and schema-migration brittleness. Outcomes: posture
|
||||
holds (no ADR change), or a fork/patch need is named (fork is normal
|
||||
work per ADR-005).
|
||||
- **Cross-references**: ADR-003, ADR-005, OQ-05 (if the read forces a
|
||||
fork, queue-on-honker-machinery work changes shape).
|
||||
|
||||
## Theme: Deployment and capabilities
|
||||
|
||||
### OQ-08: Where does the honest single-host/multi-host boundary live in the trait surface? *(== OQ-ST-08)*
|
||||
|
||||
- **Origin**: [deployment.md](deployment.md)
|
||||
- **Status**: open
|
||||
- **Priority**: medium
|
||||
- **Resolution**: open. The pg engine is natively multi-host (POC #2
|
||||
verified — no single-host assumption to remove); SQLite is
|
||||
single-machine by nature (file-backed, NFS-two-writers unsupported —
|
||||
honker's honesty posture, inherited). The unified surface must not
|
||||
pretend SQLite is multi-host. Options: per-engine capability flags
|
||||
(`Store::capabilities()`), a documented deployment matrix only
|
||||
([deployment.md] carries the facts), or compile-time knowledge only
|
||||
(a consumer choosing the SQLite engine knows). Rides OQ-04: the
|
||||
trait's shape constrains where capability differences can surface.
|
||||
- **Cross-references**: OQ-04, [ADR-006](decisions/006-wake-and-delivery-contract.md).
|
||||
|
||||
### OQ-10: How do engine crates track core-contract version changes?
|
||||
|
||||
- **Origin**: [overview.md](overview.md),
|
||||
[ADR-001](decisions/001-crate-split.md)
|
||||
- **Status**: open
|
||||
- **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), OQ-02.
|
||||
|
||||
## Deferred / Blocked
|
||||
|
||||
None currently. Every open OQ above is actionable Phase 1 architecture
|
||||
work (contract pinning, design, quality read) with its evidence base
|
||||
complete — no external arrivals are being waited on.
|
||||
Reference in new issue
Block a user