spec(R058): DB writes via MessageBus (single-writer actor)
Operator: "db via bus so we dont crash it?" — yes, this is the natural fit for the lane model (R057 system lane + R046 multi-unit lanes). Concurrent lanes writing directly to SQLite hit SQLITE_BUSY or worse; mediating all writes through a single MessageBus-owned db-writer actor enforces the single-writer invariant operationally. Reads stay direct (multi-reader WAL is safe). Migration is gradual (table by table). Also serves as the substrate for multi-repo federation (R028 / ADR-019/020) where cross-process DB sharing needs message-based access anyway. Future M040. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
14fe3fa20a
commit
72c2ecb2b2
1 changed files with 17 additions and 0 deletions
|
|
@ -720,3 +720,20 @@ ADR-0000 declares SF a **purpose-to-software compiler**. R036–R040 codify that
|
|||
- Supporting slices: none
|
||||
- Validation: unmapped
|
||||
- Notes: System-lane inventory: (1) sleeptime consolidation (currently auto/loop.js drainSleeptimeConsolidationQueue between units), (2) self-feedback triage drain, (3) memory-extract for completed units (already async post-unit but currently blocks next dispatch), (4) doctor periodic audits, (5) log/journal compaction (NEW — no current implementation), (6) reflection-corpus assembly, (7) gemini-catalog + openai-codex-catalog refresh (currently only at session start). Single-writer DB invariant met by routing all DB writes through sf-db.js serial queue. Cross-lane conflicts (e.g. memory-extract reading a unit's session file while the next unit starts) resolved by lane tasks operating on already-sealed inputs. The **lane** primitive unifies R046 (multi-unit lanes), R049 (per-lane model routing), and R057 (system lane) into one architectural model.
|
||||
|
||||
### R058 — DB Writes Routed Via MessageBus (single-writer actor)
|
||||
- Class: core-capability
|
||||
- Status: active
|
||||
- Description: All project-DB writes flow through a single MessageBus-mediated **db-writer actor** that owns the only WAL connection. Lanes (unit lane, system lane, multi-unit lanes per R046) send write-request messages; the actor serializes + applies them. Reads stay direct (multi-reader concurrency works). Crash isolation: lane crash mid-write doesn't corrupt the DB because the message is either fully delivered or not — the actor's transaction is atomic. Builds on existing uok/message-bus.js + serves the lane primitive (R046, R049, R057).
|
||||
- Why it matters: With concurrent lanes (R057 system lane today, R046 multi-unit tomorrow), naïve direct writes hit SQLITE_BUSY contention or worse (WAL corruption from mishandled retries). DB-via-bus enforces the single-writer invariant *operationally*, not just by convention. Also enables: queue-depth backpressure visibility, write-replay on crash recovery, and is the natural substrate for multi-repo federation (R028 / ADR-019/ADR-020) where cross-process DB sharing already needs message-based access.
|
||||
- Source: spec (responds to operator observation 2026-05-17 — "db via bus so we dont crash it?")
|
||||
- Primary owning slice: unmapped (future "M040 DB-via-Bus")
|
||||
- Supporting slices: none
|
||||
- Validation: unmapped
|
||||
- Notes:
|
||||
- Writer actor lives in same process today (in-memory MessageBus), can become a separate process in federation mode (ADR-020 gRPC wire)
|
||||
- sf-db.js becomes the message-producer; actual SQLite UPDATE/INSERT/DELETE happens only inside the writer
|
||||
- Reads bypass the bus (multi-reader is safe via WAL)
|
||||
- Backpressure: queue depth >N triggers self-feedback (writer overwhelmed → operator visibility)
|
||||
- Test contract: 1000 concurrent write requests from N lanes produce N total rows, no errors, no SQLITE_BUSY
|
||||
- Migration is gradual: move writers one table at a time (slices first, then milestones, then memory_*, etc.)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue