2026-09-02 11:30:11 -07:00
# Poimen Memory
2026-08-19 09:52:07 -07:00
2026-09-02 11:51:15 -07:00
> **Poimen** (ποιμήν) — Greek for "shepherd". Guiding AI agents to grounded knowledge.
2026-09-02 11:30:11 -07:00
**Agent-ready Graph-RAG system with hallucination prevention and enterprise RBAC.**
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
Poimen Memory is a knowledge retrieval system designed for AI agents. It learns from conversations and documents, builds wiki-link knowledge graphs, and serves grounded context that reduces hallucinations. Agents cite sources instead of fabricating answers.
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
## Why Poimen?
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
| Problem | Poimen Solution |
|---------|-----------------|
| LLMs hallucinate facts | Three-tier retrieval grounds responses in verified knowledge |
| Vector search misses context | Wiki-link graph propagates relevance to connected docs |
| Agents forget across sessions | Persistent memory with provenance tracking |
| Multi-tenant data leakage | Hierarchical RBAC with project/visibility scopes |
| Context window limits | Budget-aware assembly with intelligent compression |
## Architecture
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
┌─────────────────────────────────────────────────────────────────────────────┐
│ AI Agents │
│ (Claude, GPT, Local LLMs, etc.) │
└─────────────────────────────────┬───────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ Poimen Memory API │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ /query │ │ /context │ │ /ingest │ │ /learn │ │
│ │ Hybrid RAG │ │ Three-Tier │ │ Add Facts │ │ Chunk + Synthesize │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────────┬──────────┘ │
│ │ │ │ │ │
│ └────────────────┴────────────────┴─────────────────────┘ │
│ │ │
│ ┌────────┴────────┐ │
│ │ Access Guard │ ← JWT roles + RBAC scopes │
│ │ (Authentik) │ │
│ └────────┬────────┘ │
└───────────────────────────────────┼─────────────────────────────────────────┘
│
┌───────────────────────────┼───────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ pgvector │ │ OpenSearch │ │ Obsidian │
│ (Semantic) │ │ (Lexical) │ │ (Reference) │
│ │ │ │ │ │
│ HNSW cosine │ │ BM25 ranking │ │ Markdown docs │
│ 768-dim vecs │ │ Full-text │ │ Wiki-links │
└───────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
└───────────────────────────┴───────────────────────────┘
│
┌─────────┴─────────┐
│ Wiki-Link Graph │
│ PageRank boost │
│ Provenance trace │
└───────────────────┘
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
## Core Features
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
### 1. Graph-RAG Retrieval
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
Traditional RAG retrieves isolated chunks. Poimen builds a **wiki-link graph** from `[[linked-documents]]` and propagates relevance scores to connected knowledge.
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
Document A: "Kubernetes uses [[etcd]] for state storage"
Document B: "[[etcd]] requires TLS certificates"
Document C: "Generate certs with [[cfssl]]"
Query: "Kubernetes certificate issues"
→ Finds A (direct match)
→ Boosts B (linked from A)
→ Surfaces C (2-hop connection)
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
### 2. Three-Tier Context Lookup
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
Agents call `/memory/context` with tool + task + failure log. Poimen returns grounded knowledge in priority order:
| Tier | Source | Latency | Use Case |
|------|--------|---------|----------|
| **Tier 1** | Exact signature match | <50ms | Known error patterns |
| **Tier 2** | Graph-boosted hybrid search | <500ms | Similar problems |
| **Tier 3** | Reference corpus fallback | <1s | Documentation |
```bash
curl -X POST /memory/context \
-d '{"tool": "kubectl", "task": "debug-pod", "failure_log": "CrashLoopBackOff"}'
# Returns:
{
"tier" : 1,
"lessons" : [{
"text" : "CrashLoopBackOff: check container logs with kubectl logs -p" ,
"seen_count" : 23,
"provenance" : [ "session-123" , "session-456" ]
}]
}
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
### 3. Hallucination Prevention
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
Every retrieved chunk includes:
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
- **`provenance[]` ** — Which sessions/documents contributed this fact
- **`source` ** — Original file or conversation URI
- **`seen_count` ** — How many times this pattern was observed
- **`score` ** — Retrieval confidence (semantic + lexical + graph boost)
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
Agents can cite sources: *"Based on 23 previous occurrences (source: troubleshooting/k8s.md)..."*
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
### 4. Hierarchical RBAC
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
Fine-grained access control integrated with Authentik OIDC:
2026-08-19 09:52:07 -07:00
```yaml
2026-09-02 11:30:11 -07:00
# Portfolio visitor: public docs only
- role : portfolio-agent
rules :
- resources : [ wiki, embedding]
verbs : [ read, query]
scope :
projects : [ homelab, portfolio]
visibility : public
# Team member: full project access
- role : homelab-team
rules :
- resources : [ wiki, embedding, skill]
verbs : [ read, write, query]
scope :
projects : [ homelab]
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
Agents only retrieve knowledge they're authorized to access. Prevents cross-project data leakage.
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
### 5. Budget-Aware Context Assembly
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
LLM context windows are limited. Poimen optimizes what fits:
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
Budget: 8192 tokens
│
├─ Tier 1 lessons (never dropped) → 2000 tokens
├─ Tier 2 relevant chunks → 4000 tokens
├─ Tier 3 reference excerpts → 1500 tokens
└─ Skills/tools → 500 tokens
────────────
8000 tokens ✓
If over budget:
1. Drop Tier 3 first
2. Drop lowest-score Tier 2
3. Compress remaining chunks
4. Never drop Tier 1
2026-08-19 09:52:07 -07:00
```
2026-09-02 11:30:11 -07:00
## Quick Start
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
### Prerequisites
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
- Rust 1.75+
- PostgreSQL 15+ with pgvector extension
- OpenSearch 2.x
- (Optional) Authentik for OIDC
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
### Run Locally
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
```bash
# Clone
git clone https://github.com/your-org/poimen-memory.git
cd poimen-memory
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
# Start dependencies
docker-compose up -d postgres opensearch
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
# Configure
cp .env.example .env
# Edit .env with your settings
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
# Build and run
cargo build --release
./target/release/mem serve
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
# Health check
2026-08-30 13:21:07 -07:00
curl http://localhost:8080/health
2026-09-02 11:30:11 -07:00
```
2026-08-30 13:21:07 -07:00
2026-09-02 11:30:11 -07:00
### Docker
```bash
docker run -d \
-e PGVECTOR_HOST = postgres:5432 \
-e OPENSEARCH_HOST = opensearch:9200 \
-p 8080:8080 \
ghcr.io/your-org/poimen-memory:latest
```
### Kubernetes (ArgoCD)
```yaml
apiVersion : argoproj.io/v1alpha1
kind : Application
metadata :
name : poimen-memory
spec :
source :
repoURL : https://github.com/your-org/poimen-memory
path : k8s/app
destination :
namespace : poimen
```
## API Usage
### Ingest Knowledge
```bash
# From conversation
curl -X POST http://localhost:8080/memory/ingest \
2026-08-30 13:21:07 -07:00
-H "Authorization: Bearer $TOKEN " \
-H "Content-Type: application/json" \
2026-09-02 11:30:11 -07:00
-d '{
"project": "homelab",
"source": "conversation://claude/session-123",
"records": [
{"text": "To fix port 8080 conflict, use: kubectl delete pod -l app=nginx"},
{"text": "etcd backup: etcdctl snapshot save /backup/etcd.db"}
]
}'
2026-08-30 13:21:07 -07:00
```
2026-09-02 11:30:11 -07:00
### Query Memory
2026-08-30 13:21:07 -07:00
2026-09-02 11:30:11 -07:00
```bash
# Hybrid search (semantic + lexical + graph)
curl "http://localhost:8080/memory/query?project=homelab&query=kubernetes%20port%20conflict" \
-H "Authorization: Bearer $TOKEN "
2026-08-30 13:21:07 -07:00
2026-09-02 11:30:11 -07:00
# Response
{
"results" : [{
"text" : "To fix port 8080 conflict..." ,
"score" : 0.92,
"source" : "conversation://claude/session-123" ,
"provenance" : [ "session-123" ]
}]
2026-08-28 12:32:08 -07:00
}
```
2026-09-02 11:30:11 -07:00
### Get Agent Context
2026-08-28 12:32:08 -07:00
```bash
2026-09-02 11:30:11 -07:00
# Tool-specific context with failure diagnosis
curl -X POST http://localhost:8080/memory/context \
-H "Authorization: Bearer $TOKEN " \
-d '{
"project": "homelab",
"tool": "kubectl",
"task": "debug-pod",
"failure_log": "Error: ImagePullBackOff",
"budget": 4096
}'
2026-08-28 12:32:08 -07:00
```
2026-09-02 11:30:11 -07:00
### Learn from Documents
2026-08-28 12:32:08 -07:00
```bash
2026-09-02 11:30:11 -07:00
# Chunk, embed, and synthesize
curl -X POST http://localhost:8080/memory/learn \
-H "Authorization: Bearer $TOKEN " \
-d '{
"project": "homelab",
"text": "# Kubernetes Networking\n\nPods communicate via [[CNI]] plugins...",
"chunk_size": 2000
}'
2026-08-28 12:32:08 -07:00
```
2026-09-02 11:30:11 -07:00
## Retrieval Pipeline
2026-08-28 12:32:08 -07:00
2026-09-02 11:30:11 -07:00
```
Query: "fix kubernetes certificate error"
│
▼
┌───────────────────────┐
│ Query Optimizer │
│ Classify: bug_fix │
│ Route: hybrid │
└───────────┬───────────┘
│
┌───────────┴───────────┐
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ Semantic │ │ Lexical │
│ pgvector │ │ OpenSearch │
│ cosine sim │ │ BM25 │
└───────┬───────┘ └───────┬───────┘
│ │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ RRF Fusion │
│ 60% semantic │
│ 40% lexical │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ Wiki-Link Graph │
│ PageRank boost │
│ Link-distance decay │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ RBAC Filter │
│ Project scope │
│ Visibility check │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ Deduplication │
│ Shingle Jaccard │
│ >0.5 = duplicate │
└───────────┬───────────┘
│
▼
┌───────────────────────┐
│ Budget Assembly │
│ Rank by score │
│ Fit to token limit │
└───────────┬───────────┘
│
▼
Final Results
(with provenance)
```
2026-08-28 12:32:08 -07:00
2026-09-02 11:30:11 -07:00
## Configuration
2026-08-28 12:32:08 -07:00
2026-09-02 11:30:11 -07:00
### Environment Variables
2026-08-28 12:32:08 -07:00
2026-09-02 11:30:11 -07:00
| Variable | Description | Default |
|----------|-------------|---------|
| `PGVECTOR_HOST` | PostgreSQL host | `localhost:5432` |
| `PGVECTOR_DB` | Database name | `memory` |
| `OPENSEARCH_HOST` | OpenSearch host | `localhost:9200` |
| `OBSIDIAN_URL` | Obsidian REST API | (optional) |
| `MEM_AUTH_MODE` | `jwt` or `apikey` | `jwt` |
| `AUTHENTIK_ISSUER` | OIDC issuer URL | (required for jwt) |
| `RBAC_ROLES_DIR` | Custom role definitions | (builtin only) |
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
### Custom Roles
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
```yaml
# config/roles/my-team.yaml
name : my-team
rules :
- resources : [ wiki, embedding]
verbs : [ read, write, query]
scope :
projects : [ my-project]
visibility : private # Can access private docs
```
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
## Project Structure
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
```
poimen-memory/
├── crates/
│ ├── mem-cli/ # HTTP server, RBAC, handlers
│ │ └── src/
│ │ ├── http_server.rs
│ │ ├── rbac/ # Access control
│ │ ├── hybrid_retrieval.rs
│ │ └── query_optimizer.rs
│ ├── mem-core/ # Domain types, scoring
│ └── mem-ingest/ # Wiki-link parsing, chunking
├── config/
│ └── roles/ # YAML role definitions
├── docs/
│ ├── API.md # API reference
│ └── RBAC.md # Access control guide
├── k8s/ # Kubernetes manifests
└── tests/ # Integration tests (670+)
```
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
## Performance
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
| Metric | Target | Actual |
|--------|--------|--------|
| Tier 1 latency | <50ms | 12ms |
| Hybrid search | <500ms | 145ms |
| NDCG@10 | >0.85 | 0.88 |
| Test coverage | >600 | 670 |
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
## Contributing
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
```bash
# Run tests
cargo test --all
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
# Run specific test
cargo test -p mem-cli http_server::tests
2026-08-19 09:52:07 -07:00
2026-09-02 11:30:11 -07:00
# Check formatting
cargo fmt --check
cargo clippy
```
## License
MIT