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.
- Pin Meilisearch heed (the monorepo that contains heed and heed3) under
ref/as study prior art. - 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.
- Use heed's test suite as a requirements catalog + selective port, not as "drop in and
cargo testagainst beastdb." - Optimize for maximal flexibility and performance in the bindings + write path (both immediate and batched strategies).
- Priority track (Tier 0 master, 2026-07-13): migrate typical heed / heed3 non-encrypted call sites to
beastdbwith minimal code change (heed-shaped API + beastdb semantics). This is a heed3 drop-in replacement for non-crypto uses - not full heed3 encryption, notlmdb.h, not full suite green.
| # | 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. |
| 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
beastdbRust crate after heed ergonomics, mapped onto beastdb truth + dual write paths.
| 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/.
| 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.
| 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 |
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."
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+.
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 # 86cd1f681953cd5f6870706f6139b851e975975ePin: 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/. ✅
Owner: research agent (no product engine code) Landed: docs/HEED-MAP.md (full triage). PRIOR-ART + release notes + this plan status updated.
- Public API inventory - Env, options, Database, Ro/Rw txn, iterators, flags, errors (heed primary; heed3 delta = encryption only). ✅
- Test inventory - classify Port / Adapt / Skip / Needs product (and Needs batch API). ✅
- Codec layer - reimplement
BytesEncode/BytesDecode+ Bytes/Str only in crate; no upstream link. ✅ - C ABI growth list prioritized by performance (bulk multi-put P1, delete/contains P2, same-process export P3, iterate P4). ✅
- 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. ✅
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.
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:
- Port only Phase-2 T1 list with
// inspired by ref/heed/.... - Matrix of skipped tests + reason (doc).
- Wire T0+T1 into
flake.nixchecks / test-suite map (docs/TESTING.md).
Exit: named checks green for T0+T1; skip matrix published; residual R17 closed.
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 |
| 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 |
| 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.
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.
| # | 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+.
| # | 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 |
| 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 |
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):
- README Constraints: Lean-only applies to product engine;
ffi/<lang>/foreign-bindings exception (point at AGENTS). - 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).
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
- 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.
- Scope explosion toward
lmdb.h- freeze T1; growth only by measure/need. - Txn illusion - dual paths + loud rustdoc; no fake multi-key atomicity.
- Fork/exec hides under nice API - measure; bulk ABI / same-process export when needed.
- WAL vs local-power story drift - product files may still say WAL; keep bindings + LIMITS aligned; separate product change to drop WAL if desired.
- heed3 encryption creep - out of v0; contrast-only in docs.
- Namecheck / productSrc - include
ffi/rust/**like otherffi/; excluderef/heed.
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.
- 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.