feat(module): five new capability families and OpenStore for per-subtree stores - #16
Conversation
…r, and store Introduces a new address book feature for managing people, including a SQL migration for initial schema setup, a resolver for looking up contacts, a scorer for ranking relevance, and a store for persistence. This change also adds the corresponding types and tests to support the module. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When looking up a person by name, an empty string previously caused a panic due to an unwrap on a missing match. This change adds an early return for empty names, returning None instead of panicking. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Enabling the default features of cfg-if ensures that the library provides its full standard functionality, which may include important traits or utilities required by the core crate. Without default features, certain cfg-if macros or conditional compilation helpers could be missing, leading to compilation errors or unexpected behavior. This change resolves that by restoring the default feature set. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated the dependency specifications in the core crate's Cargo.toml to align with the latest compatible versions, ensuring the project builds against current releases without breaking changes. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce new capability and version modules to the API, along with their corresponding tests and integration into the provider layer. This change enables the API to manage and report supported capabilities and version information, which is necessary for client negotiation and feature discovery. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add a check for the case where provider configuration is absent, returning an appropriate error instead of panicking or proceeding with uninitialized state. This ensures the system fails gracefully when required provider settings are not provided. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Add support for null values in the API by implementing proper null handling in the null.rs module, ensuring that null inputs are correctly processed and returned without causing errors. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The API now exposes a new endpoint that returns a list of all available capabilities, allowing clients to discover supported features dynamically without hardcoding endpoint paths. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Return a 404 error when a driver is not found for a person, instead of silently returning an empty or incorrect response. This ensures the API correctly signals the absence of the associated resource. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a memory region is not found in the provider, the code now returns an appropriate error instead of panicking or proceeding with invalid state. This ensures graceful failure and clearer diagnostics for callers. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce the Cargo.toml file for the tinymemory-module crate, establishing its package metadata and dependencies to enable building and publishing the module. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory service returns an empty list of memories, the retrieval function now returns an empty result instead of failing with an error. This fixes a regression where valid queries with no matching memories were incorrectly treated as failures. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Update the tinycortex vendor submodule to its latest commit and synchronize the Cargo.lock file to reflect the new dependency versions. This ensures the project uses the most recent upstream changes. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Introduce a capabilities module that allows providers to declare and enforce access permissions for operations. This change adds capability checks to the provider driver and integrates them into the retrieval and chunking workflows, ensuring that only authorized actions are performed. The null provider and audit tests are updated to support the new capability model, and the tinymemory module is extended to declare its capabilities. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the cover set is empty, the retrieval logic now returns an empty result instead of panicking or producing undefined behavior. This ensures robustness when no matching nodes are found in the tree. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When retrieving a node from the tree, the code now correctly handles the case where a parent node is absent, preventing a potential panic or incorrect traversal. This ensures robust navigation of incomplete tree structures. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory provider attempts to look up a region that does not exist, it now returns an appropriate error instead of panicking or returning undefined behavior. This change improves robustness by ensuring the provider gracefully handles absent regions rather than assuming they are always present. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
…s/tinymemory-module/src/provide Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
…provider/people.rs,api/src/prov Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
…rieval/source.rs Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Co-authored-by: Medulla <medulla@tinyhumans.ai>
Adds a new `recall_namespace_scored` method to the retrieval trait that returns hits with their score breakdown, allowing hosts to re-rank results using their own weight profiles. The method also supports excluding a session's auto-saved documents to prevent self-echo during mid-turn searches. The null provider returns unsupported, while the module provider delegates to the unified store and the service exposes it as a bus operation. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a memory region is not found in the provider, the code now returns an appropriate error instead of panicking or proceeding with invalid data. This ensures graceful failure and clearer diagnostics for callers. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The memory module service now returns an empty result instead of panicking when given an empty input, ensuring graceful handling of edge cases in the processing pipeline. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory service receives a request to list memories but no memories exist, the service now returns an empty list instead of an error. This change ensures consistent behavior across different memory states and prevents unnecessary error handling on the client side. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory service receives a request to list memories but no memories exist, it now returns an empty list instead of failing with an error. This makes the API more robust and consistent with expected behavior for empty states. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory service receives an empty list of memories, it now returns an empty result instead of panicking or producing undefined behavior. This change adds a guard clause to check for an empty input and return early, ensuring the service behaves correctly in edge cases where no memories are provided. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory provider attempts to look up a region that does not exist, it now returns an appropriate error instead of panicking or returning an undefined state. This ensures the provider behaves predictably and safely when queried for absent memory regions. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory service receives an empty list of memories, it now returns an empty result instead of panicking. This fixes a crash that occurred when the service was initialized without any pre-existing memories. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The service now returns an empty result instead of panicking when given an empty input, ensuring graceful handling of edge cases in the memory module. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the memory service receives a request to list memories but no memories exist, it now returns an empty list instead of an error. This change ensures consistent behavior across different memory states and prevents unnecessary error handling on the client side. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The documentation in the null provider and provider module was updated to reflect that the number of optional capability families has grown from thirteen to fifteen, and the total number of families from sixteen to eighteen, matching the current implementation. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a source file is not found during tree retrieval, the system now returns an appropriate error instead of panicking. This ensures that missing files are handled consistently and the retrieval process can continue or report the issue clearly to the caller. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a source file referenced in the tree is missing from disk, the retrieval process now returns an appropriate error instead of panicking. This ensures the system degrades gracefully when the underlying file has been deleted or moved. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a source file referenced in the tree is not found on disk, the retrieval now returns an empty result instead of panicking. This ensures graceful degradation when the underlying file has been moved or deleted. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a memory module is not present, the provider now returns an empty result instead of panicking. This ensures the system remains stable during initialization or when optional memory modules are absent. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The `SourceQuery` type was not publicly exported from the retrieval module, making it inaccessible to external consumers even though the functions that use it were already exported. This change adds the missing re-export so that callers can reference the type directly. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the embedding endpoint receives an empty list of inputs, the service now returns an empty list of embeddings instead of failing with an error. This aligns the behaviour with the API specification and prevents unnecessary server errors for a valid edge case. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The embedding endpoint now returns an empty array instead of an error when given an empty list of inputs, matching the behavior of the OpenAI API. This change ensures consistent handling of edge cases in the embedding service. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a fetch operation fails, the code now checks whether the parent node exists before attempting to access it, preventing a panic in cases where the parent has been removed concurrently. This ensures graceful error handling instead of an unexpected crash. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a path contains consecutive slashes, the drill-down retrieval now correctly treats empty segments as root-level lookups instead of failing. This aligns the behavior with common filesystem conventions where multiple slashes are collapsed. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the drill-down path is empty, the function now returns an empty result set instead of panicking or producing undefined behavior. This ensures consistent behavior when no path segments are provided, matching the expected contract for tree retrieval operations. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When the drill-down path is empty, the function now returns an empty result set instead of panicking or producing undefined behavior. This ensures consistent behavior when no path segments are provided, matching the expected contract for edge cases in tree retrieval. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Return a 404 error when the requested provider is not found in the retrieval endpoint, instead of silently returning an empty or incorrect response. This ensures the API correctly communicates the absence of the resource to the caller. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The null memory provider's retrieval methods now accept an optional scope parameter, aligning their signatures with the trait definition and ensuring consistency across all memory provider implementations. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
The `drill_down` and `retrieve_leaves` methods now accept an optional `SourceScope` parameter, which is passed to the underlying engine functions to enable scoped retrieval. This allows callers to restrict results to a specific source scope when querying the memory tree. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
…aves The `RetrieveChildren` and `RetrieveLeaves` methods now accept an optional `SourceScope` argument, which is forwarded to the underlying retrieval implementation. This allows callers to constrain the search to a specific source scope rather than relying on ambient state, making the API more explicit and consistent with other retrieval methods that already accept a scope parameter. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
When a source file referenced in the tree is not found on disk, the retrieval now returns an empty result instead of panicking. This prevents crashes during partial or incomplete repository operations. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
Updated the test to properly verify that the service rejects requests exceeding the configured memory limit, ensuring the validation logic is correctly tested. Auto-committed-on: macbook Co-authored-by: Medulla <medulla@tinyhumans.ai>
|
@coderabbitai review Every actionable finding from the previous rounds is addressed and pushed. Summary of the substantive ones:
Four findings are declined with evidence and left unresolved for you to push back on: the config-propagation claim (the root store passes the same |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== Changed files ==='
git diff --name-only HEAD~1..HEAD 2>/dev/null || git diff --name-only origin/main...HEAD
printf '%s\n' '=== Service outline ==='
ast-grep outline crates/tinymemory-module/src/service/mod.rs --items all --view expanded
printf '%s\n' '=== Provider outline ==='
ast-grep outline crates/tinymemory-module/src/provider.rs --items all --view expanded
printf '%s\n' '=== Retrieval outlines ==='
ast-grep outline core/src/tree/retrieval --items all --type function,struct --view expanded
printf '%s\n' '=== Relevant symbol locations ==='
rg -n -C2 'struct StoreOpener|async fn open_store|fn open_store|serve_at|Interface::members|members\(|retrieve_children|retrieve_leaves|fetch_leaves_scoped|drill_down_scoped|format_embedding_signature|too_many_arguments|limit.*0|ChunkDetail|chunk_embeddings|get_chunk' \
crates/tinymemory-module/src/service crates/tinymemory-module/src/provider.rs crates/tinymemory-module/src/lib.rs \
crates/tinymemory-module/tests core/src/tree/retrieval api/src/host/embeddings.rs api/src/provider/chunks.rsLength of output: 53090 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== Store opener and OpenStore ==='
sed -n '168,405p' crates/tinymemory-module/src/service/mod.rs
printf '%s\n' '=== Manifest declaration and consistency test ==='
sed -n '185,290p' crates/tinymemory-module/src/lib.rs
sed -n '220,310p' crates/tinymemory-module/src/service/test.rs
printf '%s\n' '=== Retrieval bus methods and response-size utility ==='
sed -n '940,1015p' crates/tinymemory-module/src/service/mod.rs
sed -n '1248,1378p' crates/tinymemory-module/src/service/mod.rs
printf '%s\n' '=== Scoped retrieval provider methods and chunk reads ==='
sed -n '1490,1615p' crates/tinymemory-module/src/provider.rs
sed -n '1615,1750p' crates/tinymemory-module/src/provider.rs
printf '%s\n' '=== Scoped core retrieval implementations ==='
sed -n '1,120p' core/src/tree/retrieval/drill_down.rs
sed -n '1,105p' core/src/tree/retrieval/fetch.rs
sed -n '1,120p' core/src/tree/retrieval/cover.rs
sed -n '1,125p' core/src/tree/retrieval/source.rs
printf '%s\n' '=== Signature format implementation ==='
sed -n '1,135p' api/src/host/embeddings.rs
printf '%s\n' '=== Relevant regression-test locations ==='
rg -n -C2 'open_store|OpenStore|MAX_OPEN_STORES|retrieve_children|retrieve_leaves|response_fits|response.*size|join.*fail|JoinError|panic' \
crates/tinymemory-module/src/service/test.rs crates/tinymemory-module/tests core/src/tree/retrievalLength of output: 57452 🏁 Script executed: #!/bin/bash
set -euo pipefail
base="$(git merge-base HEAD origin/main 2>/dev/null || git merge-base HEAD main)"
printf '%s\n' "=== Merge base: $base ==="
printf '%s\n' '=== Diff checks ==='
git diff --check "$base"...HEAD
git diff --stat "$base"...HEAD
printf '%s\n' '=== All too_many_arguments allowances in the PR diff ==='
git diff -U4 "$base"...HEAD -- \
core/src/tree/retrieval/cover.rs core/src/tree/retrieval/source.rs \
crates/tinymemory-module/src/service/mod.rs \
| rg -n -C4 'too_many_arguments|SourceQuery|cover_window_scoped|create_segment|upsert_provider_facet' || true
printf '%s\n' '=== Root setup and factory calls ==='
rg -n -C5 'create_memory_client(_in_subdir)?\s*\(' \
crates/tinymemory-module/src core/src/store/factories.rs
sed -n '1,125p' core/src/store/factories.rs
printf '%s\n' '=== Blocking task join failure handling ==='
sed -n '235,265p' crates/tinymemory-module/src/provider.rs
rg -n -C4 'JoinError|spawn_blocking|join.*error|blocking\(' crates/tinymemory-module/src/provider.rs
printf '%s\n' '=== Exact chunk embedding return and contract signatures ==='
sed -n '1585,1625p' crates/tinymemory-module/src/provider.rs
sed -n '125,210p' api/src/provider/chunks.rs
printf '%s\n' '=== Scope-related diff and tests ==='
git diff -U3 "$base"...HEAD -- \
api/src/provider/retrieval.rs crates/tinymemory-module/src/provider.rs \
crates/tinymemory-module/src/service/mod.rs core/src/tree/retrieval \
| rg -n -C3 'retrieve_children|retrieve_leaves|scope|scoped' || true
rg -n -C3 'retrieve_children|retrieve_leaves|drill_down_scoped|fetch_leaves_scoped' \
crates/tinymemory-module/src/service/test.rs core/src/tree/retrieval/source_scope_tests.rs \
crates/tinymemory-module/tests || trueLength of output: 65972 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== Module setup and root client construction ==='
ast-grep outline crates/tinymemory-module/src/lib.rs --items all --type function --view expanded
rg -n -C8 'async fn setup|fn setup|create_memory_client|MemoryClient::|ModuleMemoryProvider::new|service::serve' \
crates/tinymemory-module/src/lib.rs crates/tinymemory-module/src/service/mod.rs
sed -n '1,190p' crates/tinymemory-module/src/lib.rs
printf '%s\n' '=== Subdirectory factory implementation ==='
sed -n '580,700p' core/src/store/factories.rs
rg -n -C5 'pub fn create_memory_client\(' core/src/store/factories.rs
printf '%s\n' '=== Join-error mapping and logging ==='
sed -n '1950,1980p' crates/tinymemory-module/src/provider.rs
rg -n -C3 'fn other\(|MemoryError::Other|fn into_bus_error|log::.*error' \
crates/tinymemory-module/src/provider.rs crates/tinymemory-module/src/service/mod.rs api/src/error.rs
printf '%s\n' '=== Scope predicate and available chunk provenance ==='
rg -n -C5 'fn chunk_source_allowed_in|chunk_source_allowed_in|pub struct Chunk|struct ChunkMetadata|source_id|tags' \
core/src/source_scope.rs core/src/store/chunks api/src/chunks.rs
sed -n '1,180p' core/src/source_scope.rs
printf '%s\n' '=== Cover-window request types ==='
sed -n '95,180p' api/src/provider/retrieval.rs
rg -n -C4 'CoverWindowQuery|cover_window_scoped\s*\(' \
api/src/provider/retrieval.rs core/src/tree/retrieval crates/tinymemory-module/srcLength of output: 23485 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== Locate scope and chunk model files ==='
fd -a -t f 'source_scope|chunks|error' core api | sort
printf '%s\n' '=== Join-error conversion and predicate handling ==='
sed -n '1950,1982p' crates/tinymemory-module/src/provider.rs
sed -n '195,222p' crates/tinymemory-module/src/provider.rs
sed -n '1380,1410p' crates/tinymemory-module/src/service/mod.rs
rg -n -C3 'join .*failed|join .*error|join failure|JoinError|workflow_identity_matches' \
crates/tinymemory-module/src/provider.rs api/src
printf '%s\n' '=== Scope predicate definitions and chunk fields ==='
rg -n -C6 'chunk_source_allowed_in|current_source_scope|pub struct Chunk|struct ChunkMetadata|source_id:|tags:' \
core api \
-g '*.rs'
printf '%s\n' '=== Cover-window request data and all uses ==='
rg -n -C8 'struct CoverWindowQuery|CoverWindowQuery\s*\{' api/src/provider/retrieval.rs \
crates/tinymemory-module/src/provider.rs crates/tinymemory-module/src/service/mod.rsLength of output: 170298
I verified these changes:
I do not withdraw the id-addressed chunk-read finding. The remaining I used the existing PR learning about scoped chunk reads during this review. Repository tests were not executed because the available sandbox does not run repository code. ✏️ Learnings added
🧠 Learnings used✅ Action performedReview finished.
|
Summary
OpenStore(memory_subdir) -> object_pathto the root object, letting one process serve more than one memory store without a store selector on every method.create_memory_client_in_subdirtotinymemory-core; the existing client factory hardcoded"memory".Problem
OpenHuman is dropping the
tinymemory*crates from its binary and reaching memory only through this module. Two things blocked that, and neither was a small gap:Four host surfaces had no wire equivalent — the people store, the chunk tier, the deterministic retrieval primitives, and the learned-facet profile. Each was reached by constructing an engine in the host process, which is precisely the split brain the module exists to end.
The archivist held a live
rusqlite::Connection. A connection cannot cross a bus, so while it existed the engine could never leave, whatever happened to everything else.A host with per-profile memory needs more than one store in a process.
setupbuilt exactly one client fromconfig.workspace_dirand served one object, sodedicatedMemoryprofiles had nowhere to go.Solution
The four families mirror the existing service shape: owned equivalents of the trait signatures,
scopealways an explicit argument (never inferred — the engine's task-local belongs to the host's task, and inferring here would read as absent, which means unrestricted, which is a source gate failing open).Episodic is the archivist's connection, decomposed. It turned out to need far less than "a raw connection" suggests: no ad-hoc SQL, no schema knowledge, ten typed calls — and two of those took no connection at all. Those two (boundary detection and the fallback summary) are host policy and stayed in OpenHuman; the other seven are this family. One deliberate change on the way across:
InsertTurnreturns the row id rather than leaving the caller to issueSELECT last_insert_rowid(). That was reading connection-local state — an interleaved insert from another task returns the wrong id and files the turn under the wrong segment. Returning it removes the race and a round trip together.OpenStoreis the interesting one, because the obvious designs were both wrong. A store selector on the wire means a parameter on every method of all 18 families, to express something that is not a property of a memory operation. Folding profile subtrees into namespaces avoids that but relocates user data on disk.Neither is necessary: which store you are talking to is settled when you are handed a driver, exactly like which workspace you are bound to. tinybus already serves many objects, so the root object opens stores and hands back object paths. Each is an ordinary
MemoryServiceexporting the identical interface — the contract does not change, and paths on disk stay where they are.Four decisions in it worth review:
StoreOpener, so the recursion is finite by construction rather than by a depth check.serve_atsucceeds. Two live handles to one SQLite file is not hypothetical — the engine migrates on open, and concurrent migrations on one file corrupt it invisibly. Caching the path before the serve succeeded would strand callers on a path nothing answers.setupkeeps filesystem detail out ofMethodFailed.message.create_memory_client_in_subdiris a separate entry point, not a parameter added to the existing factory. Every current caller wants the shared tree, and a defaulted subdir argument is exactly the kind of thing that silently routes a store somewhere nobody intended.Submission Checklist
Impact
checksum.toml, never recomputed locally.tinyhumansai/tinycortex#148(thepeopledomain); thevendor/tinycortexpointer here moves with it.Related
Depends on tinyhumansai/tinycortex#148 — merge that first.
Summary by CodeRabbit
New Features
Improvements