Hindsight¶
Each Obsidience Agent has its own historical memory bank in a local Hindsight server. Hindsight extracts facts, experiences and observations from completed conversations and reports, consolidates them, keeps entities and original dates, and answers bounded recall. Its memories are historical and unverified: they inform the model, but accepted Knowledge stays in Articles and changes only through Review.
| Upstream | vectorize-io/hindsight |
| Pinned | hindsight-api-slim[local-onnx]==0.10.3 (hash-pinned wheel, isolated environment) with twelve local patches |
| License | MIT |
| Companions | FlashRank 0.2.10 (Apache-2.0) CPU reranker; PostgreSQL 18 with pgvector 0.8.6; the shared EmbeddingGemma 2 embedding service (see llama.cpp) |
| Upstream checked 2026-10-19 | v1.0.0 (2026-10-13), a major release. It includes an API fix that refuses tag-scoped callers on bank-wide operations, Codex stream error handling and a mental-model edit race fix. Upgrading means rebasing the local patches; patch 0012 is already a backport of upstream #5747 |
Why Hindsight¶
Obsidience needed long-lived memory that is separate from accepted Knowledge, attributed to who reported it, dated by when it happened and searchable inside a voice turn's latency budget. Hindsight provides native extraction, consolidation, temporal and entity links, mental models and a graph API, as a separate local service with its own store. Obsidience adds no second memory owner and no second wiki.
Flow¶
flowchart LR
subgraph Harness
turns["Completed turns and reports<br/>routes/turns.py, executor"]
outbox["Durable delivery outbox<br/>(Harness ledger)"]
port["Memory port<br/>memory/hindsight.py"]
recall["Automatic recall<br/>750 ms, per owner turn"]
tool["observations.recall / retain<br/>Tools"]
pane["Memory pane projection<br/>graphs/memory.py"]
curate["Alexandria Curate<br/>Review recommendations"]
end
subgraph HindsightSvc["Hindsight (local services)"]
api["hindsight-api<br/>requests only"]
worker["hindsight-worker<br/>retain, consolidation,<br/>mental-model refresh"]
pg[("PostgreSQL + pgvector<br/>one bank per Agent")]
end
emb["Embedding service<br/>EmbeddingGemma 2"]
turns --> outbox --> port
port -->|"async retain, stable operation IDs"| api
api --> pg
worker --> pg
worker -->|"extraction model"| llmp["Configured provider"]
api --> emb
worker --> emb
recall --> port
tool --> port
port -->|"recall, graph_read"| api
pane --> port
api -->|"webhooks wake delivery"| port
port -->|"changed mental-model page<br/>becomes one Source"| curate
- Delivery. Accepted public conversation turns and completed specialist
reports enter a durable outbox in the Harness ledger. Stable operation and
document IDs make acceptance idempotent; a row becomes
acceptedonly when Hindsight acknowledges the exact operation, andextractedonly when the native batch and every child completed without extraction errors. - Recall. The Executive loop takes one bounded automatic recall per owner
turn (750 ms deadline, two concurrent queries, at most three memories). The
explicit
observations.recallTool allows six seconds. Neither calls generative Reflect, and memory is never treated as current screen evidence. - Mental models. The Executive bank keeps three native mental models (owner preferences and permissions, workstation changes, recent decisions). A changed page becomes one attested Source and one Curate occurrence for Alexandria, which stages at most three recommendations for owner Review.
- Dedicated worker. The API process serves requests only; upstream's
hindsight-workerruns retain, consolidation and refresh in its own process, so background model work cannot stall voice-time recall. One SIGTERM drains it (patch 0012). - Memory pane. The graph pane's Memory view reads each bank's native graph
through the port's
graph_read;graphs/memory.pyprojects it with delta cursors. No raw memory node enters the accepted Article graph.
Boundary¶
| File | Owns |
|---|---|
harness/memory/hindsight.py |
The port: delivery outbox, recall, mental-model handoff, webhooks, health, the async API client and the synchronous graph client; the only reader of hindsight_url and the Hindsight credential |
harness/memory/README.md |
Deployment, provider configuration, recovery and rollback |
harness/memory/requirements.txt |
The isolated server environment |
scripts/patches/hindsight/ |
Patches 0001 to 0012 with a README; each is recorded with preimage and installed hashes in the lock |
harness/graphs/memory.py |
The Memory pane projection of a bank graph |
harness/interfaces/api/routes/turns.py |
POST /api/turns/complete intake for external completed turns |
harness/interfaces/api/routes/memory.py |
Status and the optional private local-model port for Hindsight |
harness/capabilities/observations/ |
The observations.recall and observations.retain Tools |
Other Harness modules use the port's public object (MEMORY) and functions,
never Hindsight's HTTP API.
What Obsidience patches¶
The twelve patches keep upstream behaviour and storage formats and address
specific measured problems: graph rendering off the event loop, bounded and
cancellable CPU reranking, OpenRouter quota resets, the owner's local day for
parsed dates, combined-scope observation updates, speaker perspective in
extraction, fact text before provenance in reranker input, calendar-date
reranker queries, month-only date ranges, Codex stream volume accounting, the
semantic arm's similarity floor outside its ANN limit (index use instead of an
exact scan) and a graceful single-SIGTERM worker stop. Each patch's purpose and
hashes are in artifacts.lock.json.
Configuration¶
| Key | Where | Effect |
|---|---|---|
[memory] hindsight_url |
obsidience/obsidience.toml |
Enables the port (for example http://127.0.0.1:8790); leave unset until the service is configured |
| Hindsight environment | private state/hindsight.env |
Database DSN, extraction provider, embeddings, reranker and worker settings; see the module README |
memory_writeback |
per conversation turn | false withholds a diagnostic turn from memory before it runs |
Missing provider configuration fails startup rather than falling back silently.
Module documentation:
memory/README.md.