IAddon implementation for hive-proximum — temporal/bitemporal memory backend.
Follows the hive-tmux exemplar: reify + nil-railway pipeline. Zero compile-time hive-mcp dependencies — all resolved via requiring-resolve.
Registers a Datahike-backed IMemoryStore implementing bitemporal storage (IMemoryStoreTemporal). Backend: Datahike 0.8.1667.
Usage: ;; Via addon system (auto-discovered from META-INF manifest): (init-as-addon!)
IAddon implementation for hive-proximum — temporal/bitemporal memory backend. Follows the hive-tmux exemplar: reify + nil-railway pipeline. Zero compile-time hive-mcp dependencies — all resolved via requiring-resolve. Registers a Datahike-backed IMemoryStore implementing bitemporal storage (IMemoryStoreTemporal). Backend: Datahike 0.8.1667. Usage: ;; Via addon system (auto-discovered from META-INF manifest): (init-as-addon!)
IShutdownHook for the Proximum Datahike-backed temporal store. Priority 215 — runs after pure client closers (qdrant/chroma at 210) because Proximum syncs its konserve backing store to disk before releasing the Datahike connection, and may share a classloader path with other datahike-backed stores that need to settle first.
Binds IShutdownHook and the lifecycle registry from hive-spi, so there is
no compile-time coupling to hive-mcp at all. The memory ports are reached
by runtime resolve, matching hive-proximum.init.
Sync+close sequence:
disconnect! (flushes konserve under the hood).Each step is independently guarded; a failure in one does not skip
the next. The outer try catches Throwable so the orchestrator's
priority walk continues on error.
IShutdownHook for the Proximum Datahike-backed temporal store.
Priority 215 — runs after pure client closers (qdrant/chroma at 210)
because Proximum syncs its konserve backing store to disk before
releasing the Datahike connection, and may share a classloader path
with other datahike-backed stores that need to settle first.
Binds IShutdownHook and the lifecycle registry from hive-spi, so there is
no compile-time coupling to hive-mcp at all. The memory ports are reached
by runtime resolve, matching `hive-proximum.init`.
Sync+close sequence:
1. (hive-proximum.state/get-handle) — snapshot backend handle
2. Release Datahike connection via the store's protocol
`disconnect!` (flushes konserve under the hood).
3. (hive-proximum.state/clear-handle!) — atom bookkeeping.
Each step is independently guarded; a failure in one does not skip
the next. The outer `try` catches Throwable so the orchestrator's
priority walk continues on error.Atom-based state for Proximum bitemporal memory backend.
Holds backend handle (Datahike connection + config) once initialized.
Atom-based state for Proximum bitemporal memory backend. Holds backend handle (Datahike connection + config) once initialized.
Datahike-backed IMemoryStore + IMemoryStoreTemporal for hive-proximum.
Bitemporal design:
Protocol extension uses extend (function, not macro) to avoid
compile-time dependency on hive-mcp.protocols.memory.
Backend: Datahike 0.8.1667 (matches hive-mcp/hive-knowledge)
Datahike-backed IMemoryStore + IMemoryStoreTemporal for hive-proximum. Bitemporal design: - Every write is a new Datahike transaction (immutable fact log) - Updates add new facts; old values preserved in history - Deletes set :entry/deleted? true (tombstone, never hard-delete) - Temporal queries use d/as-of and d/history for time-travel Protocol extension uses `extend` (function, not macro) to avoid compile-time dependency on hive-mcp.protocols.memory. Backend: Datahike 0.8.1667 (matches hive-mcp/hive-knowledge)
Typed config for the Proximum HNSW vector store, resolved via hive-di defconfig. Mirrors the DatalevinKGConfig surface so a vec slot's backend swap is config-driven, not code-driven.
Resolution per field (via hive-di coalesce):
Lives in hive-proximum (the consumer of the proximum HNSW lib);
hive-mcp depends on hive-proximum and late-binds via
hive-mcp.knowledge-graph.slots.factory/backend->store :proximum.
Typed config for the Proximum HNSW vector store, resolved via hive-di defconfig. Mirrors the DatalevinKGConfig surface so a vec slot's backend swap is config-driven, not code-driven. Resolution per field (via hive-di coalesce): 1. Explicit override map (caller passes :db-path / :dim) 2. HIVE_VEC_PROXIMUM_PATH / HIVE_VEC_PROXIMUM_DIM env var 3. ~/.config/hive-mcp/config.edn at [:services :proximum <key>] 4. Hardcoded XDG default Lives in hive-proximum (the consumer of the proximum HNSW lib); hive-mcp depends on hive-proximum and late-binds via `hive-mcp.knowledge-graph.slots.factory/backend->store :proximum`.
IVecStore — role-sized port for vector index storage backends.
Lives in hive-proximum (the provider) so consumers can late-bind via
requiring-resolve without dragging hive-proximum's full classpath
into their compile-time graph. The protocol is the contract; the
record is the deliverable; nothing else crosses the seam.
Lifecycle methods (open!, close!) live ON this protocol — NOT
on a sibling lifecycle protocol — to avoid the JVM-level method-name
collision that defrecord raises when one record satisfies two
protocols that share a method name.
Naming note: vec-count (not count) is used because defrecord
inherits clojure.lang.Counted/count and a same-named protocol
method would collide on the Java method signature.
IVecStore — role-sized port for vector index storage backends. Lives in hive-proximum (the provider) so consumers can late-bind via `requiring-resolve` without dragging hive-proximum's full classpath into their compile-time graph. The protocol is the contract; the record is the deliverable; nothing else crosses the seam. Lifecycle methods (`open!`, `close!`) live ON this protocol — NOT on a sibling lifecycle protocol — to avoid the JVM-level method-name collision that `defrecord` raises when one record satisfies two protocols that share a method name. Naming note: `vec-count` (not `count`) is used because `defrecord` inherits `clojure.lang.Counted/count` and a same-named protocol method would collide on the Java method signature.
ProximumVecStore — IVecStore adapter over the proximum HNSW index (org.replikativ/proximum, ref: clones-ref/proximum).
Two design constraints drive the shape of this namespace:
Late-bind via requiring-resolve so a consumer that omits the
proximum jar still compiles. The dep IS declared in this
project's deps.edn, but addon-style isolation keeps the slot
system honest — failures surface as :slot/factory-failed
upstream instead of class-load errors.
The proximum API is immutable (every op returns a new index value). Consumers cache one handle per slot and share it across the swarm, so we wrap the immutable index in an atom and synchronise mutations under it. Concurrent writers serialise through the atom, concurrent readers see a consistent snapshot.
Reopen flow:
open! first attempts proximum.core/load against the existing
Konserve filestore. On miss (first boot / empty dir) it falls
back to proximum.core/create-index. This means a process
restart with the same :db-path resumes the same vectors —
no manual snapshot wiring required.
ProximumVecStore — IVecStore adapter over the proximum HNSW index (org.replikativ/proximum, ref: clones-ref/proximum). Two design constraints drive the shape of this namespace: 1. Late-bind via `requiring-resolve` so a consumer that omits the proximum jar still compiles. The dep IS declared in this project's deps.edn, but addon-style isolation keeps the slot system honest — failures surface as `:slot/factory-failed` upstream instead of class-load errors. 2. The proximum API is *immutable* (every op returns a new index value). Consumers cache one handle per slot and share it across the swarm, so we wrap the immutable index in an atom and synchronise mutations under it. Concurrent writers serialise through the atom, concurrent readers see a consistent snapshot. Reopen flow: `open!` first attempts `proximum.core/load` against the existing Konserve filestore. On miss (first boot / empty dir) it falls back to `proximum.core/create-index`. This means a process restart with the same `:db-path` resumes the same vectors — no manual snapshot wiring required.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |