From 7d2787a115e72792bfd597ca19ee5035ee2e2679 Mon Sep 17 00:00:00 2001 From: Joel DSouza Date: Fri, 3 Jul 2026 15:54:02 +0200 Subject: [PATCH] =?UTF-8?q?docs:=20repoint=20stale=20nexus-contract=20ref?= =?UTF-8?q?=20+=20adapter=E2=86=92in-crate=20aggregate-runner=20(#66)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - #59 refs were stale (no such issue on the public repo); the nexus integration contract lives on the private bombay-nexus#4 board. - Reframe the 'nexus adapter' bullet: per #66 there is no separate adapter crate — the aggregate-runner is an in-crate module behind the 'aggregate' feature, with nexus + nexus-store as feature-gated deps. --- CLAUDE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index 1431c9d..ecfa772 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -58,7 +58,7 @@ The big picture spans several crates/layers; understand these before touching co - **Generic core** — `Actor`, mailbox, supervision. Kept **transport- and domain-agnostic** so the nexus adapter and lite-bombay sit on top. The kameo `remote` (libp2p) feature is replaced by a `zenoh` feature; `macros`/`tracing`/`console`/`otel`/`metrics` features are repurposed. Crate/feature layout is design card **#66** and gates the rewrite shape. - **Zenoh remote layer** — actors are addressable in the dataspace by **key-expr** (the one invasive change escaping `src/remote/` is `ActorId`: libp2p `PeerId` → Zenoh key-expr, #2). `ask` = Session get / query-reply; `tell` = put; **death-watch** = one liveliness token per actor (subscriber gets a `Delete` on drop). DHT registry → key-expr discovery (#3). -- **nexus adapter** — nexus ships *primitives, never a runner*. The loop, dispatch, cursor, lifecycle, supervision, command bus, projection/saga runners are **Bombay's** to build. This boundary is dense and easy to get subtly wrong — **read issue #59 ("nexus integration contract") before implementing anything in the adapter.** Key invariants: single-writer-per-aggregate (optimistic-concurrency conflicts are surfaced, never retried internally); `GlobalSeq` monotonic but not gapless; `Version` is 1-based `NonZeroU64`; the subscription cursor never returns `None` (caught-up = wait, forever-driver); exactly-once is the runner's to assemble from at-least-once + atomic commit; the kernel is `no_std`/`no_alloc`/WASM-capable. +- **nexus aggregate-runner** (in-crate, feature-gated — *not* a separate adapter; see #66) — nexus ships *primitives, never a runner*. The loop, dispatch, cursor, lifecycle, supervision, command bus, projection/saga runners are **Bombay's** to build, as an in-crate module behind the `aggregate` feature (`nexus` + `nexus-store` are feature-gated deps). This boundary is dense and easy to get subtly wrong — **read the nexus integration contract (private `bombay-nexus#4`) before implementing anything in the aggregate-runner.** Key invariants: single-writer-per-aggregate (optimistic-concurrency conflicts are surfaced, never retried internally); `GlobalSeq` monotonic but not gapless; `Version` is 1-based `NonZeroU64`; the subscription cursor never returns `None` (caught-up = wait, forever-driver); exactly-once is the runner's to assemble from at-least-once + atomic commit; the kernel is `no_std`/`no_alloc`/WASM-capable. - **lite-bombay** — thin but self-sovereign mobile client; hosts its own KERI identity, discovers a nearby router in client mode. ## Build & tooling (per the foundation cards) @@ -77,7 +77,7 @@ Bombay is the runtime/adapter for nexus and holds the **same hygiene bar** (the **0. Facts only — no assumptions, no opinions.** If you don't know, say so and research it; don't fill gaps with plausible-sounding guesses about APIs, crate behavior, or performance. No "I think / cleaner / feels better." Technical claims about algorithms, concurrency, or crypto must cite a primary source (papers, the actual repo, RFCs/specs) — "common knowledge" is not a source. Uncertainty is a fact: state it rather than collapsing it into confidence. -**1. Atomicity.** Any operation doing 2+ store calls (multi-key reads, read-then-write) must share one transaction/snapshot — never two independent reads. Derived state (projections, snapshots) is best-effort and re-derivable; it must never block event persistence. (Mirrors nexus contract #5/#13 in issue #59.) +**1. Atomicity.** Any operation doing 2+ store calls (multi-key reads, read-then-write) must share one transaction/snapshot — never two independent reads. Derived state (projections, snapshots) is best-effort and re-derivable; it must never block event persistence. (Mirrors nexus contract #5/#13 in `bombay-nexus#4`.) **2. Arithmetic safety.** No bare arithmetic in production — use `checked_add`/`checked_sub`, return `Err` on overflow. `saturating_add` is banned (silently stops progress). No `try_from(...).unwrap_or(MAX)`. `debug_assert` is NOT a safety check (compiled out in release) — use a runtime check for anything that would corrupt data.