Hindsight: Architecture
Level 2 (Topic). Parent hub: hindsight.
Concept
Hindsight (Vectorize.io) is the multi-agent memory platform adopted by TazLab on 2026-08-28. Unlike Mnemosyne (single-vector semantic recall over raw memory blobs), Hindsight runs an LLM extraction pipeline that decomposes ingested content into facts, entities, and relationships, then serves recall by fusing four search strategies. It is the searchable memory layer agents share across projects — the “remember for me” counterpart to the durable wiki.
Platform Capabilities (v0.9.2, verified)
- Extraction: LLM-driven fact/entity/relationship extraction per retained document.
- Recall: 4 strategies — semantic (pgvector), BM25, graph expansion, temporal — fused via RRF reranker.
- Memory banks: multiple isolated banks per endpoint; every bank is addressable at
/mcp/{bank_id}/. - Native MCP: 36 tools exposed over stateless streamable HTTP.
- Always-on directives: bank-level rules injected into every session.
- Mental models: living synthesis documents auto-refreshed at consolidation.
- Knowledge base: curated document store alongside episodic memory.
Architecture: 3 Stateless Pods (namespace hindsight)
| Pod | Image | Role |
|---|---|---|
hindsight-api | hindsight-api:0.9.2-slim | REST + MCP server on :8888 (HINDSIGHT_API_WORKER_ENABLED=false) |
hindsight-worker | same image, command: hindsight-worker | Async extraction/embedding pipeline; static WORKER_ID=hindsight-worker-1; metrics :8889 |
hindsight-dashboard | hindsight-control-plane:0.9.2 | Control plane UI on :9999; talks to the API in-cluster |
Zero PVCs by design. All state (memories, facts, vectors, operations, directives) lives in PostgreSQL — the PGO-managed tazlab-db cluster, database hindsight, dedicated schema hindsight. This is deliberate: TazLab treats full cluster destroy/create cycles as a normal operation (ephemeral-castle rebirth protocol), so a stateful memory platform must survive pod, node, and whole-cluster loss. PostgreSQL gives that survival (S3 backups) plus pgvector, while every pod can be recreated freely. Deployment specifics live in the Deployment Detail.
Bank Model
Single shared bank tazlab-common (user-ratified design of the memory-migration-hindsight project), organized in three layers:
- Dated memories — all legacy and operational content retained with
timestamp= occurred date (never default-to-now). - Doctrine as timeless memories —
timestamp="unset", tagdoctrine(system-state, debts, golden rules). - Bank directives — always-on rules; 8 active:
secrets-no-cleartext,git-first-anti-drift,english-only,everything-logged,enterprise-grade-homelab,research-first-verify-always,dates-are-sacred,independent-review-before-build.
Plus a mental model tazlab-operating-doctrine — a living synthesis of the doctrine layer, auto-refreshed at consolidation.
Per-agent banks (hermes, tazpod, openclaw) exist alongside the shared bank for agent-private context. A multi-tenant single-bank extension was evaluated and rejected (upstream issue #1556): separate banks are simpler and avoid cross-agent leakage.
LLM/Embedding Split and Quota Reality
- LLM extraction runs through the
opencode-gogateway, modelmimo-v2.5— the same gateway Hermes uses (zen plan quota, shared). - Embeddings use
gemini-embedding-001at 768 dimensions, with the cluster-widecluster/gemini/api-key. The free tier allows 1000 requests/day, shared with Mnemosyne and other consumers — the binding constraint of any bulk import. - The worker self-throttles on HTTP 429 (retry + backoff), but failed retain operations save content without vectors: the facts exist but are invisible to recall, and there is no self-heal. The quota wall was hit once during migration (50 failed operations, 2026-08-29 01:14–01:31 UTC,
429 RESOURCE_EXHAUSTED, recovered by retry). - Consequence: bulk imports use adaptive pacing — honor Google’s
retryDelayplus a safety margin, never hammer.
MCP Surface (36 tools)
Main tools: retain (async; timestamp = occurred date), sync_retain, recall (4-strategy search), reflect (synthesis with optional trace), 7 mental-model tools, 3 directive tools, 7 knowledge-base tools, plus documents/operations/tags management. Access is bearer-token protected (token from Vault, never persisted).
Migration Protocols (memory-migration-hindsight)
The legacy memory migration (CRISP project memory-migration-hindsight) converts the 745-memory Mnemosyne corpus plus chronicles, reports, and doctrine into tazlab-common. Its two operational protocols:
- mark-before-advance: per-item atomic state in
import-state.json(retained_at + operation_id) before the runner advances — a kill at any point resumes losslessly and idempotently (provenance tags +metadata.legacy_idmake re-runs duplicate-free). - done = operation completed AND searchable: a retain is “done” only when its operation completed and the content is recallable. Failed ops (429) persist content without vectors — invisible to recall — so they are retried, not marked. Batch order: chronological per-source (2024 → 2025 → 2026 → chronicles → reports → doctrine → directives/mental model).
Key discovery: the Mnemosyne writer LLM had hallucinated years — cluster “2024-05” is really Jan–Feb 2026, “2024-12” is really Dec 2025 (proven against git tags and real chat files in the obsidian.brain vault). A 4-agent independent date audit corrected 38/38 dates; the bank was purged and re-imported from corrected batches.
Live status (import-state.json, 2026-08-30):
| Source | Done |
|---|---|
| session-2026-08-28 (deployment session memories) | 10/10 |
| mnemosyne-corrected-2025-12 | 17/17 |
| mnemosyne-corrected-2026-01 | 4/4 |
| mnemosyne-corrected-2026-02 | 17/17 |
| mnemosyne-2025-12 (B2) | 59/59 |
| mnemosyne-2026-01 (B3) | 30/144 — in progress |
| Total | 137 |
Remaining after B3: 2026-02 (296) + later-2026 batches, 19 chronicle archives, 57 reports, doctrine (unset-timestamp), directives + mental model. Mnemosyne stays read-only until user sign-off; its decommission is a separate future project.
Known Verification Findings (deep verification 2026-08-29)
recalloutput drops entities: 381/561 units carry entity data in storage, but the recall MCP schema never returns them and no parameter exposes them (extraction works; output-schema gap).occurred_startis populated only when fact text contains an explicit date; migrated items without in-text dates keepoccurred_start = nullwhile the unitdatefield stays correct — date-filtered recall misses them.- Temporal-query top ranks can be polluted by the recently-embedded session batch.
- Bank
missionis empty;source:reporttag absent (reports not migrated yet).
See Also
- Parent hub: hindsight
- Child details: Deployment Detail
- Sibling topics: Mnemosyne Architecture, TazLab Knowledge Layers
- Predecessor: mnemosyne-mcp-server