Skip to content

Latest commit

 

History

History
451 lines (330 loc) · 34.8 KB

File metadata and controls

451 lines (330 loc) · 34.8 KB

Plan: ref/heed + heed-inspired beastdb Rust crate

Status: Phase 0 accepted (policy + inventory; see Review & acceptance). Gap #1 (durability-"C1" scrub) closed. Gap #2 (README Decision 1) closed in worktree (Constraints ffi/ exception + Status names R17). Phase 1 done (ref/heed @ v0.22.1 / 86cd1f681953cd5f6870706f6139b851e975975e). Phase 2 done - docs/HEED-MAP.md triage + frozen T1 (12 cases). Phase 3 done - ffi/rust/beastdb v0 + checks.beastdb-rust-smoke (immediate + batch). Phase 4 done - T0+T1 flake checks (beastdb-rust-t0 / beastdb-rust-t1) + skip matrix; residual R17 closed. Phase 5 done (docs honesty) 2026-07-12 - suite provenance (heed3 tests zero), thin v0 completeness, Gap #3 operator R17 cross-links. Phase 6 advanced (partial) 2026-07-13 - P1 bulk multi-put + P2a contains + P2b product delete (P6-DEL) + Mode B flush policy (size/count + P6-BATCH-TIME max_delay) + P6-EXPORT PR0/PR0b/PR1/PR2 + P6-CURSOR + P6-ACID + P6-RANGE + D1 (product reverse/range/first-last/neighbors + len/is_empty/clear/delete_range + dual-backend C ABI v9 + Rust rev_iter/range/first/last/len/is_empty/clear/delete_range; historical C ABI v5-v8 retained; package default = export; CLI emergency BEASTDB_USE_CLI=1; BEASTDB_API_VERSION 9) + D2 (crate-only RoTxn / read_txn; selective T2 8; docs/MIGRATE-HEED.md; checks.beastdb-rust-t2; suite T0 8 / T1 26 / T2 8) + D3 measure (docs/BENCHMARKS.md M2) + R7-BYTES (export get densify + bulk memcpy) + R7-SCAN (lazy external-pair scan; R7 still deeper partial) + R7-SNAP docs (EXPORT idle gets do not auto-follow peers; reopen or successful sync refreshes; not LMDB MVCC). Tier 0 master decision locked 2026-07-13: priority track = heed / heed3 non-encrypted drop-in migration; P6-ACID done; P6-RANGE done; D1 done; D2 done; D3 measure done; R7-BYTES done; R7-SCAN done; R7-SNAP docs done; P6-WAL optional / deprioritized. Still open: P6-WAL optional, G1 human. R7 deeper partial (not closed). Completed-items ledger: docs/PLAN-COMPLETED.md. Remaining / actionable: docs/PLAN-REMAINING.md (default next G1 human). No commits from this document alone (agents never commit).

Decisions locked by master (Hunter) - see Decisions (locked). Sub-agents execute without re-litigating scope.


Goal (precise)

  1. Pin Meilisearch heed (the monorepo that contains heed and heed3) under ref/ as study prior art.
  2. Design first-party foreign language bindings in this monorepo - starting with a Rust crate whose library API and docs are inspired by heed, not a clone of LMDB wire/API.
  3. Use heed's test suite as a requirements catalog + selective port, not as "drop in and cargo test against beastdb."
  4. Optimize for maximal flexibility and performance in the bindings + write path (both immediate and batched strategies).
  5. Priority track (Tier 0 master, 2026-07-13): migrate typical heed / heed3 non-encrypted call sites to beastdb with minimal code change (heed-shaped API + beastdb semantics). This is a heed3 drop-in replacement for non-crypto uses - not full heed3 encryption, not lmdb.h, not full suite green.

Decisions (locked)

# Question Decision
1 Crate / bindings path ffi/ is the monorepo home for foreign bindings - one tree per language flavor (not demos-only). Start with ffi/rust/beastdb/; keep thin demos under ffi/demos/{c,cpp,rust}/ as smoke consumers. Document in AGENTS/README that this monorepo includes bindings (Lean product + Nix + ffi/ language crates).
2 Write / "txn" model v0 Both paths required - (A) immediate put + durable commit/sync, and (B) buffered / batched writes with sophisticated batching when it wins on measure. Flexibility + performance are highest priority. Design assumption for this workstream: local embedded durability (uninterruptible power supply (UPS) / laptop battery assumed) - do not treat WAL as mandatory for the bindings-facing model; prefer simple durable publish strategies and measure. (Product Lean may still have WAL today; bindings API and honesty docs follow the local-power / batch-friendly story; any product WAL simplification is a separate, explicit product change, not silent.)
3 heed vs heed3 in docs Study monorepo as ref/heed. API inspiration = heed (typed env/db/txn ergonomics, codecs, cookbook). heed3 = same monorepo crate family aimed at LMDB mdb.master3 (encryption-at-rest / checksum features) - not our target. Upstream relationship (accurate): one git repo; two crates (heed ↔ mdb.master, heed3 ↔ mdb.master3); not "heed3 is a git branch of this repo," though master3 is an LMDB branch. Docs may say "heed family / heed3 only for contrast."
4 Gate strength Only git is human-in-the-loop. Everything else is agent-owned automation: T0 + T1 selective suite must be flake checks (nix build / nix flake check paths). Do not park work on "wait for human land." Do not design phases around commit/push/G1 publish.
5 Priority vs residual tree FFI / bindings are agent work to complete on the current tree. Very little is HITL-blocked. Proceed; do not serialize behind human G1 publish or "clean index" rituals.
6 Migration goal (Tier 0, 2026-07-13) heed / heed3 non-encrypted drop-in track. Typical non-encrypted heed call sites should migrate to beastdb with minimal code change (heed-shaped API + beastdb semantics). Not full heed3 crypto, not lmdb.h wire drop-in, not full upstream suite green, not power-fail / kill-9 durability claims.
7 P6-ACID scope In scope for the drop-in track. Multi-key atomic commit/rollback is required so Mode B abort honesty matches heed-shaped txn expectations. Master decision recorded 2026-07-13; implementation shipped 2026-07-13 (product multi-key atomic batch - not LMDB page-level ACID).
8 P6-WAL priority Optional / deprioritized. Not a bindings blocker; not the priority. Product may keep WAL under the hood; simplify later only as an explicit product change. Bindings describe observable durability, not internal WAL file names.

Critical honesty

Claim Reality today
"Run heed3's test suite against our LMDB replacement" Not drop-in. heed/heed3 talk to real LMDB via lmdb-master*-sys (mdb_env_*, txns, cursors, multi-DB, flags, mapsize; heed3 + encryption). beastdb exposes a small C ABI (BEASTDB_API_VERSION 9: open/put/get/bytes/multi-put/contains/delete/cursor/atomic-batch/cursor_open_ex/first-last/neighbor/len/clear/delete_range/sync/close + ERR_DONE) over a dual-backend bridge: package default is same-process compiled @[export] full v9 (P6-EXPORT PR2 + P6-CURSOR + P6-ACID + P6-RANGE + D1); CLI emergency via BEASTDB_USE_CLI=1 at open (fork/exec). Residual R7 is deeper partial (not closed) - multi-file MANIFEST/shards, not lmdb.h, not mmap B+tree.
"LMDB replacement" Product language forbids wire/page drop-in. Keep LMDB-class embeddable KV, not "pass heed's suite = LMDB."
Full heed suite green on beastdb Needs near-complete lmdb.h shim or mass rewrite. Plan = subset + adapter, not full suite.
WAL Product may still implement WAL paths. This workstream's durability story = local embedded durability (UPS / laptop battery assumed); bindings optimize for batch + explicit durable publish; do not market power-fail / kill-9 (R9/R10 unchanged).

Interpretation of the goal:

  • Study heed API surface + tests under ref/heed.
  • Port/select tests that match semantics we ship (or deliberately grow for performance).
  • Shape beastdb Rust crate after heed ergonomics, mapped onto beastdb truth + dual write paths.

Policy / tree placement (AGENTS.md)

Rule Implication
Lean product only Crate is not product engine logic; Lean remains SSOT for store semantics.
ref/ = study only Submodule fine; never import into Lean; productSrc drops ref/.
First-party Rust / C Allowed exception (Phase 0 must write it): monorepo foreign bindings under ffi/<lang>/ + existing C bridge + demos. Still Nix-packaged; not Lean product; no Bash/Python product helpers.
Namecheck beastdb spelling in first-party; ref/heed exempt.

Layout (locked):

ffi/
  include/beastdb.h             # C ABI (shared)
  src/beastdb_bridge.c          # dual-backend bridge (export package default PR2; CLI emergency BEASTDB_USE_CLI=1; static .a CLI-only)
  demos/{c,cpp,rust}/           # thin smoke demos
  rust/beastdb/                 # REAL Rust crate (Cargo + src + tests)
  # later (same monorepo pattern):
  # c/... or promote demos; cpp/... as first-class bindings if needed
ref/
  heed/                         # submodule: meilisearch/heed monorepo

Do not put the crate under ref/.


Upstream pin

Item Choice
Repo https://github.com/meilisearch/heed.git
Path ref/heed (whole monorepo: heed/, heed3/, heed-types, heed-traits, lmdb-master*-sys)
Why whole repo heed3 is a crate in the monorepo, not a separate git root.
Pin Prefer release tag matching crates.io heed / heed3 (~0.22.x) or known-good SHA; record in ref/README.md + PRIOR-ART.
Nested submodules Init recursive only if building upstream suite for study; shallow pin enough for API/docs + triage.

Submodule add is a git operation (human when committing). Agents may prepare docs/tables and work against a local checkout if already present; do not block engineering on publish.


Capability gap map (heed -> beastdb)

heed concept beastdb today Phase Suite fate
EnvOpenOptions::open(path) beastdb_env_open multi-file dir Crate v0 Port
write_txn / read_txn / commit No LMDB page txn; put + sync Dual model (immediate + batch) Port with beastdb semantics
Database::put/get typed UTF-8 + bytes put/get Crate v0 codecs Port
Named multi-DB Single logical store Deferred / key-prefix emulate Skip / rewrite
Cursors / range / prefix Product scan + C ABI v6/v8; Rust iter/prefix_iter/rev_iter/range/first/last P6-CURSOR + P6-RANGE done Port/Adapt; internal-key order honesty
map_size, env flags, freelist N/A Never 1:1 Skip / non-claim
Dupsort / custom comparators Not product Deferred Skip
Nested txns, reserve, append flags Not product Deferred Skip
Encryption (heed3 / master3) G9/G19 models only Not target Skip
Multiprocess SWMR / MWMR SWMR + G22 disjoint leaves Partial Selective
Compaction copy Product compact != LMDB Different API Skip / separate smoke
"No overhead over LMDB" Export default (spawn gone on default path); R7-BYTES bulk get (~2x at 64 KiB; still ~linear); R7-SCAN open still freezes live index (not B+tree); not mmap / not O(1); R7 deeper partial Measure; never claim Honesty

Write / "txn" semantics (locked: both paths)

Do not fake LMDB ACID page transactions. Expose heed-shaped types with beastdb meaning:

Type Meaning
Env Open multi-file store (beastdb_env)
RwTxn / write path Mode A - immediate: each put hits the engine/bridge; commit() -> durable publish (sync / checkpoint). Mode B - batched: buffer puts in the crate (or future bulk C ABI); commit() flushes batch then durable publish. Choose/default by API (write_txn options or explicit Batch) for flexibility; pick batching strategy by measure.
RoTxn Read path after last durable publish / consistent open; document free-copy / stale-handle (R6).
Database<KC, DC> Typed view over single store; codecs à la heed-types patterns (reimplement or mirror traits - no link to LMDB sys crates).

Durability honesty (bindings local-power assumption):

  • Target: local embedded durability (UPS / laptop battery assumed) - not power-fail lab claims (R10 still not claimed).
  • WAL is not a bindings requirement for this plan; prefer clear durable publish on commit and high-throughput batching.
  • If product Lean still appends WAL under the hood, bindings docs describe observable semantics (when is a put durable?), not internal file names - until a separate product change simplifies storage.
  • Crash mid-batch without commit: batch not durable; no silent "looks committed."
  • P6-ACID (shipped): multi-key atomic commit/rollback for Mode B unlimited (and unflushed buffer) via product applyAtomicBatch / beastdb_atomic_batch_bytes. beastdb multi-key atomic batch, not LMDB page-level ACID. Auto-flush chunks are product-atomic but not rolled back by later abort.

Performance mandate:

  • Measure immediate vs batch (and batch sizes) on the extracted path / bridge.
  • If batching wins, invest in sophisticated batching (coalesce, size/time thresholds, bulk put ABI if fork/exec dominates).
  • R7 same-process compiled @[export] remains a latency lever when measure says fork is the wall - not blocked on "suite completeness."

Workstreams (sub-agents; disjoint write scopes)

Phase 0 - Policy + inventory (docs) - ACCEPTED 2026-07-12

Owner: docs agent Writes: AGENTS.md (monorepo bindings exception under ffi/<lang>/), ref/README.md stub, docs/PRIOR-ART.md heed family stub, docs/GAPS.md residual (R17 open: heed-inspired Rust crate + selective suite; R7 partial cross-link), release notes decision, this plan's status

Deliverables (landed):

  • Explicit foreign-bindings exception + monorepo includes bindings (AGENTS.md + README intro / prior-art / docs table; Constraints residual = N4).
  • Residual R17 open for crate + T0/T1 flake gates.
  • Non-claims: not lmdb.h, not full heed suite, not heed3 encryption, not power-fail.
  • Dual write path + local embedded durability / bindings local-power assumption recorded (not fitness C1 / R3).
  • Follow-up scrub: durability-"C1" overload removed (Gap #1 closed).
  • README Decision 1 surface largely landed (Gap #2 mostly closed).

Exit (policy): policy text matches locked decisions (no further master Q&A). ✅ Exit (fully clean monorepo surface): residual nits N1 / N2 optional; N4 + Gap #3 closed. Does not block Phase 2+.


Phase 1 - Submodule pin - DONE 2026-07-12

Owner: agent (submodule + inventory); human creates signed commit Landed:

git submodule add https://github.com/meilisearch/heed.git ref/heed
git -C ref/heed checkout v0.22.1   # 86cd1f681953cd5f6870706f6139b851e975975e

Pin: tag v0.22.1 @ 86cd1f681953cd5f6870706f6139b851e975975e (crates.io max stable heed/heed3 0.22.1).

Writes: .gitmodules, ref/heed gitlink, ref/README.md, docs/PRIOR-ART.md, release notes, this plan status Does not: link heed/LMDB into product Lean; does not make upstream suite a product gate.

Exit: ref/heed pinned in inventory; namecheck still skips ref/. ✅


Phase 2 - Study extract (read-only under ref/heed or upstream tree) - DONE 2026-07-12

Owner: research agent (no product engine code) Landed: docs/HEED-MAP.md (full triage). PRIOR-ART + release notes + this plan status updated.

  1. Public API inventory - Env, options, Database, Ro/Rw txn, iterators, flags, errors (heed primary; heed3 delta = encryption only). ✅
  2. Test inventory - classify Port / Adapt / Skip / Needs product (and Needs batch API). ✅
  3. Codec layer - reimplement BytesEncode/BytesDecode + Bytes/Str only in crate; no upstream link. ✅
  4. C ABI growth list prioritized by performance (bulk multi-put P1, delete/contains P2, same-process export P3, iterate P4). ✅
  5. Batching notes - multi-put + commit atomicity -> Mode B batch; no fake LMDB multi-key rollback. ✅

Frozen T1: 12 cases in HEED-MAP §6 (T1-01...T1-12). Batch-tagged: T1-04, T1-07 (Mode B); dual-mode: T1-01, T1-03, T1-05.

Exit: triage frozen; T1 explicit; batch-related tests tagged. ✅


Phase 3 - Crate v0 (ffi/rust/beastdb) - DONE 2026-07-12

Owner: bindings agent Landed: ffi/rust/beastdb/** library + examples/smoke.rs; Nix packages.beastdb-rust + checks.beastdb-rust-smoke.

v0 surface:

beastdb::{
  Env, EnvOpenOptions,
  Database,
  Error, Result,
  types::{Bytes, Str, BytesEncode, BytesDecode},
  WriteTxn, WriteMode,
  // write paths:
  //   Env::write_txn       - immediate put + commit -> sync
  //   Env::batch_write_txn - buffered put + commit flush -> sync
}

Build: rustc offline in Nix (no crates.io); optional local cargo via BEASTDB_LIB_DIR. Exit: ✅ smoke green - open -> immediate + batch put/commit -> reopen -> get; bytes round-trip; missing key; corrupt open fail-closed.

Honesty in crate rustdoc: fork/exec (R7); dual write paths; local-power durability; no multi-DB/cursors/LMDB flags/heed3 encryption; one env single-threaded.


Phase 4 - Selective test suite (flake-gated) - DONE 2026-07-12

Owner: test agent Landed: ffi/rust/beastdb/tests/** (common + t0.rs + t1.rs); Nix checks.beastdb-rust-t0 + checks.beastdb-rust-t1; skip matrix docs/HEED-MAP.md §6; residual R17 closed. Writes (historical): ffi/rust/beastdb/tests/**

Tier Content Gate
T0 Durable put/get, missing key, batch commit, corrupt open fail-closed checks.beastdb-rust-t0 (landed)
T1 Ported heed examples/tests needing only open/put/get/commit~=sync (+ batch variants) checks.beastdb-rust-t1 (landed; frozen set)
T2 Selective D2 expansion (RoTxn, range edges, clear/len, multi-env, abort, codecs) checks.beastdb-rust-t2 (landed; 8 tests; not full suite)
T3 Full upstream cargo test in ref/heed vs real LMDB Study-only; not product gate
T4 Cursors / multi-DB / encryption Blocked on product+ABI; not "suite vanity"

Process:

  1. Port only Phase-2 T1 list with // inspired by ref/heed/....
  2. Matrix of skipped tests + reason (doc).
  3. Wire T0+T1 into flake.nix checks / test-suite map (docs/TESTING.md).

Exit: named checks green for T0+T1; skip matrix published; residual R17 closed.


Phase 5 - API/docs polish - DONE (docs honesty) 2026-07-12

Owner: docs + bindings Landed (this worktree / parallel agents): suite provenance honesty (heed3 tests zero; suite is heed-shaped beastdb tests, not upstream port count); thin v0 completeness vs full heed; Gap #3 operator cross-links for R17 closed in docs/VISION.md (+ LIMITS optional); non-claims unchanged (not lmdb.h, not full heed suite, not heed3 encryption, not power-fail). Writes (historical / parallel): crate rustdoc, docs/API.md foreign/bindings section, README monorepo + bindings blurb, PRIOR-ART heed lessons, HEED-MAP keep-up; Gap #3 VISION/LIMITS cross-links

Content (exit checklist):

  • heed vs beastdb side-by-side (ergonomics vs engine).
  • Getting-started shaped like heed README (open -> put -> commit -> get) with both write modes.
  • LIMITS / R6 / R7 / local-power durability links (never durability-"C1").
  • Gap #3 closed (VISION R17 -> GAPS / PLAN / HEED-MAP / TESTING). N1/N2 remain optional polish.

Exit: docs honesty landed; residual R17 stays closed; Phase 6 growth continues (P6-ACID required by Tier 0; other rows still measure-driven).


Phase 6 - Growth (P6-ACID required by Tier 0; other rows measure + embed need) - ADVANCED (PARTIAL) 2026-07-13

Not "make full heed suite pass." Do not claim full Phase 6 closed - P1 bulk multi-put + P2a contains + P2b product delete (P6-DEL) + Mode B flush policy (size/count + time) + P6-EXPORT PR2 + P6-CURSOR + P6-ACID + P6-RANGE landed. Priority track (Tier 0): heed non-encrypted drop-in -> P6-ACID done. P6-RANGE done. P6-WAL optional / deprioritized.

Growth Status Residual
Bulk / multi-put C ABI (batch without N forks) Done (P1) - CLI put-bytes-multi, beastdb_put_bytes_multi (non-ACID bulk path remains) At land (pre-PR2): one spawn/batch. Superseded residual: see PR2 - export default same-process; Mode B flush now uses P6-ACID atomic batch; R7 deeper partial
Sophisticated batching (size/count thresholds) Done - BatchFlushPolicy (max_pairs / max_bytes); auto-flush without sync; loud partial-durability honesty -
contains Done (P2a) - CLI contains-bytes, C beastdb_contains / beastdb_contains_bytes, Rust Database::contains; API v4+ At land (pre-PR2): fork/exec. Superseded residual: PR2 export default; R7 deeper partial
delete Done (P2b / P6-DEL) - KV tombstone + WAL Record.del + CLI delete-bytes + C beastdb_delete/_bytes + Rust Database::delete; API v5 Not LMDB free-page reclaim; at land (pre-PR2) fork/exec. Superseded residual: PR2 export default; R7 deeper partial
Same-process compiled @[export] PR0/PR0b/PR1/PR2 done - dual-backend full v5, export package default; CLI emergency BEASTDB_USE_CLI=1 R7 deeper partial (not closed)
Cursor / prefix / reverse / range Done (P6-CURSOR + P6-RANGE) - product scan + C ABI v6/v8 + Rust iter/prefix_iter/rev_iter/range/first/last Internal-key order; not LMDB B+tree; R7 deeper partial
Time-based batch coalesce Done (P6-BATCH-TIME) - max_delay lazy idle + poll_flush; T1/smoke Auto-flush not abortable for that chunk
Real multi-key atomic txn Done (P6-ACID) - product WriteTxn + C ABI v7 atomic batch + Mode B unlimited commit/abort beastdb multi-key atomic batch, not LMDB pages; auto-flush chunks not abortable
Drop or simplify product WAL Open (optional / deprioritized) - P6-WAL Not a bindings blocker; product simplify later
lmdb.h shim Out of scope - OOS Honesty break

What success looks like

Done means Not done means
ref/heed study pin + map Product links LMDB from heed sys crates
AGENTS and README: monorepo + ffi/<lang> bindings allowed Rust as Lean product engine
Crate under ffi/rust/beastdb feels heed-like; non-encrypted heed call sites migrate with minimal change Full heed3 encryption / lmdb.h / full suite / power-fail claims
Immediate + batch write paths Only one write mode
T0+T1 flake-green Full upstream suite on beastdb
Perf measured; batching invested when it wins "As fast as LMDB" claim
Local-power durability honesty (no durability-"C1" token) Power-fail / full heed3 encryption story

Board: remaining (2026-07-13)

Doc Role
docs/PLAN-COMPLETED.md What shipped (Phases 0-5, Phase 6 done rows, R17 closed, API history)
docs/PLAN-REMAINING.md Actionable open work: IDs, priority order, next steps, acceptance, owners

Summary (details + checklists in PLAN-REMAINING):

ID Item Status Default owner
P6-DEL Product delete (tombstone) done - PLAN-COMPLETED -
P6-EXPORT PR1 Dual-backend full C ABI v5 (CLI default) done (R7 partial) - PLAN-COMPLETED -
P6-EXPORT PR2 Export package default + M1 + deeper partial done (R7 deeper partial) - PLAN-COMPLETED -
P6-CURSOR Cursor / prefix / range done - PLAN-COMPLETED -
P6-RANGE Reverse / range / first-last / neighbors done - PLAN-COMPLETED Internal-key order honesty
P6-BATCH-TIME Time-based batch coalesce done - PLAN-COMPLETED -
P6-ACID Real multi-key atomic txn done - PLAN-COMPLETED -
P6-WAL Drop / simplify product WAL open (optional / low priority) Deprioritized; not bindings blocker
D1 Drop-in depth len/clear/delete_range done - PLAN-COMPLETED C ABI v9
D2 Drop-in depth RoTxn + T2 + migrate done - PLAN-COMPLETED Not LMDB MVCC
D3 R7 embed measure (M2) measure slice done - PLAN-COMPLETED No product change this slice; R7 still deeper partial
R7-BYTES Export large-value get densify done - PLAN-COMPLETED Bulk memcpy; not mmap O(1); R7 still deeper partial
R7-SCAN Lazy external-pair scan cursor done - PLAN-COMPLETED Snapshot-at-open; open still freezes live index; not B+tree; R7 still deeper partial
R7-SNAP EXPORT long-lived handle visibility docs done (docs-only) - PLAN-COMPLETED Idle gets do not auto-follow; reopen or successful sync refreshes; not MVCC; does not close R7
N1 UPS first-use expand done -
N2 GAPS last-updated density done -
G1 Signed land / push / tag open Human only (RELEASE.md)
R7 Foreign C ABI depth deeper partial (not closed) Export default; M2 + R7-BYTES + R7-SCAN + R7-SNAP docs; remaining STATIC / optional B2 refresh / live-index freeze / densify walls; not lmdb.h
OOS-* Full suite / heed3 crypto / lmdb.h / power-fail claims out of scope Do not start

Product residuals outside this plan (R1, R3, R6, R8-R12, F3, ...) -> docs/GAPS.md.


Review & acceptance

Master review of Phase 0 (2026-07-12) and of the durability-"C1" scrub (Gap #1). Engineering phases 2+ may proceed; polish items below do not block Phase 2 study extract.

Phase 0 acceptance criteria

# Criterion Status
A1 AGENTS.md foreign-bindings exception under ffi/<lang>/; Lean remains store SSOT Accepted
A2 Layout documents ffi/ + planned ffi/rust/beastdb/; crates not under ref/ Accepted
A3 Residual R17 open with dual-write + T0/T1 flake closure criteria; R7 stays partial Accepted
A4 Non-claims locked (not lmdb.h, not full heed suite, not heed3 encryption, not power-fail, not multi-key LMDB atomicity) Accepted
A5 Dual write paths + local-power durability assumption recorded in plan / PRIOR-ART / GAPS / release notes Accepted
A6 No product Lean engine change; no crate scaffold; no accidental full-suite gate Accepted
A7 Decision 1 also documented in README (monorepo includes bindings + ffi/ exception + R17 pointer) Accepted (worktree) - intro, Constraints ffi/<lang>/ exception, Status names R17, ref/heed + PRIOR-ART
A8 Durability wording does not overload fitness/VISION C1 Accepted (Gap #1 closed)

Phase 0 policy exit: accepted (A1-A8). Phase 0 fully clean surface: residual nits N1 (+ N2); Gap #3 closed Phase 5; N4 closed in worktree. Does not block Phase 3+.

Gap #1 acceptance (durability-"C1" scrub) - CLOSED

# Criterion Status
G1.1 No live durability-"C1" / C1-class wording (historical release notes "why" quote OK) Accepted
G1.2 Canonical language: local embedded durability (UPS / laptop battery assumed) / bindings local-power assumption Accepted
G1.3 Fitness C1 / R3 (dual MANIFEST publishers) unchanged Accepted
G1.4 VISION / Horizon machine-class C1 unchanged Accepted
G1.5 Meaning preserved: local power; WAL not bindings-required; R9/R10 not claimed Accepted
G1.6 Docs-only surfaces: PLAN.md, release notes, docs/GAPS.md, docs/PRIOR-ART.md Accepted

Review findings - nits backlog

ID Severity Status Finding Acceptance when fixed Suggested owner / phase
Gap #1 Medium Closed Phase 0 used durability-"C1-class," colliding with fitness C1 / R3 and VISION machine-class C1 G1.1-G1.6 above Done (2026-07-12 scrub)
Gap #2 Medium Closed (worktree) Decision 1 README surface: intro monorepo-bindings; Constraints product engine Lean-only + ffi/<lang>/ exception; Status names open residual R17; ref/heed + PRIOR-ART heed family A7 fully accepted README hygiene 2026-07-12
Gap #3 Low (nice-to-have) Closed (2026-07-12) Operator docs lacked R17 / heed-bindings cross-links after residual land At least one clear "bindings residual R17 -> GAPS / PLAN / HEED-MAP / TESTING" line in VISION (and/or API foreign section); LIMITS optional Phase 5 docs honesty - VISION + LIMITS cross-links landed
N1 Low Closed (2026-07-13) UPS expansion inconsistent: release notes hygiene + PRIOR-ART expand uninterruptible power supply (UPS); Phase 0 release notes row and GAPS last-updated still bare UPS First use in each major section expands UPS (AGENTS doc language) Done - board + PLAN-REMAINING mark N1 done; operator docs expand UPS on first use
N2 Low Closed (2026-07-13) GAPS last-updated prepend is one dense line; C1/R3 disambiguation is greppable but hard to scan Prefer short dated bullets for new residual/policy notes (Workstream K hygiene) Done - board + PLAN-REMAINING mark N2 done; residual density accepted as Workstream K style for long last-updated lines
N3 Info Noted Dirty worktree mixes Phase 0/1 docs with prior Lean/FFI residual; staged/unstaged mixed Human land splits coherent slices; agents do not commit Human git only
N4 Low Closed (worktree) README Constraints + Status R17 naming A7 residual closed with Gap #2 Done 2026-07-12

Phase 0 polish handoff (finish A7 residuals + optional nits)

Status: done (A7 full; N1/N2/N4 + Gap #2/#3 closed). Historical note only - do not re-open as board work.

Owner (historical): docs agent Writes only (historical): README.md (N4 for full A7); docs/API.md / docs/VISION.md (Gap #3); UPS first-use (N1). No Lean / ffi/ code.

Required for full A7 (landed):

  1. README Constraints: Lean-only applies to product engine; ffi/<lang>/ foreign-bindings exception (point at AGENTS).
  2. README Status open residuals: name R17 (or "see GAPS R17") alongside R7 partial.

Nits: N1 UPS expand closed; N2 GAPS density closed (accepted residual style). Gap #3 closed Phase 5 (VISION + LIMITS R17 cross-links).

Exit: N4 closed -> A7 fully accepted; Gap #2 closed. Gap #3 closed Phase 5. N1/N2 closed 2026-07-13 (board agreement).


Execution order

flowchart TD
  P0[Phase 0 policy + residual]
  P1[Phase 1 ref/heed pin]
  P2[Phase 2 study + triage]
  P3[Phase 3 crate v0 dual write]
  P4[Phase 4 T0+T1 flake gates]
  P5[Phase 5 docs polish]
  P6[Phase 6 growth; ACID required + measure]
  P0 --> P1
  P0 --> P2
  P1 --> P2
  P2 --> P3
  P3 --> P4
  P3 --> P5
  P4 --> P6
Loading
  • P0 first for AGENTS/GAPS honesty.
  • P1 non-blocking for study if temporary upstream tree used.
  • P3 needs existing beastdb-lib / C ABI (in tree).
  • P4 flake gates are agent-complete definition of "tests done."
  • Do not serialize on human git publish.

Risks

  1. Scope explosion toward lmdb.h - freeze T1; growth only by measure/need.
  2. Txn illusion - dual paths + loud rustdoc; no fake multi-key atomicity.
  3. Fork/exec hides under nice API - measure; bulk ABI / same-process export when needed.
  4. WAL vs local-power story drift - product files may still say WAL; keep bindings + LIMITS aligned; separate product change to drop WAL if desired.
  5. heed3 encryption creep - out of v0; contrast-only in docs.
  6. Namecheck / productSrc - include ffi/rust/** like other ffi/; exclude ref/heed.

Master handoff prompts (sub-agents)

Phase 0: ✅ policy accepted - AGENTS + GAPS R17 + PRIOR-ART + release notes + local-power durability (Gap #1 scrub closed); README Decision 1 / Gap #2 / N4 closed in worktree. Phase 0 polish: ✅ done - N1 UPS first-use closed; N2 GAPS density closed; Gap #3 closed in Phase 5. No engine code.

Phase 1: ✅ done - ref/heed @ v0.22.1 / 86cd1f681953cd5f6870706f6139b851e975975e; inventory + PRIOR-ART updated.

Phase 2: ✅ done - docs/HEED-MAP.md; frozen T1-01...T1-12; codec + C ABI growth + batch notes. No crate implementation.

Phase 3: ✅ done - ffi/rust/beastdb v0 + checks.beastdb-rust-smoke (immediate + batch + bytes + corrupt fail-closed).

Phase 4: ✅ done - T0+T1 flake checks + skip matrix; residual R17 closed. No full upstream suite gate.

Phase 5: ✅ done (docs honesty) 2026-07-12 - suite provenance (heed3 tests zero), thin v0 completeness, Gap #3 VISION/LIMITS R17 cross-links; non-claims locked.

Phase 6: advanced (partial) 2026-07-13 - done: bulk multi-put (P1), contains (P2a), product delete (P2b/P6-DEL), Mode B flush policy (size/count + P6-BATCH-TIME), P6-EXPORT PR0/PR0b/PR1/PR2, P6-CURSOR, P6-ACID (API v7 atomic batch), P6-RANGE (API v8 reverse/range/first-last/neighbors), D1 (API v9 len/is_empty/clear/delete_range), D2 (RoTxn + T2 8 + MIGRATE-HEED), D3 measure (M2), R7-BYTES (export get densify + bulk memcpy), R7-SCAN (lazy external-pair scan; R7 still deeper partial) + R7-SNAP docs (EXPORT reopen/sync visibility honesty; not LMDB MVCC) - PLAN-COMPLETED.md. Tier 0: heed non-encrypted drop-in; P6-ACID done; P6-RANGE done; D1 done; D2 done; D3 measure done; R7-BYTES done; R7-SCAN done; R7-SNAP docs done; P6-WAL optional/deprioritized. Open (actionable): PLAN-REMAINING.md - default next G1 human. Do not invent full Phase 6 closed or R7 closed.


Out of scope for this plan

  • Agents committing, pushing, tagging, or G1 forge checklist (human git only; do not plan around it).
  • Full heed/heed3 suite green on beastdb.
  • NIST / heed3 encryption product.
  • Claiming LMDB wire or power-fail durability.