hippo-memory 0.36.0 → 0.38.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -254
- package/dist/api.d.ts +20 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +23 -3
- package/dist/api.js.map +1 -1
- package/dist/benchmarks/e1.3/incident-recall-eval.js +74 -0
- package/dist/benchmarks/e1.3/incident-recall-eval.js.map +1 -0
- package/dist/benchmarks/e1.3/scenarios.json +2587 -0
- package/dist/benchmarks/e1.3/slack-1000-event-smoke.js +102 -0
- package/dist/benchmarks/e1.3/slack-1000-event-smoke.js.map +1 -0
- package/dist/cli.js +449 -0
- package/dist/cli.js.map +1 -1
- package/dist/connectors/slack/backfill.d.ts +42 -0
- package/dist/connectors/slack/backfill.d.ts.map +1 -0
- package/dist/connectors/slack/backfill.js +76 -0
- package/dist/connectors/slack/backfill.js.map +1 -0
- package/dist/connectors/slack/deletion.d.ts +14 -0
- package/dist/connectors/slack/deletion.d.ts.map +1 -0
- package/dist/connectors/slack/deletion.js +46 -0
- package/dist/connectors/slack/deletion.js.map +1 -0
- package/dist/connectors/slack/dlq.d.ts +21 -0
- package/dist/connectors/slack/dlq.d.ts.map +1 -0
- package/dist/connectors/slack/dlq.js +23 -0
- package/dist/connectors/slack/dlq.js.map +1 -0
- package/dist/connectors/slack/idempotency.d.ts +5 -0
- package/dist/connectors/slack/idempotency.d.ts.map +1 -0
- package/dist/connectors/slack/idempotency.js +13 -0
- package/dist/connectors/slack/idempotency.js.map +1 -0
- package/dist/connectors/slack/ingest.d.ts +27 -0
- package/dist/connectors/slack/ingest.d.ts.map +1 -0
- package/dist/connectors/slack/ingest.js +48 -0
- package/dist/connectors/slack/ingest.js.map +1 -0
- package/dist/connectors/slack/ratelimit.d.ts +9 -0
- package/dist/connectors/slack/ratelimit.d.ts.map +1 -0
- package/dist/connectors/slack/ratelimit.js +18 -0
- package/dist/connectors/slack/ratelimit.js.map +1 -0
- package/dist/connectors/slack/scope.d.ts +16 -0
- package/dist/connectors/slack/scope.d.ts.map +1 -0
- package/dist/connectors/slack/scope.js +13 -0
- package/dist/connectors/slack/scope.js.map +1 -0
- package/dist/connectors/slack/signature.d.ts +12 -0
- package/dist/connectors/slack/signature.d.ts.map +1 -0
- package/dist/connectors/slack/signature.js +20 -0
- package/dist/connectors/slack/signature.js.map +1 -0
- package/dist/connectors/slack/tenant-routing.d.ts +13 -0
- package/dist/connectors/slack/tenant-routing.d.ts.map +1 -0
- package/dist/connectors/slack/tenant-routing.js +17 -0
- package/dist/connectors/slack/tenant-routing.js.map +1 -0
- package/dist/connectors/slack/transform.d.ts +20 -0
- package/dist/connectors/slack/transform.d.ts.map +1 -0
- package/dist/connectors/slack/transform.js +31 -0
- package/dist/connectors/slack/transform.js.map +1 -0
- package/dist/connectors/slack/types.d.ts +35 -0
- package/dist/connectors/slack/types.d.ts.map +1 -0
- package/dist/connectors/slack/types.js +23 -0
- package/dist/connectors/slack/types.js.map +1 -0
- package/dist/connectors/slack/web-client.d.ts +12 -0
- package/dist/connectors/slack/web-client.d.ts.map +1 -0
- package/dist/connectors/slack/web-client.js +43 -0
- package/dist/connectors/slack/web-client.js.map +1 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +105 -1
- package/dist/db.js.map +1 -1
- package/dist/goals.d.ts +73 -0
- package/dist/goals.d.ts.map +1 -0
- package/dist/goals.js +227 -0
- package/dist/goals.js.map +1 -0
- package/dist/importers.js +3 -3
- package/dist/importers.js.map +1 -1
- package/dist/mcp/server.js +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +174 -2
- package/dist/server.js.map +1 -1
- package/dist/src/ambient.js +147 -0
- package/dist/src/ambient.js.map +1 -0
- package/dist/src/api.js +343 -0
- package/dist/src/api.js.map +1 -0
- package/dist/src/audit.js +152 -0
- package/dist/src/audit.js.map +1 -0
- package/dist/src/auth.js +65 -0
- package/dist/src/auth.js.map +1 -0
- package/dist/src/autolearn.js +143 -0
- package/dist/src/autolearn.js.map +1 -0
- package/dist/src/capture.js +512 -0
- package/dist/src/capture.js.map +1 -0
- package/dist/src/cli.js +5338 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/client.js +181 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/config.js +108 -0
- package/dist/src/config.js.map +1 -0
- package/dist/src/connectors/slack/backfill.js +76 -0
- package/dist/src/connectors/slack/backfill.js.map +1 -0
- package/dist/src/connectors/slack/deletion.js +46 -0
- package/dist/src/connectors/slack/deletion.js.map +1 -0
- package/dist/src/connectors/slack/dlq.js +23 -0
- package/dist/src/connectors/slack/dlq.js.map +1 -0
- package/dist/src/connectors/slack/idempotency.js +13 -0
- package/dist/src/connectors/slack/idempotency.js.map +1 -0
- package/dist/src/connectors/slack/ingest.js +48 -0
- package/dist/src/connectors/slack/ingest.js.map +1 -0
- package/dist/src/connectors/slack/ratelimit.js +18 -0
- package/dist/src/connectors/slack/ratelimit.js.map +1 -0
- package/dist/src/connectors/slack/scope.js +13 -0
- package/dist/src/connectors/slack/scope.js.map +1 -0
- package/dist/src/connectors/slack/signature.js +20 -0
- package/dist/src/connectors/slack/signature.js.map +1 -0
- package/dist/src/connectors/slack/tenant-routing.js +17 -0
- package/dist/src/connectors/slack/tenant-routing.js.map +1 -0
- package/dist/src/connectors/slack/transform.js +31 -0
- package/dist/src/connectors/slack/transform.js.map +1 -0
- package/dist/src/connectors/slack/types.js +23 -0
- package/dist/src/connectors/slack/types.js.map +1 -0
- package/dist/src/connectors/slack/web-client.js +43 -0
- package/dist/src/connectors/slack/web-client.js.map +1 -0
- package/dist/src/consolidate.js +517 -0
- package/dist/src/consolidate.js.map +1 -0
- package/dist/src/dag.js +104 -0
- package/dist/src/dag.js.map +1 -0
- package/dist/src/dashboard.js +409 -0
- package/dist/src/dashboard.js.map +1 -0
- package/dist/src/db.js +643 -0
- package/dist/src/db.js.map +1 -0
- package/dist/src/embeddings.js +344 -0
- package/dist/src/embeddings.js.map +1 -0
- package/dist/src/eval-suite.js +289 -0
- package/dist/src/eval-suite.js.map +1 -0
- package/dist/src/eval.js +187 -0
- package/dist/src/eval.js.map +1 -0
- package/dist/src/extract.js +87 -0
- package/dist/src/extract.js.map +1 -0
- package/dist/src/goals.js +227 -0
- package/dist/src/goals.js.map +1 -0
- package/dist/src/handoff.js +30 -0
- package/dist/src/handoff.js.map +1 -0
- package/dist/src/hooks.js +582 -0
- package/dist/src/hooks.js.map +1 -0
- package/dist/src/importers.js +399 -0
- package/dist/src/importers.js.map +1 -0
- package/dist/src/index.js +25 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/invalidation.js +94 -0
- package/dist/src/invalidation.js.map +1 -0
- package/dist/src/mcp/framing.js +45 -0
- package/dist/src/mcp/framing.js.map +1 -0
- package/dist/src/mcp/server.js +510 -0
- package/dist/src/mcp/server.js.map +1 -0
- package/dist/src/memory.js +280 -0
- package/dist/src/memory.js.map +1 -0
- package/dist/src/multihop.js +32 -0
- package/dist/src/multihop.js.map +1 -0
- package/dist/src/path-context.js +32 -0
- package/dist/src/path-context.js.map +1 -0
- package/dist/src/physics-config.js +26 -0
- package/dist/src/physics-config.js.map +1 -0
- package/dist/src/physics-state.js +163 -0
- package/dist/src/physics-state.js.map +1 -0
- package/dist/src/physics.js +361 -0
- package/dist/src/physics.js.map +1 -0
- package/dist/src/postinstall.js +68 -0
- package/dist/src/postinstall.js.map +1 -0
- package/dist/src/raw-archive.js +72 -0
- package/dist/src/raw-archive.js.map +1 -0
- package/dist/src/refine-llm.js +147 -0
- package/dist/src/refine-llm.js.map +1 -0
- package/dist/src/replay.js +117 -0
- package/dist/src/replay.js.map +1 -0
- package/dist/src/salience.js +74 -0
- package/dist/src/salience.js.map +1 -0
- package/dist/src/scheduler.js +67 -0
- package/dist/src/scheduler.js.map +1 -0
- package/dist/src/scope.js +35 -0
- package/dist/src/scope.js.map +1 -0
- package/dist/src/search.js +801 -0
- package/dist/src/search.js.map +1 -0
- package/dist/src/server-detect.js +70 -0
- package/dist/src/server-detect.js.map +1 -0
- package/dist/src/server.js +784 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/shared.js +309 -0
- package/dist/src/shared.js.map +1 -0
- package/dist/src/sso.js +22 -0
- package/dist/src/sso.js.map +1 -0
- package/dist/src/store.js +1390 -0
- package/dist/src/store.js.map +1 -0
- package/dist/src/tenant.js +17 -0
- package/dist/src/tenant.js.map +1 -0
- package/dist/src/trace.js +64 -0
- package/dist/src/trace.js.map +1 -0
- package/dist/src/working-memory.js +149 -0
- package/dist/src/working-memory.js.map +1 -0
- package/dist/src/yaml.js +98 -0
- package/dist/src/yaml.js.map +1 -0
- package/dist/store.d.ts +9 -1
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +30 -2
- package/dist/store.js.map +1 -1
- package/extensions/openclaw-plugin/openclaw.plugin.json +1 -1
- package/extensions/openclaw-plugin/package.json +1 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +2 -2
- package/dist/import.d.ts +0 -31
- package/dist/import.d.ts.map +0 -1
- package/dist/import.js +0 -307
- package/dist/import.js.map +0 -1
package/README.md
CHANGED
|
@@ -5,33 +5,57 @@
|
|
|
5
5
|
[](https://npmjs.com/package/hippo-memory)
|
|
6
6
|
[](./LICENSE)
|
|
7
7
|
|
|
8
|
+
A memory layer for AI agents. Modeled on the hippocampus. Decay by default, strength through use, provenance on every memory. SQLite under the hood, zero runtime deps, works with every CLI agent you have.
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install -g hippo-memory && hippo init --scan ~
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
One command. Every git repo on your machine gets memory.
|
|
15
|
+
|
|
8
16
|
```
|
|
9
|
-
Works with:
|
|
10
|
-
Imports from:
|
|
11
|
-
Storage:
|
|
12
|
-
Dependencies:
|
|
17
|
+
Works with: Claude Code, Codex, Cursor, OpenClaw, OpenCode, Pi, any MCP client
|
|
18
|
+
Imports from: ChatGPT, Claude (CLAUDE.md), Cursor (.cursorrules), Slack, markdown
|
|
19
|
+
Storage: SQLite backbone with markdown mirrors. Git-trackable, human-readable.
|
|
20
|
+
Dependencies: Zero runtime deps. Node.js 22.5+. Optional embeddings via @xenova/transformers.
|
|
13
21
|
```
|
|
14
22
|
|
|
15
23
|
---
|
|
16
24
|
|
|
17
|
-
##
|
|
25
|
+
## Why this exists
|
|
26
|
+
|
|
27
|
+
Most "AI memory" systems save everything and search later. That's storage with semantic search bolted on. It's why your agent kept hitting the same deploy bug last week. And the week before. The system saw the failure four times. It had no way to know it should remember.
|
|
28
|
+
|
|
29
|
+
Hippo applies the thing brains have been getting right for 500 million years. Memories decay over time. Retrieval makes them stronger. Three biological layers (buffer, episodic, semantic) consolidate during sleep. Hard lessons stick because you used them. Trivia fades because you didn't.
|
|
30
|
+
|
|
31
|
+
It also fixes the portability problem. Your ChatGPT memories don't travel to Claude. Your `.cursorrules` don't travel to Codex. Hippo is one process behind every agent. CLAUDE.md, Cursor rules, ChatGPT exports, Slack history, all in one SQLite store, all queryable from any tool that speaks MCP or HTTP.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Receipts
|
|
18
36
|
|
|
19
|
-
|
|
37
|
+
Numbers, not adjectives. Every claim links to the benchmark or the test that proves it.
|
|
20
38
|
|
|
21
|
-
|
|
39
|
+
- **78% → 14% trap rate.** [Sequential Learning Benchmark](benchmarks/sequential-learning/). 50 tasks, 10 buried traps. Measures whether agents actually learn from past mistakes, not just retrieve text.
|
|
40
|
+
- **R@5 = 74.0%** on [LongMemEval](benchmarks/longmemeval/). 500-question industry retrieval benchmark, BM25 only, no embeddings.
|
|
41
|
+
- **10 of 10 incident scenarios beat transcript replay** on a staged Slack corpus ([benchmarks/e1.3/](benchmarks/e1.3/)). Recall surfaces the cause faster than scrolling the last N messages.
|
|
42
|
+
- **0 outbound HTTP** on the 1000-event ingestion smoke. Proven by a `globalThis.fetch` spy that throws on call, not a hardcoded zero.
|
|
43
|
+
- **926 tests, real DB, zero mocks.** Project rule. The one mocks-vs-prod divergence that bit us early is now the constraint that kept the next ten releases honest.
|
|
44
|
+
- **dlPFC goal-conditioned cluster discrimination, 3/3 queries pass** — full goal stack with policy weighting and lifespan-windowed outcome propagation. Per-goal lift on a 3-cluster fixture where BM25 alone cannot discriminate; deterministic test in [`benchmarks/micro/results/b3-depth.json`](benchmarks/micro/results/b3-depth.json).
|
|
22
45
|
|
|
23
46
|
---
|
|
24
47
|
|
|
25
|
-
##
|
|
48
|
+
## What it does for your agent
|
|
26
49
|
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
29
|
-
- **
|
|
30
|
-
- **
|
|
50
|
+
- **Stops repeating mistakes.** Tag a failure with `--tag error` once, the lesson surfaces every time the agent walks back into that part of the code. Errors decay slower than ordinary observations.
|
|
51
|
+
- **Survives tool switches.** Use Claude Code on Monday, Cursor on Tuesday, Codex on Wednesday. Same `.hippo/` store. Same memories. Pick up exactly where you left off.
|
|
52
|
+
- **Ingests systems of record.** Slack today (`POST /v1/connectors/slack/events`). GitHub, Jira, Notion next. Webhooks land as `kind='raw'` memories with full provenance and GDPR-correct deletion.
|
|
53
|
+
- **Knows where every memory came from.** Every row carries `kind`, `scope`, `owner`, and `artifact_ref`. Right-to-be-forgotten is a single API call, not an audit nightmare.
|
|
54
|
+
- **Plays nice with multi-tenant.** API keys, scrypt-hashed. Audit log on every mutation. Tenant A literally cannot see tenant B's memories. Proven by negative test.
|
|
31
55
|
|
|
32
56
|
---
|
|
33
57
|
|
|
34
|
-
## Quick
|
|
58
|
+
## Quick start
|
|
35
59
|
|
|
36
60
|
```bash
|
|
37
61
|
npm install -g hippo-memory
|
|
@@ -43,14 +67,15 @@ hippo init
|
|
|
43
67
|
hippo init --scan ~
|
|
44
68
|
```
|
|
45
69
|
|
|
46
|
-
`--scan` finds every git repo under your home directory, creates a `.hippo/` store in each one, and seeds it with lessons from
|
|
70
|
+
`--scan` finds every git repo under your home directory, creates a `.hippo/` store in each one, and seeds it with lessons from the last 30 days of commit history. One command, instant memory across all your projects.
|
|
71
|
+
|
|
72
|
+
After setup, `hippo sleep` runs at session end (via auto-installed agent hooks) and does five things:
|
|
47
73
|
|
|
48
|
-
After setup, `hippo sleep` runs automatically at session end (via agent hooks) and does five things:
|
|
49
74
|
1. **Learns** from today's git commits
|
|
50
75
|
2. **Imports** new entries from Claude Code MEMORY.md files
|
|
51
76
|
3. **Consolidates** memories (decay, merge, prune)
|
|
52
|
-
4. **Deduplicates** near-identical memories
|
|
53
|
-
5. **Shares** high-value lessons to
|
|
77
|
+
4. **Deduplicates** near-identical memories, keeping the stronger copy
|
|
78
|
+
5. **Shares** high-value lessons to a global store so they surface in every project
|
|
54
79
|
|
|
55
80
|
```bash
|
|
56
81
|
# Manual usage
|
|
@@ -60,248 +85,23 @@ hippo recall "data pipeline issues" --budget 2000
|
|
|
60
85
|
|
|
61
86
|
---
|
|
62
87
|
|
|
63
|
-
### What's new in v0.
|
|
64
|
-
|
|
65
|
-
- **`hippo serve` daemon.** Persistent HTTP server on 127.0.0.1:6789. CLI auto-detects and becomes a thin client; one process owns the SQLite DB.
|
|
66
|
-
- **MCP-over-HTTP.** MCP clients can now connect over HTTP/SSE in addition to stdio. Same tool surface.
|
|
67
|
-
- **Bearer-token auth + loopback trust.** Set HIPPO_API_KEY for remote calls; loopback connections work without a key. Server refuses to bind to non-loopback host without auth.
|
|
68
|
-
- **Audit log fix.** Mutations on non-default tenants are now correctly attributed in the audit log (was using HIPPO_TENANT env, now uses the row's tenant_id).
|
|
69
|
-
- **Tenant deny on archive/forget.** A valid Bearer for tenant A can no longer affect tenant B's memories, cross-tenant requests return "memory not found".
|
|
70
|
-
- **Known issue:** p99 recall latency is 58.4ms on a 10k store, target is 50ms. Architecture ships; latency hardening in v0.37.0.
|
|
71
|
-
|
|
72
|
-
### What's new in v0.35.0
|
|
73
|
-
|
|
74
|
-
- **Stub auth landed.** API keys + audit log + per-tenant data isolation. `hippo auth create` mints a scrypt-hashed key shown plaintext exactly once. `hippo audit list` exposes the mutation trail.
|
|
75
|
-
- **Cross-tenant safety.** Set `HIPPO_TENANT=acme` (or pass an API key) and recall, explain, context, MCP, and dashboard all filter by that tenant. Tenant A cannot see tenant B's memories, proven by negative test.
|
|
76
|
-
- **Audit trail.** Every mutation writes to `audit_log`: remember, recall, promote, supersede, forget, archive, auth_revoke. Query with `hippo audit list --op recall --since 2026-04-01 --json`.
|
|
77
|
-
- **Schema v16.** `tenant_id` columns added to memories and four other tables, default 'default'. Existing data is unaffected.
|
|
78
|
-
- **SSO/SCIM stubs.** Hook points exist (throw `NotImplementedError`); full multi-tenant + OAuth deferred to v2.
|
|
79
|
-
|
|
80
|
-
### What's new in v0.34.0
|
|
81
|
-
|
|
82
|
-
- **Provenance envelope on every memory.** `kind` (raw / distilled / superseded), `scope`, `owner`, `artifact_ref` columns now ride alongside content. `hippo recall --why` shows them; `hippo remember --kind --scope --owner --artifact-ref` sets them. Foundation for ingestion connectors and right-to-be-forgotten.
|
|
83
|
-
- **Append-only invariant on raw memories.** `kind='raw'` rows can only leave the store via `archiveRawMemory(db, id, { reason, who })`, which audits into the new `raw_archive` table. Direct DELETE aborts via trigger. Sets up A4 lifecycle compliance.
|
|
84
|
-
- **Schema v14 + v15.** Auto-migrates on first open. Backwards compatible.
|
|
85
|
-
- **Pineal salience v2.** `--salience-threshold` for tuning the recall salience gate.
|
|
86
|
-
- **Enterprise execution roadmap.** New `ROADMAP-RESEARCH.md` re-sequences the 90-day plan after Codex + eng-review pass. Provenance first, then auth stub, then server mode, then first ingestion connector.
|
|
87
|
-
|
|
88
|
-
### What's new in v0.33.0
|
|
89
|
-
|
|
90
|
-
- **Fact extraction at sleep time.** `hippo sleep` now extracts standalone facts from episodic memories via LLM, stored as semantic-layer entries that score 1.3x higher and auto-deduplicate against their raw source in search results.
|
|
91
|
-
- **DAG summarization.** Extracted facts cluster by entity similarity into summary nodes. When a summary matches your query, its children drill down into results automatically.
|
|
92
|
-
- **Multi-hop retrieval.** `hippo recall --multihop` chains two search passes via entity tags discovered in the first pass, finding connections that single-pass search misses.
|
|
93
|
-
- **`hippo dag --stats`** shows how your memory is organized across DAG levels.
|
|
94
|
-
- **Performance fix.** Temporal scoring refactored from O(N^2) to O(N), eliminating stack overflow risk on large stores.
|
|
95
|
-
|
|
96
|
-
### What's new in v0.32.0
|
|
97
|
-
|
|
98
|
-
- **Correction without deletion.** `hippo supersede <old-id> "<new content>"` links the old memory as historical truth and creates a successor. Default recall shows only current beliefs; the old one stays in the store so you can audit what changed and when.
|
|
99
|
-
- **`--include-superseded`** on `recall` and `explain` surfaces historical memories with a `[superseded]` marker. Useful for "what did I used to think about X?"
|
|
100
|
-
- **`--as-of <ISO-date>`** returns the set of beliefs that were current at a past moment. Invalid dates exit with a clear format hint.
|
|
101
|
-
- **Schema v11, zero breaking changes.** Adds `valid_from` + `superseded_by` columns. Existing v10 stores upgrade on first open, no data loss, no manual migration.
|
|
102
|
-
- **Physics search ablation: CUT.** Benchmarked over 60 LongMemEval-oracle questions: physics-on is statistically worse than plain BM25 + embeddings on MRR, Recall@5, and NDCG@5 (paired bootstrap, 5000 iters, 95% CI excludes zero). Full results in `benchmarks/physics-ablation/`. Physics stays in the codebase this release; removal is a separate decision.
|
|
103
|
-
|
|
104
|
-
### What's new in v0.31.0
|
|
105
|
-
|
|
106
|
-
- **Scope-aware corrections.** Tag a memory with `hippo remember --scope plan-eng-review` and it only surfaces strongly when that scope is active again. Matching scope gets 1.5x boost, mismatching scope is suppressed 0.5x, unscoped memories stay neutral. Corrections said during one skill stop polluting unrelated contexts.
|
|
107
|
-
- **Auto-detect from env.** `HIPPO_SCOPE`, `GSTACK_SKILL`, `OPENCLAW_SKILL` populate the scope automatically. Explicit `--scope` on any command overrides.
|
|
108
|
-
- **`hippo explain --why`** now shows the `scope:` multiplier when it fires, so you can see why a memory got ranked up or down.
|
|
109
|
-
|
|
110
|
-
### What's new in v0.30.1
|
|
111
|
-
|
|
112
|
-
- **`hippo recall --layer <L>` is now a strict filter.** Previously the flag was accepted but silently dropped; other layers leaked into results. The RSI demo's `recall --layer trace` now does what it says.
|
|
113
|
-
- **`hippo status` prints a `Trace:` counter.** The new layer is visible in status output.
|
|
114
|
-
- **`hippo --version` / `-v`** works as expected. Previously errored.
|
|
115
|
-
|
|
116
|
-
### What's new in v0.30.0
|
|
117
|
-
|
|
118
|
-
- **Sequence binding for recursive-self-improvement agents.** New `Layer.Trace` memories store ordered `A → B → C → outcome` traces. Agents can `hippo trace record` explicitly, or just call `hippo session complete --outcome success` and let `hippo sleep` auto-promote completed sessions into queryable traces.
|
|
119
|
-
- **`hippo recall --outcome success`** — retrieve only successful prior strategies. The missing RSI primitive: "what worked last time I tried this?"
|
|
120
|
-
- **`examples/rsi-demo/`** — a minimal self-improving agent, deterministic and CI-runnable. Uses traces to learn. Current seed: 20% success on tasks 1-10 rising to 100% on tasks 41-50. Non-zero exit if the learning curve collapses — the demo is also the integration test.
|
|
121
|
-
- **Schema v3 migration, with a regression test that preserves existing data.** Idempotent auto-promotion via indexed `source_session_id`. Four inheritance smoke tests lock the claim that traces get decay / search / replay / physics "for free."
|
|
122
|
-
|
|
123
|
-
### What's new in v0.29.3
|
|
124
|
-
|
|
125
|
-
- **Post-install banner for Claude Code users.** After `npm install -g hippo-memory`, if Claude Code is detected but the Hippo hook isn't wired yet, a three-line message points the user at `hippo init`. Silent on reinstalls or machines without Claude Code. Opt out via `HIPPO_SKIP_POSTINSTALL=1`.
|
|
126
|
-
|
|
127
|
-
### What's new in v0.29.2
|
|
128
|
-
|
|
129
|
-
- **Fix UserPromptSubmit hook in fresh directories.** In v0.29.0/0.29.1, the `hippo context --pinned-only` hook errored with "No .hippo directory found" every time Claude Code opened a session in a cwd without a local hippo store, and would silently auto-create `.hippo/` there. Fixed: pinned-only falls back to global-only, leaves cwd untouched.
|
|
130
|
-
|
|
131
|
-
### What's new in v0.29.1
|
|
132
|
-
|
|
133
|
-
- **Raise default `pinnedInject.budget` to 1500.** Smoke-testing on a real 10-pinned-memory store showed 500 tokens truncated new invariants off the bottom. 1500 matches `defaultContextBudget` and fits typical mature installs. Explicit `.hippo/config.json` overrides are untouched; only the default changes.
|
|
134
|
-
|
|
135
|
-
### What's new in v0.29.0
|
|
136
|
-
|
|
137
|
-
- **Mid-session pinned re-injection (Claude Code).** Pinned memories now re-enter context every turn via a new `UserPromptSubmit` hook — not just at SessionStart — so invariants survive long sessions where Opus 4.7 might otherwise forget them. `hippo context --pinned-only --format additional-context` is the command the hook runs; it's read-only so retrieval_count doesn't inflate. Existing users must re-run `hippo hook install claude-code` to pick it up. Opt out with `{"pinnedInject":{"enabled":false}}` in `.hippo/config.json`.
|
|
138
|
-
- **Replay consolidation pass.** `hippo sleep` now rehearses 5 high-value memories per cycle (weighted by outcome feedback, emotional valence, under-rehearsal, idle time, strength). Closes the "replay" gap in the 7 hippocampal mechanisms. Non-destructive; opt out with `{"replay":{"count":0}}`.
|
|
139
|
-
- **Model profile benchmark (null result).** New reusable eval harness at `evals/model-profile-bench.json` + `scripts/run-model-profile-bench.mjs` measures invariant honor, hallucination guard, noise rejection, and contradiction rejection. 4.6 and 4.7 both score 100% with hippo context injection — no per-model profile tuning needed. See `docs/plans/2026-04-21-phase-a-decision.md`.
|
|
140
|
-
- **Physics soak test harness.** `scripts/soak-test.mjs` + 10 synthetic workload profiles. All 10 bounded at 100-tick smoke scale; grant-scale 100hr runs are separate follow-up work.
|
|
141
|
-
|
|
142
|
-
### What's new in v0.28.0
|
|
143
|
-
|
|
144
|
-
- **Budget saturation fix.** Large memories (14k+ chars) no longer starve retrieval. New `minResults` option guarantees at least N results regardless of token budget. `hippo recall <q> --min-results 5`.
|
|
145
|
-
- **LongMemEval parity restored.** The 35pp R@10 gap vs v0.11 was a benchmark methodology issue (budget-limited vs unlimited comparison). Corrected: v0.28 R@3 67.0% (+0.4pp), answer_in_content@5 49.6% (+3.0pp), R@10 81.0% (-1.6pp). Top-5 results now more often contain the actual answer.
|
|
146
|
-
- **MMR performance.** Re-ranking capped at top-100 candidates, dropping per-query time from ~50s to ~9s. `preparedCorpus` option skips per-query tokenization for batch callers.
|
|
147
|
-
- **RRF scoring option.** `hybridSearch` accepts `scoring: 'rrf'` for reciprocal rank fusion as an alternative to score blending.
|
|
148
|
-
- **`hippo refine` command.** LLM-powered semantic rewrite of memories for improved recall quality.
|
|
149
|
-
|
|
150
|
-
### What's new in v0.27.0
|
|
151
|
-
|
|
152
|
-
- **Recall is now debuggable.** `hippo explain <query>` prints the full score breakdown for each retrieved memory: BM25 + cosine, every multiplier (strength, recency, decision, path, source-bump, outcome), age, and final composite. Read-only so it's safe to run as a diagnostic.
|
|
153
|
-
- **`hippo trace <id>`** gives a one-page dossier per memory: decay trajectory projected to 30/90 days, effective half-life, retrieval staleness, outcome counts, consolidation parents, open conflicts.
|
|
154
|
-
- **MMR diversity** re-ranks near-duplicate results so you don't get five paraphrases at the top. Default `lambda=0.7`, tunable via config or `--no-mmr` / `--mmr-lambda`.
|
|
155
|
-
- **Outcome feedback is immediate.** `hippo outcome --good` now nudges that memory up on the very next recall (not just via slow half-life decay). Bounded at +/-15%.
|
|
156
|
-
- **`hippo eval`** measures recall quality against a test corpus (MRR, Recall@K, NDCG@K). Gate CI with `--min-mrr`. A real 15-case corpus ships at `evals/real-corpus.json`; baseline numbers in `evals/README.md`.
|
|
157
|
-
|
|
158
|
-
### What's new in v0.26.0
|
|
159
|
-
|
|
160
|
-
- **`hippo audit` catches junk memories.** New command flags too-short entries, release/merge/WIP commit noise, fragments, and vague single-clause notes. `--fix` removes the worst offenders. `hippo sleep` now runs audit automatically so commit-noise never survives consolidation.
|
|
161
|
-
- **Conflict detector stops firing on English prepositions.** The v0.25 detector was scanning whole memory bodies and flagging 800+ bogus "polarity mismatch" conflicts anywhere the words `on` / `off` / `in` / `out` appeared together. Rewritten to use stopword-filtered Jaccard, a rare-token gate, and an opening-window polarity check.
|
|
162
|
-
- **`hippo remember` rejects tiny inputs.** Content under 3 characters is blocked at the CLI with a clear error.
|
|
163
|
-
|
|
164
|
-
### What's new in v0.24.2
|
|
165
|
-
|
|
166
|
-
- **One daily runner per machine, not one task per project.** `hippo init` now registers each workspace and installs a machine-level `hippo daily-runner` job that sweeps every registered Hippo project at 6:15am.
|
|
167
|
-
- **OpenClaw session-end autosleep no longer blocks shutdown.** The native OpenClaw plugin now detaches `hippo sleep` on `session_end` when `autoSleep` is enabled.
|
|
168
|
-
- **Retrieval and refresh are now documented separately across tools.** Query-time recall still uses local plus global memory, while session-end hooks and the daily runner handle consolidation on their own paths.
|
|
169
|
-
|
|
170
|
-
### What's new in v0.24.1
|
|
171
|
-
|
|
172
|
-
- **Conflict detection stops over-weighting shared tags.** `feedback` / `policy` tags no longer make unrelated memories look contradictory on the next `hippo sleep`.
|
|
173
|
-
- **Reworded contradictions still get caught.** Hippo keeps pairs like `API auth must be enabled in prod` / `Disable API auth in prod` while dropping the false positives that triggered the review.
|
|
174
|
-
- **Broader regression coverage.** This release adds tests for the exact false-positive examples from the migrated store plus extra polarity cases like `must` vs `should not` and `available` vs `missing`.
|
|
175
|
-
|
|
176
|
-
### What's new in v0.24.0
|
|
177
|
-
|
|
178
|
-
- **Codex session-end memory is now automatic on install/update.** Hippo no longer tells Codex users to fix `PATH` by hand. The published package now attempts to wrap the detected `codex` launcher during install or upgrade, and it can self-heal on later Hippo commands if Codex shows up afterward.
|
|
179
|
-
- **Codex wrapper now patches the real launcher in place.** Hippo renames the original launcher to a sibling backup such as `codex.hippo-real.cmd` / `codex.hippo-real.exe`, writes a wrapper at the command users already invoke, and runs `hippo sleep` plus `hippo capture --last-session` after `/exit`.
|
|
180
|
-
- **Codex rollout transcripts are captured directly.** `hippo capture --last-session` now understands Codex `response_item` transcript JSONL, so session-end capture uses the real Codex transcript rather than a partial history reconstruction.
|
|
181
|
-
|
|
182
|
-
### What's new in v0.23.0
|
|
88
|
+
### What's new in v0.38.0
|
|
183
89
|
|
|
184
|
-
- **
|
|
185
|
-
- **
|
|
90
|
+
- **B3 dlPFC persistent goal stack (depth 3).** Schema v18 adds `goal_stack`, `retrieval_policy`, `goal_recall_log`. New CLI subcommands: `hippo goal push|list|complete|suspend|resume`. With `HIPPO_SESSION_ID` set, `hippo recall` auto-boosts memories tagged with the active goal (final multiplier hard-capped at 3.0x). Retrieval policies (`error-prioritized`, `schema-fit-biased`, `recency-first`, `hybrid`) further shape ranking.
|
|
91
|
+
- **Outcome propagation with lifespan window.** `hippo goal complete --outcome <score>` adjusts strength only on memories actually recalled while the goal was alive. `outcome >= 0.7` boosts (×1.10), `outcome < 0.3` decays (×0.85), neutral band leaves strength alone. UNIQUE(memory_id, goal_id) prevents double-propagation.
|
|
92
|
+
- **B3 cluster-discrimination micro-benchmark.** `benchmarks/micro/fixtures/dlpfc_depth.json` — 3 disjoint memory clusters under 3 named goals. Each query asserts the active goal's cluster is in top-3 AND the other two clusters are NOT, a deterministic test BM25 alone cannot pass. Receipt: 3/3 queries pass in [`benchmarks/micro/results/b3-depth.json`](benchmarks/micro/results/b3-depth.json).
|
|
93
|
+
- **Deferred to v0.39:** sequential-learning trap-rate lift (needs adapter contract change), MCP/REST `session_id` plumbing, vlPFC interference handling, `--no-propagate` flag.
|
|
186
94
|
|
|
187
|
-
### What's new in v0.
|
|
95
|
+
### What's new in v0.37.0
|
|
188
96
|
|
|
189
|
-
- **
|
|
97
|
+
- **Slack ingestion (E1.3).** First end-to-end ingestion connector. `POST /v1/connectors/slack/events` accepts HMAC-signed Events API webhooks; messages land as `kind='raw'` memories with `slack://team/channel/ts` provenance and a `slack:public:*` or `slack:private:*` scope. Source deletions route through `archiveRawMemory` (GDPR). Backfill via `hippo slack backfill --channel <id>`; malformed events to `hippo slack dlq list`.
|
|
98
|
+
- **Schema v17.** New tables: `slack_event_log` (idempotency), `slack_cursors` (backfill resume), `slack_dlq` (parse failures), `slack_workspaces` (team_id to tenant_id routing).
|
|
99
|
+
- **`PUBLIC_ROUTES` allow-list + `HIPPO_REQUIRE_AUTH` knob.** The Slack webhook is the first explicit public `/v1/*` route (HMAC-signed, no Bearer). Every other `/v1/*` route returns 401 without auth when `HIPPO_REQUIRE_AUTH=1`.
|
|
100
|
+
- **Recall default-deny on private scopes.** No-scope queries cannot see `slack:private:*` memories. Frontend callers passing undefined scope no longer leak private content.
|
|
101
|
+
- **`api.remember.afterWrite` hook.** Connectors stamp idempotency rows atomically with the memory row via a SAVEPOINT-scoped callback.
|
|
190
102
|
|
|
191
|
-
|
|
103
|
+
For everything since v0.8.0, see [CHANGELOG.md](./CHANGELOG.md).
|
|
192
104
|
|
|
193
|
-
- **`hippo capture --last-session` works.** The placeholder from earlier releases is now implemented. It reads the JSONL transcript of the most recent agent session and extracts actionable memories (decisions, rules, errors, preferences). Resolves the transcript from `--transcript <path>`, stdin JSON payload (the shape SessionEnd hooks pass), or auto-discovery under `~/.claude/projects/`.
|
|
194
|
-
- **SessionEnd auto-runs `hippo capture`.** `hippo init` / `hippo setup` now installs a second SessionEnd entry alongside `hippo sleep` — one summary per `/exit`, not per turn. Existing installs pick it up on re-run (idempotent).
|
|
195
|
-
- **Claude Code plugin moved off `Stop`.** The plugin's `hooks.json` now fires sleep + capture + outcome on `SessionEnd`, matching the JSON-hook install path.
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
npm install -g hippo-memory
|
|
199
|
-
hippo setup # picks up the new SessionEnd capture hook
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### What's new in v0.21.0
|
|
203
|
-
|
|
204
|
-
- **`hippo setup` — one command, every tool.** Detects Claude Code, OpenCode, OpenClaw, Codex, Cursor, and Pi on your machine and installs all available SessionEnd + SessionStart hooks in one pass. It also repairs the machine-level daily runner. Idempotent — safe to re-run.
|
|
205
|
-
- **OpenCode hooks.** SessionEnd + SessionStart install into `~/.config/opencode/opencode.json` (OpenCode added Claude-Code-compatible hooks in Jan 2026).
|
|
206
|
-
- **You actually see consolidation output now.** New `SessionStart` hook prints the previous session's `hippo sleep` output between banners on the next startup. Previously, SessionEnd output was invisible because the TUI was tearing down when it ran.
|
|
207
|
-
|
|
208
|
-
```bash
|
|
209
|
-
npm install -g hippo-memory
|
|
210
|
-
hippo setup # or: hippo hook install claude-code
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
### What's new in v0.20.3
|
|
214
|
-
|
|
215
|
-
- **Visible confirmation on session-end sleep.** The installed `SessionEnd` hook now echoes `[hippo] consolidating memory...` before running and `[hippo] sleep complete` / `[hippo] sleep failed` after, so you can see consolidation actually ran. Existing installs need a reinstall (`hippo hook uninstall claude-code && hippo hook install claude-code`) to pick up the new command.
|
|
216
|
-
|
|
217
|
-
### What's new in v0.20.2
|
|
218
|
-
|
|
219
|
-
- **Claude Code hook uses `SessionEnd`, not `Stop`.** Earlier versions ran `hippo sleep` after every assistant turn; now it runs once at session exit. Re-running `hippo hook install claude-code` migrates existing `Stop` entries automatically.
|
|
220
|
-
- **No more accidental `CLAUDE.md` files.** `hippo hook install` and `hippo init` only patch agent-instruction files that already exist — they no longer create fresh ones in unrelated directories.
|
|
221
|
-
|
|
222
|
-
### What's new in v0.20
|
|
223
|
-
|
|
224
|
-
- **`hippo dedup`.** Scans for near-duplicate memories, shows you what's duplicated and why (redundant semantic patterns, same lesson from multiple sources, cross-layer overlap), and removes the weaker copy. Runs automatically during `hippo sleep`.
|
|
225
|
-
- **MEMORY.md import.** `hippo init` and `hippo sleep` now scan Claude Code memory files and import new entries. Your agent memories from Claude Code flow into hippo automatically.
|
|
226
|
-
|
|
227
|
-
### What's new in v0.19.1
|
|
228
|
-
|
|
229
|
-
- **Configured embedding models now work end to end.** `hippo embed`, hybrid search, and physics search all respect `embeddings.model` from `.hippo/config.json`.
|
|
230
|
-
- **Safe rebuild on model change.** If you switch embedding models, rerun `hippo embed`. Hippo now rebuilds cached embeddings and resets physics state so old vectors are not mixed with the new model.
|
|
231
|
-
|
|
232
|
-
### What's new in v0.18
|
|
233
|
-
|
|
234
|
-
- **Multi-project auto-discovery.** `hippo init --scan [dir]` finds all git repos under a directory and initializes each one. Seeds with a full year of git history by default. One command to set up memory across all your projects.
|
|
235
|
-
|
|
236
|
-
### What's new in v0.17
|
|
237
|
-
|
|
238
|
-
- **Auto-share to global.** `hippo sleep` now promotes high-value memories to the global store automatically. Universal lessons travel across projects; project-specific memories stay local. No manual `hippo promote` needed.
|
|
239
|
-
|
|
240
|
-
### What's new in v0.16
|
|
241
|
-
|
|
242
|
-
- **Auto-learn from git.** `hippo init` seeds the store with 30 days of commit history. `hippo sleep` captures today's commits before consolidation. New users get instant memory; existing users get continuous learning. Both skippable with `--no-learn`.
|
|
243
|
-
|
|
244
|
-
### What's new in v0.15
|
|
245
|
-
|
|
246
|
-
- **Adaptive decay for intermittent agents.** Memories now decay based on how often the agent actually runs, not wall-clock time. A weekly agent's memories persist ~7x longer automatically. Three modes via `decayBasis` in `.hippo/config.json`: `"adaptive"` (default), `"session"`, or `"clock"`.
|
|
247
|
-
|
|
248
|
-
### What's new in v0.14
|
|
249
|
-
|
|
250
|
-
- **OpenClaw backup cleanup.** Plugin updates no longer leave `hippo-memory.bak-*` directories that cause duplicate plugin ID errors. Cleanup runs automatically at boot.
|
|
251
|
-
|
|
252
|
-
### What's new in v0.13
|
|
253
|
-
|
|
254
|
-
- **Security: command injection fixed.** OpenClaw plugin now uses `execFileSync` (no shell). All user input is passed as array args, eliminating shell injection vectors.
|
|
255
|
-
- **25+ bug fixes** across search, embeddings, physics, MCP server, store, and CLI: NaN propagation, token budget accuracy, atomic writes, FTS/LIKE escaping, Buffer-based MCP parsing, protocol compliance, and more. See [CHANGELOG](./CHANGELOG.md) for the full list.
|
|
256
|
-
|
|
257
|
-
### What's new in v0.12
|
|
258
|
-
|
|
259
|
-
- **Configurable global store.** Set `$HIPPO_HOME` or use XDG (`$XDG_DATA_HOME/hippo`) to put the global store wherever you want. Falls back to `~/.hippo/` if neither is set.
|
|
260
|
-
|
|
261
|
-
### What's new in v0.11
|
|
262
|
-
|
|
263
|
-
- **OpenClaw error capture filtering.** The `autoLearn` hook now applies three filters before storing tool errors: noise pattern filter, per-session rate limiting (max 5), and deduplication. Prevents memory pollution from infrastructure noise.
|
|
264
|
-
- **Orphaned embedding pruning.** `hippo embed` removes cached vectors for deleted memories.
|
|
265
|
-
- **Cross-platform path handling.** OpenClaw plugin uses `path/posix` for consistent `.hippo` detection on Unix with Windows-style paths.
|
|
266
|
-
|
|
267
|
-
### What's new in v0.11.0
|
|
268
|
-
|
|
269
|
-
- **Reward-proportional decay.** Outcome feedback now modulates decay rate continuously instead of fixed half-life deltas. Memories with consistent positive outcomes decay up to 1.5x slower; consistent negatives decay up to 2x faster. Mixed outcomes converge toward neutral. Inspired by R-STDP in spiking neural networks. `hippo inspect` now shows cumulative outcome counts and the computed reward factor.
|
|
270
|
-
- **Public benchmarks.** Two benchmarks in `benchmarks/`: a [Sequential Learning Benchmark](benchmarks/sequential-learning/) (50 tasks, 10 traps, measures agent improvement over time) and a [LongMemEval integration](benchmarks/longmemeval/) (industry-standard 500-question retrieval benchmark, R@5=74.0% with BM25 only). The sequential learning benchmark is unique: no other public benchmark tests whether memory systems produce learning curves.
|
|
271
|
-
|
|
272
|
-
### What's new in v0.10.0
|
|
273
|
-
|
|
274
|
-
- **Active invalidation.** `hippo learn --git` detects migration and breaking-change commits and actively weakens memories referencing the old pattern. Manual invalidation via `hippo invalidate "REST API" --reason "migrated to GraphQL"`.
|
|
275
|
-
- **Architectural decisions.** `hippo decide` stores one-off decisions with 90-day half-life and verified confidence. Supports `--context` for reasoning and `--supersedes` to chain decisions when the architecture evolves.
|
|
276
|
-
- **Path-based memory triggers.** Memories auto-tagged with `path:<segment>` from your working directory. Recall boosts memories from the same location (up to 1.3x). Working in `src/api/`? API-related memories surface first.
|
|
277
|
-
- **OpenCode integration.** `hippo hook install opencode` patches AGENTS.md. Auto-detected during `hippo init`. Integration guide with MCP config and skill for progressive discovery.
|
|
278
|
-
- **`hippo export`** outputs all memories as JSON or markdown.
|
|
279
|
-
- **Decision recall boost.** 1.2x scoring multiplier for decision-tagged memories so they surface despite low retrieval frequency.
|
|
280
|
-
|
|
281
|
-
### What's new in v0.9.1
|
|
282
|
-
|
|
283
|
-
- **Auto-sleep on session exit.** `hippo hook install claude-code` now installs a Stop hook in `~/.claude/settings.json` so `hippo sleep` runs automatically when Claude Code exits. `hippo init` does this too when Claude Code is detected. No cron needed, no manual sleep.
|
|
284
|
-
|
|
285
|
-
### What's new in v0.9.0
|
|
286
|
-
|
|
287
|
-
- **Working memory layer** (`hippo wm push/read/clear/flush`). Bounded buffer (max 20 per scope) with importance-based eviction. Current-state notes live separately from long-term memory.
|
|
288
|
-
- **Session handoffs** (`hippo handoff create/latest/show`). Persist session summaries, next actions, and artifacts so successor sessions can resume without transcript archaeology.
|
|
289
|
-
- **Session lifecycle** with explicit start/end events, fallback session IDs, and `hippo session resume` for continuity.
|
|
290
|
-
- **Explainable recall** (`hippo recall --why`). See which terms matched, whether BM25 or embedding contributed, and the source bucket (layer, confidence, local/global).
|
|
291
|
-
- **`hippo current show`** for compact current-state display (active task + recent session events), ready for agent injection.
|
|
292
|
-
- **SQLite lock hardening**: `busy_timeout=5000`, `synchronous=NORMAL`, `wal_autocheckpoint=100`. Concurrent plugin calls no longer hit `SQLITE_BUSY`.
|
|
293
|
-
- **Consolidation batching**: all writes/deletes happen in a single transaction instead of N open/close cycles.
|
|
294
|
-
- **`--limit` flag** on `hippo recall` and `hippo context` to cap result count independently of token budget.
|
|
295
|
-
- **Plugin injection dedup guard** prevents double context injection on reconnect.
|
|
296
|
-
|
|
297
|
-
### What's new in v0.8.0
|
|
298
|
-
|
|
299
|
-
- **Hybrid search** blends BM25 keywords with cosine embedding similarity. Install `@xenova/transformers`, run `hippo embed`, recall quality jumps. Falls back to BM25 otherwise.
|
|
300
|
-
- Configure a custom embedding model with `embeddings.model` in `.hippo/config.json`. If you change models later, rerun `hippo embed` so Hippo rebuilds cached embeddings and physics state for the new vector space.
|
|
301
|
-
- **Schema acceleration** auto-computes how well new memories fit existing patterns. Familiar memories consolidate faster; novel ones decay faster if unused.
|
|
302
|
-
- **Multi-agent shared memory** with `hippo share`, `hippo peers`, and transfer scoring. Universal lessons travel between projects; project-specific config stays local.
|
|
303
|
-
- **Conflict resolution** via `hippo resolve <id> --keep <mem_id>`. Closes the detect-inspect-resolve loop.
|
|
304
|
-
- **Agent eval benchmark** validates the learning hypothesis: hippo agents drop from 78% trap rate to 14% over a 50-task sequence.
|
|
305
105
|
|
|
306
106
|
### Zero-config agent integration
|
|
307
107
|
|
|
@@ -362,6 +162,14 @@ hippo capture --file conversation.md
|
|
|
362
162
|
hippo capture --file conversation.md --dry-run
|
|
363
163
|
```
|
|
364
164
|
|
|
165
|
+
### Slack ingestion (E1.3)
|
|
166
|
+
|
|
167
|
+
Hippo accepts Slack Events API webhooks at `POST /v1/connectors/slack/events`. Configure `SLACK_SIGNING_SECRET` (validated on every request) and point Slack at `https://<your-host>/v1/connectors/slack/events`. Messages land as `kind='raw'` memories with `slack://team/channel/ts` provenance and a `slack:public:Cxxx` or `slack:private:Cxxx` scope. Source deletions are honored (GDPR).
|
|
168
|
+
|
|
169
|
+
Backfill an existing channel: `SLACK_BOT_TOKEN=xoxb-... hippo slack backfill --channel C0000`. Inspect malformed events: `hippo slack dlq list`.
|
|
170
|
+
|
|
171
|
+
Multi-workspace deployments populate `slack_workspaces (team_id, tenant_id)` to route events per tenant; single-workspace falls back to `HIPPO_TENANT`.
|
|
172
|
+
|
|
365
173
|
### Active task snapshots
|
|
366
174
|
|
|
367
175
|
Long-running work needs short-term continuity, not just long-term memory. Hippo can persist the current in-flight task so a later `continue` has something concrete to recover.
|
package/dist/api.d.ts
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
* (`hippo serve`, A1) call into this module so the business logic lives
|
|
7
7
|
* in exactly one place.
|
|
8
8
|
*/
|
|
9
|
+
import { type DatabaseSyncLike } from './db.js';
|
|
9
10
|
import { type MemoryKind } from './memory.js';
|
|
10
11
|
import { type AuditEvent, type AuditOp } from './audit.js';
|
|
11
12
|
import { type ApiKeyListItem } from './auth.js';
|
|
@@ -22,6 +23,15 @@ export interface RememberOpts {
|
|
|
22
23
|
owner?: string;
|
|
23
24
|
artifactRef?: string;
|
|
24
25
|
tags?: string[];
|
|
26
|
+
/**
|
|
27
|
+
* Optional hook invoked inside the same transaction as the underlying
|
|
28
|
+
* memories INSERT. Used by ingestion connectors (E1.3+) to stamp
|
|
29
|
+
* idempotency / cursor rows atomically with the memory row, so a crash
|
|
30
|
+
* mid-write cannot produce a memory without its corresponding side-effect
|
|
31
|
+
* log row (or vice versa). If the callback throws, the INSERT is rolled
|
|
32
|
+
* back and the error is rethrown.
|
|
33
|
+
*/
|
|
34
|
+
afterWrite?: (db: DatabaseSyncLike, memoryId: string) => void;
|
|
25
35
|
}
|
|
26
36
|
export interface RememberResult {
|
|
27
37
|
id: string;
|
|
@@ -33,6 +43,16 @@ export interface RecallOpts {
|
|
|
33
43
|
query: string;
|
|
34
44
|
limit?: number;
|
|
35
45
|
mode?: 'bm25' | 'hybrid' | 'physics';
|
|
46
|
+
/**
|
|
47
|
+
* Restrict results to memories whose `scope` equals this value exactly.
|
|
48
|
+
*
|
|
49
|
+
* When `scope` is undefined or empty, recall applies a DEFAULT-DENY rule:
|
|
50
|
+
* any memory whose scope starts with `'slack:private:'` is filtered out so
|
|
51
|
+
* a frontend caller passing `undefined` cannot accidentally surface
|
|
52
|
+
* private-channel content. Memories with scope=null (the common case for
|
|
53
|
+
* non-Slack content) are still returned.
|
|
54
|
+
*/
|
|
55
|
+
scope?: string;
|
|
36
56
|
}
|
|
37
57
|
export interface RecallResultItem {
|
|
38
58
|
id: string;
|
package/dist/api.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
package/dist/api.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* in exactly one place.
|
|
8
8
|
*/
|
|
9
9
|
import { openHippoDb, closeHippoDb } from './db.js';
|
|
10
|
-
import { writeEntry, readEntry, deleteEntry, loadSearchEntries, } from './store.js';
|
|
10
|
+
import { writeEntry, readEntry, deleteEntry, loadSearchEntries, removeEntryMirrors, } from './store.js';
|
|
11
11
|
import { createMemory, Layer, } from './memory.js';
|
|
12
12
|
import { appendAuditEvent, queryAuditEvents, } from './audit.js';
|
|
13
13
|
import { promoteToGlobal, getGlobalRoot } from './shared.js';
|
|
@@ -24,7 +24,7 @@ export function remember(ctx, opts) {
|
|
|
24
24
|
});
|
|
25
25
|
// writeEntry threads ctx.actor into its internal audit hook, so exactly
|
|
26
26
|
// one 'remember' event lands in the log with the supplied actor.
|
|
27
|
-
writeEntry(ctx.hippoRoot, entry, { actor: ctx.actor });
|
|
27
|
+
writeEntry(ctx.hippoRoot, entry, { actor: ctx.actor, afterWrite: opts.afterWrite });
|
|
28
28
|
return { id: entry.id, kind: entry.kind, tenantId: ctx.tenantId };
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
@@ -35,7 +35,20 @@ export function remember(ctx, opts) {
|
|
|
35
35
|
*/
|
|
36
36
|
export function recall(ctx, opts) {
|
|
37
37
|
const limit = opts.limit ?? 10;
|
|
38
|
-
const
|
|
38
|
+
const all = loadSearchEntries(ctx.hippoRoot, opts.query, undefined, ctx.tenantId);
|
|
39
|
+
// Scope filtering runs AFTER the tenant filter inside loadSearchEntries, so
|
|
40
|
+
// a tenant-mismatched scope cannot surface another tenant's row even when
|
|
41
|
+
// both share the same scope string (e.g. 'slack:private:CSHARED').
|
|
42
|
+
let entries;
|
|
43
|
+
if (opts.scope !== undefined && opts.scope !== '') {
|
|
44
|
+
entries = all.filter((e) => e.scope === opts.scope);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Default-deny: a no-scope caller cannot see private slack channels. This
|
|
48
|
+
// is load-bearing because frontend callers will pass `undefined` and must
|
|
49
|
+
// not see `slack:private:*` rows by default.
|
|
50
|
+
entries = all.filter((e) => !(e.scope ?? '').startsWith('slack:private:'));
|
|
51
|
+
}
|
|
39
52
|
// BM25 ordering already comes from loadSearchEntries; cap to `limit`.
|
|
40
53
|
// Score is a placeholder — the physics/hybrid scorers in src/search.ts
|
|
41
54
|
// produce richer breakdowns and will replace this when wired up.
|
|
@@ -207,6 +220,13 @@ export function archiveRaw(ctx, id, reason) {
|
|
|
207
220
|
finally {
|
|
208
221
|
closeHippoDb(db);
|
|
209
222
|
}
|
|
223
|
+
// archiveRawMemory deletes the memories row but leaves any legacy markdown
|
|
224
|
+
// mirror in <root>/{buffer,episodic,semantic}/<id>.md untouched. If we left
|
|
225
|
+
// the mirror in place, a subsequent initStore() on an empty memories table
|
|
226
|
+
// would silently re-import the row via bootstrapLegacyStore — defeating the
|
|
227
|
+
// archive (and the GDPR right-to-be-forgotten promise on raw rows). Mirror
|
|
228
|
+
// forget() at src/store.ts:1046, which uses the same removeEntryMirrors call.
|
|
229
|
+
removeEntryMirrors(ctx.hippoRoot, id);
|
|
210
230
|
// archiveRawMemory does not return the archive_at timestamp it wrote. We
|
|
211
231
|
// emit a fresh ISO timestamp here for the API response. Within a millisecond
|
|
212
232
|
// of the actual write, fine for a server response shape.
|
package/dist/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,
|
|
1
|
+
{"version":3,"file":"api.js","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E1.3 incident-recall eval (Task 17).
|
|
3
|
+
*
|
|
4
|
+
* ROADMAP success criterion: recall surfaces incident context faster than
|
|
5
|
+
* transcript replay on at least 7 of 10 staged scenarios.
|
|
6
|
+
*
|
|
7
|
+
* Approach (review patch #8): stamp a per-message sentinel
|
|
8
|
+
* `[s:<scenario.id>:<m.ts>]` into the ingested text. Sentinels are unique
|
|
9
|
+
* across the corpus, so checking sentinel substring presence in
|
|
10
|
+
* `RecallResultItem.content` is a deterministic equality test — no false
|
|
11
|
+
* positives from ambient phrase repetition, no need to extend the recall
|
|
12
|
+
* response shape with artifact_ref.
|
|
13
|
+
*
|
|
14
|
+
* Baseline: take the last 10 messages of the raw transcript (the
|
|
15
|
+
* "transcript replay" a human would do by scrolling to the bottom). Answers
|
|
16
|
+
* are buried mid-transcript so the baseline misses them. Recall must beat
|
|
17
|
+
* that on >=7/10 scenarios.
|
|
18
|
+
*/
|
|
19
|
+
import { readFileSync } from 'fs';
|
|
20
|
+
import { join, dirname } from 'path';
|
|
21
|
+
import { fileURLToPath } from 'url';
|
|
22
|
+
import { ingestMessage } from '../../src/connectors/slack/ingest.js';
|
|
23
|
+
import { recall } from '../../src/api.js';
|
|
24
|
+
export async function runIncidentRecallEval(opts) {
|
|
25
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
26
|
+
const scenarios = JSON.parse(readFileSync(join(here, 'scenarios.json'), 'utf-8'));
|
|
27
|
+
const ctx = {
|
|
28
|
+
hippoRoot: opts.hippoRoot,
|
|
29
|
+
tenantId: 'default',
|
|
30
|
+
actor: 'eval:slack',
|
|
31
|
+
};
|
|
32
|
+
const results = [];
|
|
33
|
+
for (const sc of scenarios) {
|
|
34
|
+
const sentinel = (m) => `[s:${sc.id}:${m.ts}]`;
|
|
35
|
+
for (const m of sc.transcript) {
|
|
36
|
+
ingestMessage(ctx, {
|
|
37
|
+
teamId: 'T1',
|
|
38
|
+
channel: { id: sc.channel, is_private: false },
|
|
39
|
+
message: {
|
|
40
|
+
type: 'message',
|
|
41
|
+
channel: sc.channel,
|
|
42
|
+
user: m.user,
|
|
43
|
+
text: `${m.text} ${sentinel(m)}`,
|
|
44
|
+
ts: m.ts,
|
|
45
|
+
},
|
|
46
|
+
eventId: `${sc.id}:${m.ts}`,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
const r = recall(ctx, {
|
|
50
|
+
query: sc.query,
|
|
51
|
+
limit: 10,
|
|
52
|
+
scope: `slack:public:${sc.channel}`,
|
|
53
|
+
});
|
|
54
|
+
const recallHit = sc.answer_ts.filter((ts) => r.results.some((res) => res.content.includes(sentinel({ ts })))).length;
|
|
55
|
+
const recallPrecision = recallHit / sc.answer_ts.length;
|
|
56
|
+
// Baseline: linear transcript scan returning the last 10 messages — what a
|
|
57
|
+
// human does when they scroll to the bottom of a Slack channel. Direct
|
|
58
|
+
// ts equality is enough; sentinels are not in the raw transcript.
|
|
59
|
+
const tail = sc.transcript.slice(-10);
|
|
60
|
+
const baselineHit = sc.answer_ts.filter((ts) => tail.some((m) => m.ts === ts)).length;
|
|
61
|
+
const baselinePrecision = baselineHit / sc.answer_ts.length;
|
|
62
|
+
results.push({
|
|
63
|
+
id: sc.id,
|
|
64
|
+
recallPrecision,
|
|
65
|
+
baselinePrecision,
|
|
66
|
+
beat: recallPrecision > baselinePrecision,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
scenarios: results,
|
|
71
|
+
scenariosBeaten: results.filter((r) => r.beat).length,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=incident-recall-eval.js.map
|