# Stash -- Comparison & Analysis

## Overview

This document records our analysis of [Stash](https://github.com/alash3al/stash) (alash3al, Apache 2.0) against our schema discovery search service. Stash is a persistent memory layer for AI agents -- it stores raw observations (episodes), consolidates them into structured knowledge (facts, relationships, patterns), and provides semantic recall via MCP tools. The tagline: "Your AI has amnesia. We fixed it."

We evaluated it to identify transferable techniques, as we did with [LightRAG](../search/lightrag-comparison.md), [ChromaFs](../search/chromafs-comparison.md), [RAG-Anything](../search/raganything-comparison.md), [LLM Wiki](../knowledge/llm-wiki-comparison.md), [RLMs](../knowledge/rlm-comparison.md), and [Graphify](../knowledge/graphify-comparison.md).

**Last updated**: 2026-05-10 (refreshed with live GitHub data. Stash at 675 stars (up from 674), v0.2.9, last pushed May 1 -- pace slowing since late-April burst. All 4 open issues unchanged: #5 SQL injection, #7 pattern bug, #1 and #6 docs. Competitive landscape: Mem0 55,253 stars (pushed today), Letta 22,577 (quiet since Apr 12), MemOS 8,996 (active), engram 3,374.)

---

## How Stash works

Stash is a Go service backed by PostgreSQL + pgvector, exposed as an MCP server (stdio or SSE). It organizes agent memory into hierarchical namespaces and progressively consolidates raw observations into higher-order knowledge.

### Data model

Seven core entities, all namespace-scoped with soft deletes:

| Entity            | Purpose                                       | Storage                                           |
| ----------------- | --------------------------------------------- | ------------------------------------------------- |
| **Episode**       | Immutable raw observation (append-only)       | Text + pgvector embedding                         |
| **Fact**          | Synthesized belief with confidence 0.0--1.0   | Text + entity/property/value triple + embedding   |
| **Relationship**  | Entity edge (from -> relation -> to)          | from_entity, relation_type, to_entity, confidence |
| **Pattern**       | Higher-order abstraction over facts/relations | Text + source fact/rel IDs + coherence score      |
| **CausalLink**    | Cause-effect pair between two facts           | cause_fact_id -> effect_fact_id + confidence      |
| **Contradiction** | Conflict between two facts on same property   | old_fact_id vs new_fact_id + resolution method    |
| **Hypothesis**    | Uncertain belief with verification plan       | Content + status + source facts + test results    |

### Consolidation pipeline

The core of Stash is an 8-stage consolidation pipeline that runs as a background job:

1. **Episodes -> Facts + Contradictions**: LLM synthesizes clusters into structured facts with confidence scores
2. **Facts -> Relationships**: LLM extracts entity edges from recent facts
3. **Facts -> Causal Links**: LLM identifies cause-effect pairs
4. **Facts + Relationships -> Patterns**: LLM identifies higher-order abstractions
5. **Goal Progress Inference**: Scans new facts against active goals
6. **Failure Pattern Detection**: Identifies repeated mistakes
7. **Hypothesis Evaluation**: Checks new facts against pending hypotheses
8. **Confidence Decay**: Pure SQL -- multiplies confidence by decay factor for stale facts

### Retrieval (recall)

Recall is **vector-only** -- cosine similarity via pgvector. No BM25, no keyword matching, no score fusion.

---

## How our system differs

| Aspect               | Stash                                                          | @coda/search                                                                         |
| -------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| **Problem**          | Agents forget between sessions                                 | Agent needs to find relevant schema from 10K+ items in <15ms                         |
| **Layer**            | Memory (knowledge accumulation over time)                      | Retrieval (ranked search over structured metadata)                                   |
| **Retrieval**        | Vector-only (pgvector cosine similarity)                       | BM25 keyword + HNSW vector + glossary boost + graph degree + proximity -> RRF fusion |
| **Query latency**    | ~50--200ms (PostgreSQL round-trip + embedding)                 | ~10--15ms (in-memory BM25 + HNSW)                                                    |
| **Indexing cost**    | High -- LLM calls per consolidation run                        | Zero LLM calls (tokenize + embed only, ONNX local inference)                         |
| **Confidence model** | Decay over time (facts lose confidence without re-observation) | Not applicable (schema metadata is authoritative)                                    |
| **State machine**    | None (implicit via consolidation progress)                     | CREATED -> READY -> DEGRADED -> DESTROYED with graceful transitions                  |

---

## Why we are not adopting Stash

1. **Different problem domains** -- agent memory vs schema retrieval
2. **Vector-only retrieval is insufficient** -- BM25 + HNSW + RRF improves NDCG@10 by 0.15-0.20 over vector-only
3. **PostgreSQL latency is incompatible** -- ~50-200ms vs our 10-15ms budget
4. **LLM-dependent consolidation is architecturally incompatible** -- zero-LLM policy
5. **Confidence decay is wrong for authoritative metadata** -- schema tables either exist or they don't
6. **No access control beyond namespaces**

---

## What we could adopt from Stash

### 1. Structured consolidation result reporting

Stash returns detailed metrics from consolidation runs. Our `POLL_COMPLETED` event carries only `durationMs`. A richer refresh report would improve operational visibility.

**Status**: Low priority. Individual events provide the detail.

### 2. Semantic deduplication during ingestion

Could be useful for future glossary deduplication -- preventing near-identical glossary entries.

**Status**: Not needed today. Revisit if automated glossary generation is introduced.

### 3. Embedding cache by content hash

Our snapshot + LRU approach already covers this.

---

## Enterprise readiness comparison

| Factor                 | Stash                                            | @coda/search                                                                        |
| ---------------------- | ------------------------------------------------ | ----------------------------------------------------------------------------------- |
| **Authentication**     | None (open MCP endpoint)                         | ConnectRPC with service-level auth (admin email allowlist, RPC auth pending COD-82) |
| **Horizontal scaling** | Not supported (single PostgreSQL instance)       | Stateless Fargate tasks + S3 snapshot restore on cold start                         |
| **State machine**      | None                                             | CREATED -> READY -> DEGRADED -> DESTROYED with abort propagation                    |
| **Observability**      | Prometheus counters/histograms for consolidation | 28-type structured event bus (OTel-compatible), admin UI                            |
| **Test coverage**      | Zero test files in repository                    | 1,386 tests (Vitest), 34 test files in search package alone                         |
| **Security**           | Open issue #5: SQL injection via LIKE wildcards  | Parameterized queries throughout; no known injection vectors                        |

---

## Developer experience comparison

| Factor                   | Stash                                                    | @coda/search                                                                                      |
| ------------------------ | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| **Time to first query**  | ~2 min (docker compose up + MCP client config)           | ~5 min (pnpm install, env setup, pnpm dev:all)                                                    |
| **Interface**            | MCP tools (natural language via any MCP client)          | ConnectRPC API (typed clients, admin UI)                                                          |
| **Type safety**          | Go structs with `db:` tags                               | TypeScript interfaces, Zod validation, proto-generated types                                      |
| **Package organization** | Flat Go packages (`internal/brain`, `internal/embedder`) | 9 sub-path exports (root, primitives, engine, pipeline, events, graph, signals, stages, snapshot) |

---

## Abstraction quality comparison

| Factor                 | Stash                                                     | @coda/search                                                                                      |
| ---------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| **Core abstraction**   | `Brain` (god object: all 8 consolidation stages + recall) | Decomposed: `SearchEngine` + `HybridSearch` + `SearchPipeline` + `ScoreFusion`                    |
| **Extension model**    | None (all logic in Brain methods)                         | Pluggable: `SearchStage`, `QueryExpander`, `StaticSignal`, `QuerySignal`, `ScoreFusion`, `Filter` |
| **Signal composition** | Single signal (cosine similarity)                         | N-signal fusion: keyword, keyword_expanded, vector, glossary_match, degree, proximity             |

---

## Scope & limitations

### Stash limitations

1. No retrieval quality measurement -- no benchmarks, no golden queries
2. No tests -- zero test files in the repository
3. Single-signal retrieval -- vector-only cosine similarity
4. External LLM dependency for every consolidation run
5. Open security issues -- SQL injection (#5), pattern stage bug (#7) still open
6. Offset-based pagination -- O(n) at depth

### @coda/search limitations

1. In-memory only -- corpus size bounded by available RAM
2. No persistent query log
3. No cross-session learning
4. No fuzzy/typo tolerance at query time

---

## If we started fresh, what would we adopt from this project?

1. **The knowledge maturation pipeline concept.** Episodes -> facts -> relationships -> patterns -> hypotheses is a well-designed lifecycle. For agent memory (not search), this would be our starting model.
2. **Namespace-scoped memory with cascading reads.** Slash-delimited hierarchy with automatic inheritance.
3. **Confidence decay for non-authoritative data.** Temporal decay is the right model for agent observations, not schema metadata.

## What are we doing better?

1. **Retrieval precision.** 8-signal RRF fusion. NDCG=0.887, MRR=0.943, Recall@10=0.994.
2. **Latency.** 10-15ms vs ~50-200ms.
3. **Cost.** $0 always vs LLM calls per consolidation.
4. **Composability.** 12 pluggable interfaces, 9 sub-path exports vs monolithic `Brain` class.
5. **Test coverage.** 1,386 tests with regression benchmarks vs zero tests.
6. **Security posture.** No known injection vectors vs open SQL injection issue (#5).

## What are we missing for enterprise-level production readiness?

1. **Agent memory.** No mechanism for cross-session knowledge accumulation. Stash's core problem is a real gap.
2. **Failure tracking.** Stash's `Failure` model would be valuable in the agent loop.
3. **MCP interface.** Stash is MCP-native. Our service is ConnectRPC-only.

---

## Competitive landscape -- AI agent memory

| Project            | Stars  | Last Push | Description                                            |
| ------------------ | ------ | --------- | ------------------------------------------------------ |
| **mem0ai/Mem0**    | 55,253 | May 10    | Universal memory layer for AI Agents. Dominant.        |
| **letta-ai/Letta** | 22,577 | Apr 12    | Platform for stateful agents (formerly MemGPT). Quiet. |
| **MemOS**          | 8,996  | --        | Self-evolving memory OS, hybrid retrieval. Active.     |
| **engram**         | 3,374  | --        | Persistent memory with SQLite + FTS5 keyword search.   |
| **Stash**          | 675    | May 1     | 8-stage consolidation pipeline. Stalling.              |

**Key observation**: Stash at 674 stars is **82x smaller** than Mem0. Development has stalled (no commits since May 1). If we revisit agent memory patterns, Mem0, MemOS, and engram are stronger candidates.

---

## Project maturity assessment

| Factor             | Assessment                                                                     |
| ------------------ | ------------------------------------------------------------------------------ |
| **Age**            | 2 weeks active (created 2026-04-24, last pushed 2026-05-01). Pre-alpha.        |
| **Maintainership** | Solo developer. 97 commits, all from same author.                              |
| **Stars**          | 674 -- flat since initial review, growth stalled.                              |
| **Test coverage**  | Zero. No test files. No CI test step.                                          |
| **Open issues**    | 4 open -- all unchanged: SQL injection (#5), pattern bug (#7), docs (#1, #6).  |
| **Trajectory**     | Stalling. No commits since May 1. Competitors have surpassed it significantly. |

---

## Applicability beyond the search service

While Stash's patterns don't transfer to search, several are directly relevant to the **agent loop** (`apps/server`):

| Pattern                   | Agent loop gap                                                   | Stash analog                                     |
| ------------------------- | ---------------------------------------------------------------- | ------------------------------------------------ |
| Cross-session user memory | Agent doesn't know user's domain, preferences, or common queries | Episodes -> Facts consolidation per tenant       |
| Failure pattern tracking  | Same tool failures repeat across sessions with no learning       | `Failure` model with `reason` + `lesson`         |
| Goal continuity           | Multi-session tasks rediscover context from scratch each time    | `Goal` model with status, priority, parent/child |

---

## Verdict & recommendation

**No techniques to adopt for search. High-value opportunity for the agent loop.**

**For search**: No action. The structured poll report idea is low priority.

**For the agent**: High-value opportunity. Cross-session user memory, failure tracking, and goal continuity would meaningfully improve agent effectiveness. If we pursue this, analyze **Mem0** (55K stars, active daily) and **engram** (3.4K stars, keyword search, same Go+MCP stack) rather than Stash.

**Stash trajectory**: Development has stalled. Stars flat at 674. All 4 open issues (including SQL injection) remain unresolved. No longer a viable candidate for adoption -- it is an interesting design document, not a production tool.

---

## References

- alash3al: [Stash](https://github.com/alash3al/stash) (Apache 2.0, 675 stars, v0.2.9, 2026)
- Mem0: [mem0ai/mem0](https://github.com/mem0ai/mem0) (55,253 stars, 2026)
- LightRAG comparison: [lightrag-comparison.md](../search/lightrag-comparison.md)
- LLM Wiki comparison: [llm-wiki-comparison.md](../knowledge/llm-wiki-comparison.md)
- Graphify comparison: [graphify-comparison.md](../knowledge/graphify-comparison.md)
