Skip to content

C ABI

Crate holographic-memory-c (bindings/c), header bindings/c/include/holographic_memory.h (generated by bindings/c/scripts/gen-header.sh, cbindgen). Libraries: cdylib, staticlib, rlib. Go, Java and .NET wrap this ABI.

Surface

open/close store (path, dimensions, encryption key, signing, audit, embedding space), batch ingest (BM25 title_weight, chunking, optional embeddings, metadata JSON), search (k, candidate limit, filter, source URI, document ids, query embedding, lexical/semantic weights, fusion blend/rrf, bm25_k1, bm25_b), delete, stats, security status (encryption active), flush, compact, maintain, snapshot (verified point-in-time copy), chunk a document without a store.

Contract

  • Every fallible call returns hms_status_t (0 = HMS_OK); the failing thread's hms1_last_error_code() and hms1_last_error_message() describe it. The slot is per thread: read it right after the call on the same OS thread.
  • No panic crosses the boundary (catch_unwind, HMS_ERR_PANIC).
  • Strings are hms_str_t (pointer + length, UTF-8, not NUL terminated). NULL pointer with length 0 means "absent". Lengths are bounded (HMS_MAX_BUFFER_BYTES 1 GiB, HMS_MAX_ARRAY_LEN 2^24); nothing is allocated from a caller-supplied size.
  • Zero-initialised option structs mean all defaults (set struct_size, or call hms1_*_options_init). Numeric search overrides are honoured only when their HMS_SEARCH_SET_* flag is set. Structs that begin with struct_size grow append-only; out-structs (stats, security_status) are filled only up to the caller's struct_size.
  • Thread safety: a store handle is safe from any number of threads. hms1_store_close may run while calls are in flight; they finish first. Handles are never-reused tokens: a stale handle returns HMS_ERR_INVALID_HANDLE, never aliasing a later store. Result/chunk sets are immutable; concurrent reads are fine, free must not race with reads, double free is undefined, NULL is ignored.
  • A store directory is held by one handle at a time across processes (HMS_ERR_LOCKED).
  • Ingest is atomic per batch. Snapshot blocks mutations (not searches) while copying, then verifies the copy before publishing it.

Versioning

Symbols are hms1_* (ABI major in the name; unversioned hms_* aliases are macros, disable with HMS_NO_ALIASES). hms1_abi_version() returns major<<16|minor<<8|patch. Minor: new functions and appended struct fields. Major: new symbol prefix, so two majors can coexist in one process. Document and result structs are fixed in v1; changing them needs a new function.

Build and test

export CARGO_TARGET_DIR=/path/to/private/target
bindings/c/tests/c/run.sh              # C program vs shared and static library
MODE=leaks bindings/c/tests/c/run.sh   # macOS leaks(1); MODE=valgrind on Linux
cargo test --manifest-path bindings/c/Cargo.toml   # header layout vs C compiler, counting-allocator leak test
bindings/c/scripts/package-native.sh [rid [rust-target]]   # release archive + sha256
Archive names: holographic-memory-c-<version>-<rid>.tar.gz, rid in osx-arm64 osx-x64 linux-x64 linux-arm64 win-x64 win-arm64 plus win-x64-gnu (MinGW static library for Go on Windows).

Verified here (macOS arm64)

C program with shared and static linking, leaks: 0 leaks; counting-allocator test (fails when results are not freed); layout test against the system C compiler; Rust 1.89 compile, clippy 1.99; cargo check for x86_64 Linux and x86_64 Windows MSVC. Linux/Windows execution is not verified locally (.github/workflows/bindings.yml runs it).

Known engine gap

With encryption on, the engine writes chunk text to documents.text unencrypted (transaction log, vectors and indices are encrypted). The ABI tests report this and fail on it only with HMS_STRICT_AT_REST=1. Fix belongs in src/core/engine (encrypt the text segment).