AndaDB is a modular Rust workspace for embedded AI memory systems. The core
anda_db crate is a schema-aware document database with B-Tree, BM25, and HNSW
retrieval, backed by object_store. anda_kip is the protocol SDK;
anda_cognitive_nexus is the stateful KIP executor over AndaDB. The independent
TypeScript engine in ts/kip-do uses SQLite-backed Cloudflare Durable Objects.
- Work independently as the current agent. Do not spawn or delegate work to subagents.
- Before editing, run
git status --short, confirm the current branch, and inspect existing diffs in the files you intend to change. Preserve the user's existing work; do not overwrite or revert unrelated files or changes. - Use
rgfor search and focused reads before editing. Do not assume module boundaries from filenames alone. - Before committing, review the final diff and stage only the files or hunks belonging to the requested task.
- At completion, briefly summarize the changes, the checks actually run and their results, and any checks not run or blocked. Never report an unrun check as passing. When committing, include the branch and commit ID in the summary.
Before writing Rust code that uses AndaDB, or changing its API examples, read skills/anda-db/SKILL.md. It owns the dependency template and runnable quick start; keep examples there instead of duplicating them in this document. Read supporting references only as needed:
| Task | Reference |
|---|---|
| Lifecycle, CRUD, indexes, search, pagination | Core API |
| Derives, type mapping, schema upgrades, serialization | Schemas and CBOR |
| Backends, encryption, cache budgets, recovery, shutdown | Storage and recovery |
| KIP, Nexus, Brain host integration, cross-engine checks | KIP and Cognitive Nexus |
Use the checked-out implementations and manifests as the authority when prose or older examples disagree. Update affected documentation alongside public API or behavior changes.
rs/
├── anda_db/ # Core embedded database
├── anda_db_schema/ # Schema, FieldType, FieldValue, Document
├── anda_db_derive/ # AndaDBSchema and FieldTyped derives
├── anda_db_btree/ # Exact-match and range index
├── anda_db_tfs/ # BM25 full-text search
├── anda_db_hnsw/ # HNSW vector index
├── anda_db_utils/ # Standalone UniqueVec; no workspace users
├── anda_object_store/ # Metadata and encrypted storage wrappers
├── anda_kip/ # KIP SDK, specs, grammar, wire schemas
├── anda_cognitive_nexus/ # Stateful Rust KIP executor
├── anda_db_server/ # HTTP server for core database APIs
├── anda_cognitive_nexus_server/ # HTTP/JSON-RPC server for Nexus
├── anda_db_shard_proxy/ # Multi-tenant shard proxy
├── anda_kip_wasm/ # Parser test oracle; separate workspace
└── cf-tokenizer/ # Stateless Jieba HTTP service; separate workspace
ts/kip-do/ # Independent TypeScript KIP engine
py/anda_cognitive_nexus_py/ # Python binding; not a default workspace member
fixtures/kip-conformance-2.0/ # Shared cross-engine conformance fixtures
skills/anda-db/ # Agent-facing API usage guidance
docs/ # Technical and maintenance guides
Root cargo --workspace commands do not include the separate WASM/tokenizer
workspaces, TypeScript, or the Python binding.
The root workspace uses Rust edition 2024 with MSRV 1.95. Rust crates are
in the 0.14 release family; patch versions can diverge after a release,
so read each Cargo.toml instead of assuming a shared patch version. Use workspace
dependencies and existing feature conventions when editing workspace crates.
The root Cargo.lock is ignored, but the server's Docker build uses the tracked
rs/anda_cognitive_nexus_server/Cargo.lock with --locked: refresh it with
cp Cargo.lock rs/anda_cognitive_nexus_server/Cargo.lock whenever a crate
version or dependency changes.
object_storeis on 0.14.anda_db/fullonly enablesobject_store/fs; core indexes and Jieba are already available without that feature.- Use
cbor2for CBOR,cbor2::serialized_sizefor encoded sizes, andcbor2::to_canonical_vecwhere deterministic bytes are required. Do not introduce directciboriumusage. - Stored embeddings use
Vectorandvector_from_f32; query vectors useVec<f32>. Preserve the embedding model's dimension and metric. - Share one live writer instance per database namespace. Clone database and
collection handles for concurrent tasks;
DBConfig::lockis not a writer lease. Await mutations, flushes, and closes to completion; cancellation can poison a handle, requiring reopen/recovery through the database. - Return heavy async work boxed. A debug build keeps each awaited future in its
caller's frame, so inlined futures add up along a call chain and once took a
host past a 2 MiB thread stack. Write an I/O or multi-step API as
fn f(..) -> impl Future<Output = R> + Send { Box::pin(async move { .. }) }(drop+ Sendonly where a generic parameter decides it: a callback, or a borrowed&Tthat would otherwise needT: Sync). A wrapper that only forwards returns the callee's boxed future as is. Keep helpers called per row in a loop asasync fn, and keeprs/anda_cognitive_nexus/tests/stack_budget.rsgreen. See testing guidance. - Install tokenizers and deterministic index hooks at the start of each fresh
open callback, before recovery-triggering operations. Active cached handles
skip callbacks. Use
db.close_collection(name)before reopening to change schema/index configuration. - Multi-field B-Tree indexes are always unique. Their encoded keys support
tuple equality, not tuple-ordered ranges.
_idis queryable without an explicit B-Tree index. - Schema upgrades preserve persisted field indexes and require a higher version; new fields must be optional. Storage settings are fixed on first initialization and are not changed by passing a different startup config. See the references before implementing migrations or storage reconfiguration.
KIP protocol versions are distinct from Cargo package versions. The repository
implements KIP 2.0 (KIP 11a82ec) with the vendored cognitive-memory@2.0.0
draft package; use the
vendored specification and
syntax reference.
Protocol timestamps follow §6.5: UTC strings in YYYY-MM-DDTHH:mm:ss.SSSZ
form, including .000Z for whole seconds. Reject noncanonical inputs;
truncate engine clocks to milliseconds. Use space_seq for commit order.
A Proposition is truth-neutral; Assertions record claims and BELIEF projects
them under a policy. Governance and Schema Packages have separate control
planes. Hosts construct authenticated session context; user request fields
must not choose their own authority.
Check DESCRIBE CAPABILITIES on the relevant engine before relying on optional
behavior. Parsing a command or installing a profile does not install an
embedding model, scheduler, evaluator, or executor. For Watch/wake/dispatch and
learning integration, read the Brain host contracts.
For old stores, follow the KIP 1.x migration guide.
rs/anda_kip/FunctionDefinition.json and FunctionDefinitionReadonly.json are
the model-facing execute_kip tool definitions that Anda Engine and Brain hand
to model providers. Never use oneOf, anyOf or allOf in them or in any
other model-facing schema: Anthropic rejects them at the top level of a tool's
input_schema and fails the whole request with a 400 (a top-level oneOf once
broke every Brain pass on Claude), and strict modes reject them anywhere. Use a
type list ("type": ["string", "object"], ["string", "null"]) for
alternatives, enforce cross-field rules such as "exactly one of command or
operations" when parsing, and state them in the descriptions;
the_function_definitions_use_no_schema_combinators guards both files. The
protocol validation schemas under rs/anda_kip/schemas/ are never sent to a
model and may use them.
Run commands from the repository root unless stated otherwise. Choose checks for the changed behavior; documentation-only edits need link/consistency checks and compilation of changed runnable examples, not unrelated full suites.
| Scope | Command |
|---|---|
| Rust workspace compile | cargo check --workspace --all-features |
| Rust workspace tests | cargo test --workspace --all-features |
| Core database unit and integration tests | cargo test -p anda_db --all-features |
| Core crash recovery and format compatibility | cargo test -p anda_db --test crash_recovery --test format_compat |
| Schema and derive changes | cargo test -p anda_db_schema -p anda_db_derive |
| KIP SDK and Rust executor | cargo test -p anda_kip -p anda_cognitive_nexus |
| TypeScript typecheck and tests | make test-ts |
| Formatting and Clippy | make lint |
make lint runs cargo fmt and can change files. For a formatting check
without edits, use cargo fmt --all -- --check.
make test-all adds format-compatibility checks and KIP fuzzing to Rust tests.
make test-full also runs TypeScript checks. Fuzzing requires nightly and
cargo-fuzz; TypeScript checks require installed dependencies and pnpm. The
current TypeScript CI uses Node 24 and pnpm 11; see
the CI workflow for the matching setup.
When changing persistence/recovery, verify crash consistency and existing format fixtures. For index algorithm changes, run the affected index crate's tests, including its property/recall checks. See testing guidance. Do not regenerate old fixtures merely to make an incompatible change pass.
The runnable core example is
cargo run -p anda_db --example db_demo --features full; it creates data under
./debug/metastore. Keep documentation-example test data in a temporary
directory. For Python tests, follow the root Cargo.toml / make test-py
instructions to enable the binding member and select its supported interpreter.
ts/kip-do tests shared conformance fixtures and compares its parser against
the committed Rust WASM oracle. Protocol changes should be checked in both
engines; a default Rust workspace test does not exercise TypeScript.
When generation sources change, run pnpm run codegen from ts/kip-do
and include the generated diff:
src/errors.generated.tssrc/meta/capability-names.generated.tssrc/schema/profiles.generated.tssrc/schema/contracts.generated.tstest/conformance/fixtures.generated.tstest/oracle/corpus.generated.ts
The oracle corpus is harvested from the shared conformance fixtures and from
every KIP command string literal in the src/ and tests/ directories of
rs/anda_kip and rs/anda_cognitive_nexus. Adding or editing such a string
is a generation-source change even when the commit touches only Rust tests:
regenerate before committing, or the CI TypeScript job fails its drift check.
When the Rust KIP parser changes, also run pnpm run build:oracle-wasm from
ts/kip-do and include the updated vendor/anda_kip_wasm/ artifacts. This
requires wasm-pack and the WASM target toolchain. pnpm run codegen does not
rebuild the oracle. Then run make test-ts from the repository root. CI
regenerates the TypeScript files and rejects drift.