Co-authored-by: YellowSnnowmann <167776381+YellowSnnowmann@users.noreply.github.com> Co-authored-by: Steven Enamakel <31011319+senamakel@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Cyrus Gray <144336577+graycyrus@users.noreply.github.com> Co-authored-by: Horst1993 <horst.w@gmicloud.ai> Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: James Gentes <jgentes@users.noreply.github.com> Co-authored-by: Sam <samrusani@users.noreply.github.com> Co-authored-by: Sami Rusani <14844597+samrusani@users.noreply.github.com> Co-authored-by: oxoxDev <164490987+oxoxDev@users.noreply.github.com> Co-authored-by: Muhammad Ismail <78064250+myi1@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> Co-authored-by: nb213 <binyangzhu000@gmail.com> Co-authored-by: binyangzhu000-sudo <224954946+binyangzhu000-sudo@users.noreply.github.com> Co-authored-by: Steven Enamakel <enamakel@tinyhumans.ai> Co-authored-by: CodeGhost21 <164498022+CodeGhost21@users.noreply.github.com> Co-authored-by: sanil-23 <sanil@tinyhumans.ai> Co-authored-by: M3gA-Mind <elvin@mahadao.com> Co-authored-by: oxoxDev <oxoxdev@users.noreply.github.com> Co-authored-by: mysma-9403 <64923976+mysma-9403@users.noreply.github.com> Co-authored-by: mwakidenis <mwakidenice@gmail.com> Co-authored-by: NgoQuocViet2001 <123613986+NgoQuocViet2001@users.noreply.github.com> Co-authored-by: viet.ngo <viet.ngo@sotatek.com> Co-authored-by: Maciej Myszkiewicz <mmyszkiewicz@bwcoders.com>
12 KiB
TinyCortex API Gap Audit (Phase 0.2)
Status (2026-07-22): Historical gap inventory for the completed engine
cutover. Counts and source anchors below describe the audit base; unresolved
host consolidation work, including G1 re-homing and sync dedupe, is tracked in
tinycortex-migration-plan-2026-07-22.md.
Purpose. Map every host call site into the engine-mapping modules
(memory_store, memory_tree, memory_queue, and the long tail) onto a TinyCortex
public API. Where no crate API covers a host need, record a gap — each gap becomes a
tinycortex issue/PR (engine-side) or an explicit host-adapter decision, and gates the
workstream that touches it.
Anchors: host 7850cf363 · tinycortex d1a8c7be (v0.1.1). Crate API surface inventoried
from vendor/tinycortex/src/memory/** (pub traits/fns/types, verbatim signatures).
Call-site volume (host → engine, external references only)
External refs = uses of memory_<mod>::… from host code outside that module.
| Engine module | External refs | Maps to crate | Coverage |
|---|---|---|---|
memory_store |
454 | store/, chunks/ |
High — see per-API below |
memory_tree |
169 | tree/, retrieval/, score/ |
High (gaps G3, G5) |
memory_queue |
42 | queue/ |
High (drift D2) |
memory_sources |
35 | sources/ |
Full (local readers only) |
memory_conversations |
24 | conversations/ |
Full (drift D1) |
memory_tools |
12 | tool_memory/ |
Full |
memory_diff |
11 | diff/ |
Full |
memory_archivist |
9 | archivist/ |
Full |
memory_goals |
6 | goals/ |
Full |
memory_search |
1 | retrieval/, score/ |
tools stay host |
memory_entities |
0 | entities/ |
Full |
memory_graph |
0 | graph/ |
Derive-on-read (gap G2) |
Highest-traffic memory_store sub-APIs (external): chunks::store (152), chunks::types
(93), trees::types (54), create_memory (31), trees::store (27), profile (26),
types (19), content (19), content::compose (14), content::paths (10),
content::read (9), content::atomic (8), content::raw (7). All of chunks::*,
trees::*, content::*, profile map to crate re-exports (chunks::…, tree::…,
store::content::…, config::WeightProfile). create_memory is host glue (see below).
Seam-trait roster (the W1 adapter targets — all present in crate)
The crate exposes every seam the plan expects, plus more. Host implements these:
| Trait | Path | Host adapter (W1) |
|---|---|---|
EmbeddingBackend |
store/vectors/embedding.rs:32 |
tinycortex/embeddings.rs over openhuman::embeddings (amended: bridged to tinyagents::harness::embeddings::EmbeddingModel in W-EMB, plan §8.2) |
Embedder (retrieval/summarise) |
score/embed.rs:28 |
same seam file |
ChatProvider |
score/extract/llm.rs:70 |
tinycortex/chat.rs over memory::chat / inference |
Summariser (bucket-seal, structured) |
tree/summarise.rs:70 |
tinycortex/chat.rs |
Summariser (time-tree, string) |
tree/runtime/engine.rs:29 |
divergent — see G6 |
EntityExtractor (regex + LLM) |
score/extract/composite.rs:16 |
tinycortex/chat.rs (LLM variant) |
QueueDelegates |
queue/handlers.rs:96 |
tinycortex/queue_driver.rs |
TreeJobSink |
ingest/types.rs:15 |
tinycortex/ingest.rs |
TreeLeafSink |
archivist/sink.rs:44 |
tinycortex/ingest.rs |
SnapshotItemSource |
diff/source.rs:28 |
host diff adapter |
EntityOccurrenceIndex |
graph/types.rs:44 |
host graph adapter |
SelfIdentity |
store/entity_index/store.rs:25 |
host identity registry |
GoalsGenerator |
goals/reflect.rs:57 |
tinycortex/chat.rs |
SourceReader |
sources/readers/mod.rs:1732 |
local readers only (amended: live-sync readers join the crate in W-SYNC, plan §8) |
SyncEventSink (new, W-SYNC) |
sync/traits.rs (planned) |
tinycortex/sync_sink.rs → MemorySyncStage bus events |
SkillDocSink (new, W-SYNC) |
sync/traits.rs (planned) |
forwards to MemoryClient::store_skill_sync (host-retained unified tier) |
ConversationEventBus / ChannelEventHandler |
conversations/bus.rs:106/95 |
host memory_conversations/bus.rs (translate to DomainEvent) |
Config seam: MemoryConfig{workspace, embedding: EmbeddingConfig{dim,model,strict}, tree: TreeConfig{input_token_budget,output_token_budget,summary_fanout,flush_age_secs}, retrieval: RetrievalConfig{default_profile}, sync_budget: SyncBudgetConfig} +
WeightProfile{graph,vector,keyword,freshness} — all pub with the exact fields the W1
config.rs adapter maps Config onto.
Gaps (each → tinycortex issue/PR or explicit host-adapter decision)
G1 — Raw SQLite connection escape hatch (sqlite_conn()) — HARD, high blast radius
- Host: two trait methods return a live handle:
memory/traits.rs:277andmemory_store/memory_trait.rs:458fn sqlite_conn(&self) -> Option<Arc<Mutex<Connection>>>. ~312 references tosqlite_conn/raw_conn/with_connectionacross the host. - Crate: deliberately omits it (
traits.rs:3-6). Offers instead a scoped accessorchunks::with_connection(config, |conn| …)(chunks/mod.rs:217) over the cached handle;conn_cache()is private. - Decision (W2): do not upstream a handle-getter (it breaks the crate's connection-cache
invariants). Instead: (a) migrate host internal raw-SQL sites to
chunks::with_connectionduring W3; (b) keepsqlite_conn()as a host-side extension trait over the crate store for the transition, shrinking to zero as sites migrate. Track residual call sites in the deletion ledger. Gates W2/W3.
G2 — Graph relation-edge persistence (E2GraphRAG accumulation) — HARD
- Host:
memory_store/namespace_store/{graph,query}.rspersist and query co-occurrence / LLM-triple relations;NamespaceMemoryHit.supporting_relations: Vec<GraphRelationRecord>is populated at retrieval. - Crate: persists the entity occurrence index at persist time
(
score::persist_score/persist_score_tx,score/mod.rs:847-906) but does not write co-occurrence graph edges — docstringscore/mod.rs:843-846: "Co-occurrence graph edges (OpenHuman's E2GraphRAG accumulation) are not written here." Thegraphmodule derives edges on read from the occurrence index (graph/query.rs, "owns no state, performs no writes").GraphRelationRecordexists as a type but nothing in the crate writes it. - Decision (W6/W7): verify whether derive-on-read reproduces the host's persisted-relation
retrieval (
supporting_relations) with parity. If yes → host relation store stays host (namespace doc/graph store is explicitly host per plan §1); if the crate must own accumulation → upstream a relation-persist path. Gates W6/W7. Parity-critical for retrieval output.
G3 — Seal-time embedding — MEDIUM (parity timing)
- Host: computes summary embeddings around seal (
memory_tree/tree/bucket_seal.rs,memory_tree/score/embed/*,set_summary_embedding). - Crate:
bucket_seal.rs:21/tree/mod.rs:22list "seal-time embedding" as not ported;seal_one_levelcomputes labels but never embeds. Summary embedding runs later via the queue'sreembed_batchdelegate. Themem_tree_summary_embeddingssidecar + setters exist. - Decision (W5): confirm retrieval parity on freshly-sealed summaries — if the host embeds at seal but the crate defers to the queue, a summary is momentarily unembedded until the worker drains. Either drive an embed job at seal from the host queue driver, or upstream seal-time embedding. Gates W5.
G4 — Post-seal notification sink (for host wiki_git mirror) — SOFT
- Host:
6395f642ewired a seal-time hook inbucket_seal.rsto commit summary markdown to the git-backedwiki_gitmirror (host-retained, per the drift ledger). - Crate: no observer/sink trait for seal events — but
append_leaf/cascade_all_from/TreeFactory::seal_nowreturnVec<String>of sealed summary ids. The host can drivewiki_gitfrom the returned ids without a callback. - Decision (W3/W5): no crate change required; the host queue driver calls
wiki_gitafter each seal using returned ids. Record as a seam-wiring task, not an upstream gap. Revisit only if a push-notification is later wanted.
G5 — Tree health / doctor (storage-degraded state machine) — SOFT (host-retained)
- Host:
memory_tree/health/*(mark_storage_degraded/clear_storage_degraded, degraded flag), consumed bymemory/tools/doctor.rsand fed by the D2 host-FS classifier. - Crate: defers tree health/doctor entirely (
tree/mod.rs:20); onlyMemory::health_check() -> bool. Queue uses its ownJobFailure(no storage-degraded machine). - Decision (W5): host-retained (like
wiki_git).memory_tree::healthstays host; the D2 predicate (queue classifier) upstreams, its Sentry-once + degraded-flag consumers stay host.
G6 — Two divergent Summariser traits — MEDIUM (ambiguity)
- Crate has two traits named
Summariser:tree/summarise.rs:70(structured batch fold —summarise(&[SummaryInput], &SummaryContext) -> SummaryOutput) used by bucket-seal, andtree/runtime/engine.rs:29(string in/out —summarise(Option<&str>, &str) -> String) used by the markdown time-tree runtime. They are distinct contracts with the same name. - Decision (W1/W5): the host seam must implement both. Flag for possible upstream
unification (rename one, e.g.
TimeTreeSummariser) to reduce confusion — non-blocking. Note which tree path OpenHuman actually drives (bucket-seal SQLite trees vs markdown time-tree) so we don't wire a dead seam.
Non-gaps (expected host glue — no crate change)
| Host API | Refs | Disposition |
|---|---|---|
memory_store::create_memory / create_memory_with_local_ai (factories.rs:297,322) |
31 | Host glue building UnifiedMemory. Crate has no UnifiedMemory/MemoryClient (by design). W3 re-implements these factories over tinycortex::store + chunks, keeping the host-facing MemoryClient API stable. Not a crate gap. |
memory_store::profile (unified::profile) |
26 | Maps to config::WeightProfile (fields graph/vector/keyword/freshness, by_name). |
memory_store::fts / keyword search |
7 | Crate provides retrieval::keyword_relevance + hybrid_score (not SQLite FTS5). Verify keyword-recall parity in W5 (behavioral, not a missing API). |
| Namespace document/graph store | — | Explicitly host-retained per plan §1 until/unless upstreamed (ties to G2). |
Gap → workstream gate summary
| Gap | Severity | Gates | Resolution path |
|---|---|---|---|
| G1 escape hatch | High | W2/W3 | Migrate to with_connection; host extension trait for transition |
| G2 graph relations | High | W6/W7 | Parity check derive-on-read; upstream persist iff needed |
| G3 seal-time embedding | Medium | W5 | Drive embed at seal from host queue driver, or upstream |
| G4 seal notification | Soft | W3/W5 | Drive wiki_git from returned sealed ids (no crate change) |
| G5 tree health/doctor | Soft | W5 | Host-retained |
G6 two Summariser traits |
Medium | W1/W5 | Implement both; optional upstream rename |
No hard gap blocks W1 (seam scaffolding) or W4 (queue, only drift D2). W3 is gated by G1; W5 by G3/G6; W6/W7 by G2. These are recorded here and mirrored in the spec's deletion ledger.
Amendment 2026-07-09 (plan §8): the crate's sync data model (SourceKind::Composio,
SyncBudgetConfig, the TOML source registry with upsert_composio_source /
memory_sync_defaults_for_toolkit) — previously host-consumed only — becomes engine-consumed by
W-SYNC: the crate's own sync engine reads the registry and enforces the budget. New seam traits
SyncEventSink / SkillDocSink land with W-SYNC.1 (see roster above); no other new gaps.