memoryoss 0.2.0

Memory for AI Agents — store, recall, update, forget
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
# memoryOSS

[![CI](https://github.com/memoryOSScom/memoryOSS/actions/workflows/ci.yml/badge.svg)](https://github.com/memoryOSScom/memoryOSS/actions/workflows/ci.yml)
[![Latest Release](https://img.shields.io/github/v/release/memoryOSScom/memoryOSS)](https://github.com/memoryOSScom/memoryOSS/releases/latest)
[![GitHub stars](https://img.shields.io/github/stars/memoryOSScom/memoryOSS?style=social)](https://github.com/memoryOSScom/memoryOSS/stargazers)
[![License: AGPL-3.0](https://img.shields.io/badge/License-AGPL--3.0-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)

Persistent long-term memory for AI agents. memoryOSS runs as a local memory layer in front of the LLM API, with MCP always available for explicit memory tools. The runtime contract is versioned and machine-readable, so the product can be described precisely as a portable memory runtime instead of only a proxy.

> **Public Beta (v0.2.0)** — memoryOSS is a public beta for evaluation and testing. Features, APIs, and configuration may change without notice. Do not use for critical or regulated workloads. Please keep your own backups. This notice does not limit any mandatory statutory rights.

memoryOSS is for project context, preferences, prior fixes, and working history — not for replacing general world knowledge the model already has.

## Why It Exists

Agents lose project context between sessions. memoryOSS persists the things that actually matter in day-to-day work: decisions, conventions, fixes, constraints, and user preferences.

In public retention, regression, and soak runs, memoryOSS continued to retrieve early high-signal memories even after the stored corpus grew into the tens of thousands. The public test page publishes two clearly separated surfaces: internal proof loops such as 20k retention, long-memory regression, soak stability, the universal memory loop proof, extraction quality, observed duplicate rate, active memory size, observed false-positive injection rate, and the supported Claude/Codex compatibility matrix; plus an open comparison lane with published fixture memories, queries, expected anchors, and explicit failure thresholds.

The benchmark surface now also publishes a small multilingual calibration lane alongside the English default lane before any default embedding-model change is considered. That calibration is a visibility check, not a blanket claim that the current default model is already optimal for every multilingual workload.

In a separate constrained 10-task Claude benchmark, using recalled memory context instead of replaying the full task context reduced average input tokens by 44.4%. We treat this as evidence for repeated-task context compression in that workload, not as a universal promise of lower token usage in every workload.

## How It Works

1. Run memoryOSS locally as a small proxy and memory service.
2. Let it recall relevant project memory before the LLM call.
3. Let it extract durable project-specific facts after the response.
4. Keep explicit memory tools available through MCP when you want direct control.

## Fastest Install

Use a prebuilt release binary from GitHub Releases. Current archives:

- `memoryoss-linux-x86_64.tar.gz`
- `memoryoss-linux-aarch64.tar.gz`
- `memoryoss-darwin-x86_64.tar.gz`
- `memoryoss-darwin-aarch64.tar.gz`
- `memoryoss-windows-x86_64.zip`

Linux/macOS example:

```bash
curl -L https://github.com/memoryOSScom/memoryOSS/releases/latest/download/memoryoss-linux-x86_64.tar.gz -o memoryoss.tar.gz
tar xzf memoryoss.tar.gz
sudo install -m 0755 memoryoss /usr/local/bin/memoryoss
memoryoss setup --profile claude
```

Windows has a PowerShell example in [Windows](#windows).

If you prefer the install helper, it installs the latest release binary. Run setup explicitly afterwards:

```bash
curl -fsSL https://memoryoss.com/install.sh | sh
memoryoss setup --profile codex
```

Every published archive ships with a matching `.sha256` file, and the release workflows now attach a GitHub artifact attestation for the built archives before the GitHub Release is published. That is the signed install surface for the binary/update path today; memoryOSS is not claiming OS-native notarization or MSI/PKG installers yet.

## From Source

```bash
cargo install --git https://github.com/memoryOSScom/memoryOSS.git
memoryoss setup
```

## Docker

memoryOSS also ships as an official container image on GHCR:

- `ghcr.io/memoryosscom/memoryoss:latest`
- `ghcr.io/memoryosscom/memoryoss:<version>`

This is an additional self-hosting path, not a replacement for the source/binary install.

Before starting the container:

- copy [memoryoss.toml.example](memoryoss.toml.example) to `memoryoss.toml`
- set `[server].host = "0.0.0.0"` so the service is reachable outside the container
- set `[storage].data_dir = "/data"` so the persisted database lands on the mounted volume
- fill in your real API keys and secrets

### Minimal `docker run`

```bash
docker run -d \
  --name memoryoss \
  -p 8000:8000 \
  -v "$(pwd)/memoryoss.toml:/config/memoryoss.toml:ro" \
  -v memoryoss-data:/data \
  ghcr.io/memoryosscom/memoryoss:latest \
  -c /config/memoryoss.toml serve
```

### Minimal `docker compose`

```yaml
services:
  memoryoss:
    image: ghcr.io/memoryosscom/memoryoss:latest
    restart: unless-stopped
    ports:
      - "8000:8000"
    volumes:
      - ./memoryoss.toml:/config/memoryoss.toml:ro
      - memoryoss-data:/data
    command: ["-c", "/config/memoryoss.toml", "serve"]

volumes:
  memoryoss-data:
```

## Windows

Official GitHub Releases also publish a Windows archive with `memoryoss.exe`:

- `memoryoss-windows-x86_64.zip`

### Minimal PowerShell install

```powershell
Invoke-WebRequest `
  https://github.com/memoryOSScom/memoryOSS/releases/latest/download/memoryoss-windows-x86_64.zip `
  -OutFile memoryoss-windows-x86_64.zip
Expand-Archive .\memoryoss-windows-x86_64.zip -DestinationPath .\memoryoss
Invoke-WebRequest `
  https://raw.githubusercontent.com/memoryOSScom/memoryOSS/main/memoryoss.toml.example `
  -OutFile .\memoryoss\memoryoss.toml
cd .\memoryoss
.\memoryoss.exe setup
```

Or, if you already have a config:

```powershell
.\memoryoss.exe -c .\memoryoss.toml serve
```

Windows-specific notes:

- keep `memoryoss.toml`, `memoryoss.key`, and the data directory in a user-only location such as `%LOCALAPPDATA%\memoryoss`
- use NTFS ACLs to protect secrets instead of Unix-style `chmod 600`
- if you set an absolute Windows `data_dir`, use a TOML-safe path such as `'C:\Users\you\AppData\Local\memoryoss\data'`
- if you need remote access from outside the machine, change `[server].host` to `0.0.0.0`; otherwise keep the default loopback host
- current Windows builds use a portable brute-force vector backend instead of `usearch`, so very large-memory recall will be slower than on Linux/macOS

The setup wizard now supports explicit install profiles: `auto`, `claude`, `codex`, `cursor`, and `team-node`. In `auto`, it detects your environment and writes the matching integrations. In explicit profiles, it only writes the profile-relevant surfaces. Claude profiles write deterministic MCP registrations plus guard hooks, Codex profiles write MCP plus the fallback policy block in `~/AGENTS.md`, Cursor profiles write `~/.cursor/mcp.json` plus the managed runtime rule `~/.cursor/rules/memoryoss.mdc`, and `team-node` configures whichever of Claude/Codex/Cursor are actually present on that workstation while keeping the machine service-first. Team nodes can also seed shared trust defaults via `--team-manifest`, which persists the manifest path plus a local bootstrap receipt so `memoryoss doctor --repair` can replay the rollout later without silently wiping local opt-ins. OAuth-first setups keep MCP enabled without forcing global `BASE_URL` overrides, so login flows keep working. Re-running setup with a non-Cursor explicit profile prunes the managed Cursor surfaces instead of leaving stale config behind. On a fresh setup it starts in **full** mode. If existing memories are already present, the wizard asks which memory mode you want and defaults that prompt to **full**.

If your auth setup changes later — for example from OAuth to API key or the other way around — run `memoryoss setup --profile <profile>` again so memoryOSS can safely update the integration path.

Team rollout example:

```bash
memoryoss setup --profile team-node --team-manifest ./team-bootstrap.json
memoryoss doctor --repair
```

That path replays the managed Claude/Codex/Cursor surfaces plus the shared trust catalog for the current workstation, while preserving local additions outside the managed memoryOSS blocks.

## Update Channels

memoryOSS now treats install and upgrade flow as an explicit product surface:

- stable channel: GitHub Releases tagged `vX.Y.Z` plus `ghcr.io/memoryosscom/memoryoss:latest`
- beta channel: prerelease tags such as `vX.Y.Z-beta.N` or `vX.Y.Z-rc.N` plus `ghcr.io/memoryosscom/memoryoss:beta`
- rollback channel: reinstall the last known-good release archive or pinned container tag, then restore the pre-update backup

The release smoke workflow exercises install, checksum verification, doctor, migrate, failed-update detection, and rollback recovery on Linux, macOS, and Windows before a smoke branch is promoted to a published release.

Recommended binary upgrade flow:

```bash
memoryoss backup -o memoryoss-preupdate.tar.zst --include-key
curl -L https://github.com/memoryOSScom/memoryOSS/releases/latest/download/memoryoss-linux-x86_64.tar.gz -o memoryoss.tar.gz
tar xzf memoryoss.tar.gz
sudo install -m 0755 memoryoss /usr/local/bin/memoryoss
memoryoss doctor
memoryoss migrate
```

If `doctor`, `migrate`, or post-upgrade startup fails:

```bash
sudo install -m 0755 ./previous-memoryoss /usr/local/bin/memoryoss
memoryoss restore memoryoss-preupdate.tar.zst
memoryoss doctor
```

For container installs, the equivalent rollback is to pin the previous image tag and keep the same mounted data volume plus the same backup/restore sequence.

## Hybrid Mode (Recommended)

For API-key setups, the default setup is hybrid:

- supported clients talk to the local memoryOSS gateway via `BASE_URL`
- MCP is also registered for Claude/Codex
- if the memory core is healthy, requests get recall/injection/extraction
- if the memory core is unavailable, the gateway falls back to direct upstream passthrough instead of breaking the client

For OAuth-first Claude/Codex setups, the wizard keeps MCP enabled and skips global `BASE_URL` exports by default so provider login continues to work normally. Claude can still use the proxy in supported OAuth paths; Codex OAuth stays MCP-first by default, and proxy mode for Codex requires an OpenAI API key.

Background fact extraction is only enabled automatically when a real provider API key is available. OAuth alone is enough for passthrough traffic, but not treated as a reliable extraction credential.

So you get transparent memory when available, plus explicit MCP tools when needed.

### After `memoryoss setup`

Start your selected client normally. The wizard always records the active setup profile, writes only the profile-relevant integrations, enforces Claude recall/store discipline through client hooks when Claude is selected, writes the Codex policy fallback to `~/AGENTS.md` when Codex is selected, writes Cursor MCP config plus the managed `~/.cursor/rules/memoryoss.mdc` runtime rule when Cursor is selected, seeds the shared trust catalog when `--team-manifest` is used, and only writes local `BASE_URL` exports when the chosen auth mode and profile are proxy-safe. If a managed team workstation drifts later, `memoryoss doctor --repair` replays the selected client surfaces plus the shared trust seed.

### Manual proxy mode (optional)

If you want to point clients at the gateway yourself:

### Claude Code / Claude API

```bash
export ANTHROPIC_BASE_URL=http://127.0.0.1:8000/proxy/anthropic/v1
export ANTHROPIC_API_KEY=<your-existing-key-or-oauth-flow>
```

### OpenAI / Codex CLI

```bash
export OPENAI_BASE_URL=http://127.0.0.1:8000/proxy/v1
export OPENAI_API_KEY=<your-openai-api-key>
```

Both the Chat Completions API (`/v1/chat/completions`) and the Responses API (`/v1/responses`) are supported in manual proxy mode. For Codex OAuth, the supported path remains MCP-first without forced global `BASE_URL` overrides.

### What memoryOSS Adds

memoryOSS is most useful when the missing context is specific to you or your work:

- project conventions and architecture decisions
- previous fixes, incidents, and deployment notes
- user preferences and recurring workflows
- facts learned in earlier sessions with Claude or Codex

It is not meant to inject generic facts the model already knows.

### How It Works

```
Client (Claude/Codex)
    │
    ▼
memoryOSS Gateway (:8000)
    ├── 1. Try memory core
    ├── 2. Recall: find relevant project memories
    ├── 3. Inject: add scoped context to the request
    ├── 4. Forward: send to upstream LLM API
    ├── 5. Extract: pull candidate facts from response (async)
    └── 6. Fail open to direct upstream if the core is unavailable
    │
    ▼
Upstream API (Anthropic / OpenAI)
```

### Memory Modes

memoryOSS supports 4 memory modes, configurable per-server (in config) or per-request (via headers):

| Mode | Recall | Store | Use Case |
|------|--------|-------|----------|
| `full` | Yes | Yes | Full automatic memory — recall past context, store new facts |
| `readonly` | Yes | No | See past memories but don't save anything from this session |
| `after` | Yes (filtered) | Yes | Only recall memories after a specific date |
| `off` | No | No | Pure proxy passthrough, no memory involvement |

On a fresh setup the wizard defaults to **full**. If existing memories are already present, the wizard asks which mode to use and defaults that prompt to `full`.

### Per-Request Memory Control

Control memory behavior per request via headers:

| Header | Values | Effect |
|--------|--------|--------|
| `X-Memory-Mode` | `full` / `readonly` / `off` / `after` | Set memory mode for this request |
| `X-Memory-After` | `YYYY-MM-DD` | Only inject memories after this date (with mode `after`) |
| `X-Memory-Policy-Confirm` | `true` / `1` / `yes` | Confirm a risky action that the policy firewall marked as `require_confirmation` |

Server operators can set a default mode in config (`default_memory_mode`) and disable client overrides with `allow_client_memory_control = false`.

## Configuration

Representative generated config

This is a representative hybrid config. The exact extraction provider/model and whether extraction is enabled depend on the tooling and real provider credentials the wizard detects.

```toml
[server]
host = "127.0.0.1"
port = 8000
hybrid_mode = true
core_port = 8001

[tls]
enabled = false
auto_generate = false

[auth]
jwt_secret = "..."
audit_hmac_secret = "..."

[[auth.api_keys]]
key = "ek_..."       # Generated by setup wizard
role = "admin"
namespace = "default"

[storage]
data_dir = "data"

[embeddings]
model = "all-minilm-l6-v2"                # Or bge-small-en-v1.5 / bge-base-en-v1.5 / bge-large-en-v1.5

[proxy]
enabled = true
passthrough_auth = true
passthrough_local_only = true              # Restrict passthrough to loopback clients by default
upstream_url = "https://api.openai.com/v1"
default_memory_mode = "full"               # Fresh setup default; existing installs are prompted
extraction_enabled = false                 # True only when a real provider API key is available
extract_provider = "openai"                # Or "claude", depending on detected auth
extract_model = "gpt-4o-mini"              # Or a provider-specific default such as Claude Haiku
allow_client_memory_control = true         # Allow X-Memory-Mode header (default: true)
max_memory_pct = 0.10                      # Max 10% of context window for memories
min_recall_score = 0.40                    # Minimum relevance score for injection (calibrated from internal query benchmarks)
min_channel_score = 0.15                   # Precision gate: min score in any channel (default: 0.15)
diversity_factor = 0.3                     # MMR diversity penalty (default: 0.3)
identifier_first_routing = true            # Route path/endpoint/env-var style queries through lexical-first reranking
memory_coprocessor = "off"                 # Or "local_heuristic" for deterministic local extraction

[[proxy.key_mapping]]
proxy_key = "ek_..."                       # Client-facing key
namespace = "default"                      # Memory isolation namespace
# upstream_key = "sk-..."                  # Optional per-client upstream key override

[logging]
level = "info"

[decay]
enabled = true
strategy = "age"
after_days = 14

[sharing]
allow_private_webhooks = false             # Keep localhost/private webhook targets blocked by default
```

### Managed Key Providers

`[encryption].provider = "local"` is the default and fully supported path.

`[encryption].provider = "vault"` is also supported through Vault Transit. The runtime now has hermetic coverage for:
- initial Vault bootstrap
- wrapped-key reload from disk
- rotation with a retained grace window for old ciphertext inside the running process
- fail-closed bootstrap errors

`aws_kms` is not currently a supported provider surface. The code accepts the value only to fail closed with an explicit unsupported error instead of silently downgrading to local keys.

## API Endpoints

### Proxy (transparent, no code changes)

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/proxy/v1/chat/completions` | POST | OpenAI Chat Completions proxy with memory |
| `/proxy/v1/responses` | POST | OpenAI Responses API proxy with memory (Codex CLI) |
| `/proxy/v1/models` | GET | Model list passthrough |
| `/proxy/anthropic/v1/messages` | POST | Anthropic proxy with memory |
| `/proxy/v1/debug/stats` | GET | Proxy metrics (auth required) |

### Memory API (direct access)

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/v1/auth/token` | POST | Get JWT from API key |
| `/v1/store` | POST | Store a memory |
| `/v1/store/batch` | POST | Store multiple memories |
| `/v1/recall` | POST | Semantic recall with raw memories plus summary/evidence view |
| `/v1/recall/batch` | POST | Batch recall |
| `/v1/update` | PATCH | Update a memory |
| `/v1/forget` | DELETE | Delete memories |
| `/v1/consolidate` | POST | Merge similar memories |
| `/health` | GET | Health check |

### Admin

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/v1/admin/keys` | GET | List API keys |
| `/v1/admin/keys/rotate` | POST | Rotate key |
| `/v1/admin/keys/{id}` | DELETE | Revoke a specific key |
| `/v1/admin/tokens` | POST | Create scoped tokens |
| `/v1/admin/cache/flush` | POST | Flush recall cache |
| `/v1/admin/cache/stats` | GET | Cache statistics |
| `/v1/admin/trust-stats` | GET | Memory trust scores |
| `/v1/admin/trust/fabric` | GET | Portable trust identities, imported catalogs, local pins, revocations, and replacement links |
| `/v1/admin/trust/catalog/export` | GET | Export the current trust fabric as a portable signer catalog |
| `/v1/admin/trust/catalog/import` | POST | Import or refresh a shared signer catalog into the local trust fabric |
| `/v1/admin/trust/pin` | POST | Locally pin one trust identity so verification shows an explicit local trust root |
| `/v1/admin/trust/unpin` | POST | Remove a local trust pin without deleting the identity |
| `/v1/admin/trust/register` | POST | Register an author, device, or sync-peer identity for artifact signing |
| `/v1/admin/trust/revoke` | POST | Revoke a portable trust identity and attach an optional replacement |
| `/v1/admin/trust/restore` | POST | Re-trust a previously revoked identity without silent data loss |
| `/v1/admin/trust/sign` | POST | Sign a portable bundle, passport, history artifact, or sync-peer descriptor |
| `/v1/admin/trust/verify` | POST | Verify a signed portable artifact against the current trust fabric |
| `/v1/admin/index-health` | GET | Index status |
| `/v1/admin/idf-stats` | GET | IDF index statistics |
| `/v1/admin/space-stats` | GET | Space index statistics |
| `/v1/admin/query-explain` | POST | Query debug/explain with summary + evidence drill-down |
| `/v1/admin/hud` | GET | Unified operator HUD as JSON or `?format=html` desktop view |
| `/v1/admin/lifecycle` | GET | Lifecycle state summary and latest memories |
| `/v1/admin/recent` | GET | Recent injections, extractions, feedbacks, and consolidations |
| `/v1/admin/team/governance` | GET | Branch/scope governance overview for governed team memory |
| `/v1/admin/team/governance/propose` | POST | Propose a governed team-memory write without dedup rejection |
| `/v1/admin/review-queue` | GET | Candidate / contested / rejected review inbox with suggested actions |
| `/v1/admin/review/action` | POST | Confirm, reject, or supersede via review keys |
| `/v1/admin/intent-cache/stats` | GET | Intent cache statistics |
| `/v1/admin/intent-cache/flush` | POST | Flush intent cache |
| `/v1/admin/prefetch/stats` | GET | Prefetch statistics |
| `/v1/inspect/{id}` | GET | Inspect memory by ID |
| `/v1/peek/{id}` | GET | Peek at memory content |
| `/v1/source` | GET | AGPL-3.0 source code info |
| `/metrics` | GET | Prometheus-style metrics |

Proxy memory injection now uses a two-level format inside `<memory_context>`:
- `<summary>` blocks give the compact task-facing memory
- `<evidence>` blocks carry bounded preview snippets plus provenance so operators can drill down without dumping raw stored content into every prompt

For recognized task classes (`deploy`, `bugfix`, `review`, `style`), memoryOSS now compiles an explicit `<task_state>` block instead of a flat memory list. That compiled state separates:
- facts
- constraints
- recent actions
- open questions
- evidence

The admin explain surface exposes the same compiled task state plus the input memories and condensation decisions that produced it.

Query explain now also returns a `policy_firewall` section. For risky action prompts (`deploy`, `delete`, `exfiltrate`, `override`) the same policy evaluation used by the proxy reports whether the request would `warn`, `block`, or `require_confirmation`, plus the exact policy memories that caused that intervention.

For privacy-sensitive flows, the proxy can switch to a local memory coprocessor instead of a remote extraction model. Set `memory_coprocessor = "local_heuristic"` to keep a bounded rule set fully local and deterministic for high-signal decisions such as deploy policies, branch habits, and proxy env exports. The proxy debug stats expose the active coprocessor mode so operators can verify when the local path is in effect.

The operator HUD at `/v1/admin/hud` folds that together with lifecycle, recent activity, review inbox, and import/export launcher actions. Use JSON for scripting or `?format=html` for a browser-ready desktop dashboard.

Governed team memory now rides on the same review and history primitives. `POST /v1/admin/team/governance/propose` records branch, scope, owners, watchlists, and whether the scope is review-required; `GET /v1/admin/team/governance` summarizes duplicate writes, stale merged policy, and conflicting decisions per branch. When a governed memory requires review, `/v1/admin/review/action` only allows `confirm` or `supersede` from a listed owner, and the merge provenance survives `history/replay` and passport export/import.

Proxy responses surface the same preflight via headers:
- `x-memory-policy-decision`
- `x-memory-policy-actions`
- `x-memory-policy-match-count`
- `x-memory-policy-confirmed`

If the firewall returns `require_confirmation`, resend the request with `X-Memory-Policy-Confirm: true`. Hard blocks return `403` before the upstream model is called.

### Portable Runtime Contract

memoryOSS now exposes a versioned runtime contract at `/v1/runtime/contract`.

Stable runtime semantics today:
- namespace-scoped memory records
- opaque provenance and lifecycle metadata
- explicit merge and supersede lineage
- contract-tagged portability export

Explicitly outside the stable runtime contract for now:
- retrieval strategy details like confidence gating and identifier-first routing
- broad replay/branch semantics beyond the current safe empty-target scope
- first-class typed policy and evidence objects with full import/export fidelity

### Runtime Conformance Kit

The runtime contract is now backed by a versioned conformance kit in [conformance/](conformance/README.md).

It ships:
- JSON Schemas for the current runtime contract, passport bundle, and history bundle lines
- canonical fixtures for `memoryoss.runtime.v1alpha1`, `memoryoss.passport.v1alpha1`, and `memoryoss.history.v1alpha1`
- reference reader/writer paths in Rust, Python, and TypeScript
- an automated compatibility harness in `python3 tests/run_conformance_kit.py`

Reference commands:

```bash
memoryoss conformance normalize --kind runtime_contract --input conformance/fixtures/runtime-contract.json --output /tmp/runtime.json
python3 tests/reference_conformance.py --kind passport --input conformance/fixtures/passport-bundle.json --output /tmp/passport.json
node sdk/typescript/dist/conformance.js --kind history --input conformance/fixtures/history-bundle.json --output /tmp/history.json
```

Compatibility policy:
- published artifact lines are immutable; breaking wire changes require a new `contract_id` or `bundle_version`
- readers must ignore unknown additive fields inside a published line
- once a successor line ships, memoryOSS keeps reader compatibility for the previous published line for at least two minor releases
- the conformance harness is the authoritative pass/fail gate for published lines

LTS policy for the current published line set:

| Surface | Current write line | Read / verify window | Migration / rollback guarantee |
| --- | --- | --- | --- |
| Runtime contract | `memoryoss.runtime.v1alpha1` | `N`, `N-1`, `N-2` published fixture snapshots | `memoryoss conformance normalize` must still accept published snapshots before a line leaves support |
| Passport bundle | `memoryoss.passport.v1alpha1` | `N`, `N-1`, `N-2` in the reader and passport import preview | Dry-run import must stay available for published fixtures during the support window |
| History bundle | `memoryoss.history.v1alpha1` | `N`, `N-1`, `N-2` in the reader and history replay preview | Dry-run replay must stay available for published fixtures during the support window |
| Memory bundle envelope | `memoryoss.bundle.v1alpha1` | `N`, `N-1`, `N-2` in reader, diff, and validate | Envelope validation must succeed for published snapshots unless integrity is actually broken |
| Sync peer sidecar signatures | current trust-fabric line | `N`, `N-1`, `N-2` verification window | Revocation, replacement identity, and signature verification remain readable even after writer upgrades |

Operational rules:
- memoryOSS only writes the current published line, never silently rewrites an older published artifact in place
- any future successor line must be announced in the conformance kit and public docs before the older line leaves the `N-2` reader window
- `bash tests/run_all.sh` now includes an explicit `compatibility and LTS` gate, and that gate exercises published `N`, `N-1`, and `N-2` fixture snapshots through normalize, reader, passport import dry-run, and history replay dry-run paths

### Universal Memory Loop Proof

The public portability claim is now backed by a reproducible proof runner:

```bash
python3 tests/run_universal_memory_loop.py
```

That runner now executes three stable end-to-end loops on local runtimes:
- store durable memories through the HTTP API
- export a passport through the CLI
- verify the exported artifact through the offline reader
- import that passport into a second runtime with dry-run merge/conflict preview
- verify portability through `query-explain`
- queue and confirm governed review items to measure operator throughput
- block risky delete requests and require confirmation for deploy requests through the proxy
- replay a history bundle into a clean namespace and compare lineage fidelity

The published report tracks hard daily-utility metrics from those loops:
- repeated-context elimination versus replaying the full portable notebook
- portability success rate
- passport merge/conflict rate
- review throughput
- blocked-bad-actions rate
- confirmation-gate success rate
- replay fidelity
- task-state quality

Claim lanes stay explicit:
- stable: repeated-context elimination, passport portability, review throughput, blocked bad actions, history replay, task-state portability proof
- external: open fixture-based recall/injection lane with published inputs, expected anchors, and explicit failure thresholds
- experimental: retrieval tuning, confidence gating, identifier-first routing, extraction quality deltas, provider-specific token/cost evidence
- moonshot: ambient everyday utility across every client and every workday

### Memory Bundle Envelope

memoryOSS now wraps portable artifacts in `memoryoss.bundle.v1alpha1`, a stable envelope around existing passport and history payloads.

The envelope adds:
- a top-level `bundle_version`
- a portable `memoryoss://bundle/...` URI and attachment-style filename
- separate outer-envelope integrity on top of the nested passport/history integrity line
- a runtime signature from `device:local-runtime` when `auth.audit_hmac_secret` is stable
- an embedded signature chain that can later be checked against revocations or replacement identities

Reference commands:

```bash
memoryoss bundle export --kind passport --namespace test --scope project -o project.membundle.json
memoryoss bundle preview project.membundle.json
memoryoss bundle validate project.membundle.json
memoryoss bundle diff old.membundle.json new.membundle.json
memoryoss reader open project.membundle.json
memoryoss reader diff old.membundle.json new.membundle.json --format html
```

`memoryoss reader` is the offline read-only path on top of those artifacts. It can open an exported envelope or a raw published passport/history artifact, print summary/provenance/signature data, and diff two artifacts without needing a running daemon or even a valid local config file.

When a valid `--config` is available, the reader also verifies signed bundle envelopes against the local trust fabric and shows `trusted`, `revoked`, or `invalid_signature` plus any replacement identity. It now also reports whether trust came from a local pin, an imported signer catalog, or an unknown signer. The admin trust endpoints provide the write path around that same fabric so passports and sync-peer descriptors can use sidecar signatures without mutating the raw artifact.

`memoryoss status` and `memoryoss doctor` now print the active runtime embedding model and expected vector dimension explicitly, so embedding drift is visible without starting a full proxy session.

### Cross-App Adapter Bridges

memoryOSS can now normalize dominant local client artifacts into the same runtime contract instead of treating them as opaque files.

Implemented adapter paths:
- `claude_project` — import/export Markdown-style Claude Project knowledge files
- `cursor_rules` — import/export `.mdc` / rule-style Cursor memory files
- `git_history` — import recent Git commit history as candidate runtime memories

Adapter guarantees:
- foreign artifacts are normalized into runtime records instead of being stored as one raw blob
- imported records carry opaque runtime provenance plus source tags like `adapter:*`, `client:*`, and `source_ref:*`
- dry-run import previews show `create / merge / conflict` before any write happens
- one write-once-read-everywhere loop is now covered in tests: Cursor rules → memoryOSS runtime → Claude project artifact

Reference endpoints:
- `POST /v1/adapters/import`
- `GET /v1/adapters/export?kind=claude_project`

Reference commands:

```bash
memoryoss adapter import --kind cursor_rules .cursor/rules/review.mdc --namespace test --dry-run
memoryoss adapter export --kind claude_project --namespace test -o claude-project.md
memoryoss adapter import --kind git_history . --namespace test --dry-run
```

### Ambient Connector Mesh

memoryOSS now exposes an opt-in connector mesh so ambient signals can enter the same candidate and review path as extracted memories.

Supported connector kinds today:
- `editor`
- `terminal`
- `browser`
- `docs`
- `ticket`
- `calendar`
- `pull_request`
- `incident`

Connector defaults are intentionally conservative:
- disabled by default
- sensitive fragments are redacted by default
- raw excerpts are not captured unless explicitly allowed
- every candidate carries uniform provenance tags like `connector:*`, `client:ambient_mesh`, and `source_ref:*`

Reference endpoints:
- `GET /v1/connectors`
- `POST /v1/connectors/ingest`

Reference commands:

```bash
memoryoss connector list
memoryoss connector ingest --kind terminal --namespace test --summary "Terminal note: use cargo fmt before release commits." --evidence "export API_KEY=sk-live-secret" --source-ref "terminal://release/42" --dry-run
```

### Sharing (cross-namespace collaboration)

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/v1/admin/sharing/create` | POST | Create shared namespace |
| `/v1/admin/sharing/list` | GET | List shared namespaces |
| `/v1/admin/sharing/{name}` | DELETE | Delete shared namespace |
| `/v1/admin/sharing/{name}/grants/add` | POST | Add sharing grant |
| `/v1/admin/sharing/{name}/grants/list` | GET | List sharing grants |
| `/v1/admin/sharing/{name}/grants/{grant_id}` | DELETE | Remove sharing grant |
| `/v1/sharing/accessible` | GET | List accessible shared namespaces |

### GDPR Compliance

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/v1/export` | GET | Data export (all memories) |
| `/v1/history/{id}` | GET | Inspect lineage, review chain, contradictions, and state transitions |
| `/v1/history/{id}/bundle` | GET | Export a deterministic time-machine replay bundle |
| `/v1/history/replay` | POST | Replay a history bundle into an empty target namespace |
| `/v1/adapters/export` | GET | Export runtime memories into a foreign client artifact |
| `/v1/adapters/import` | POST | Dry-run or apply a normalized foreign client artifact |
| `/v1/connectors` | GET | List supported ambient connector kinds plus privacy defaults |
| `/v1/connectors/ingest` | POST | Preview or store an opt-in ambient connector signal as a candidate memory |
| `/v1/bundles/export` | GET | Export a versioned memory bundle envelope around passport or history artifacts |
| `/v1/bundles/preview` | POST | Preview bundle metadata, URI, and sampled contents without importing |
| `/v1/bundles/validate` | POST | Validate bundle envelope integrity, nested artifact integrity, and current trust state |
| `/v1/bundles/diff` | POST | Diff two bundle envelopes without importing either one |
| `/v1/passport/export` | GET | Selective portable memory passport bundle export |
| `/v1/passport/import` | POST | Dry-run or apply a portable memory passport bundle |
| `/v1/runtime/contract` | GET | Versioned portable memory runtime contract |
| `/v1/memories` | GET | Data access (list memories) |
| `/v1/forget/certified` | DELETE | Certified deletion with audit trail |

## MCP Server

For Claude Desktop, Claude Code, or Codex MCP support:

```json
{
  "mcpServers": {
    "memory": {
      "command": "memoryoss",
      "args": ["-c", "memoryoss.toml", "mcp-server"]
    }
  }
}
```

Provides 4 tools: `store`, `recall`, `update`, `forget`. In the default setup MCP runs alongside the gateway. It is not the transport failover path; it is the explicit memory-tool path.

## Anthropic Local MCP Readiness

memoryOSS uses the same local stdio MCP path Anthropic documents for Claude Desktop extensions and local MCP directory submissions. The repo now maps the submission-critical pieces explicitly instead of implying they are already bundled:

| Requirement | memoryOSS mapping | Status |
|-------------|-------------------|--------|
| Local MCP server | `memoryoss mcp-server` over stdio via [server.json](server.json) and [src/mcp.rs](src/mcp.rs) | Ready |
| Public privacy policy | https://memoryoss.com/datenschutz.html | Ready |
| Support channel | `hello@memoryoss.com` and GitHub issues | Ready |
| Minimum three usable examples | See examples below | Ready |
| Tool titles + safety hints | Canonical mapping in [src/mcp.rs](src/mcp.rs) | Mapped |
| Release MCP metadata bundle | Generated `memoryoss-mcp-*.json` artifacts plus `server.json` | Shipped |

Current packaging gaps are explicit:

- `rmcp 0.1.5` does not yet serialize MCP spec-era `title`, `readOnlyHint`, and `destructiveHint` fields on the live `tools/list` response, so memoryOSS is not claiming directory-ready wire compatibility yet.
- A portable `.mcpb` artifact is still follow-up packaging work; the release pipeline now ships canonical JSON metadata artifacts (`memoryoss-mcp-server.json`, `memoryoss-mcp-manifest.json`, `memoryoss-mcp-claude-desktop.json`, `memoryoss-mcp-tools.json`, `memoryoss-mcp-package.json`) beside the binaries.

### Neutral Runtime Governance

memoryOSS now treats the runtime contract, bundle format, MCP packaging, and signer catalogs as a neutral compatibility surface instead of a repo-local install trick.

The public policy is:
- runtime contract and bundle changes publish fixture-backed deprecation notice before removal
- compatibility stays inside the published `N/N-1/N-2` window for import, replay, and reader paths
- third-party implementations can target the published conformance fixtures and canonical MCP metadata bundle without private coordination
- signer discovery rides on portable trust catalogs plus local pins, not on hidden vendor-owned trust roots

The machine-readable summary of that policy ships in [server.json](server.json) under `_meta.io.github.memoryOSScom/anthropic-local-mcp.governance`.

### Current install path

For Claude Desktop, Claude Code, or Codex today, install memoryOSS locally and register the stdio server. The release artifacts now ship the generated install metadata directly, so the JSON below is derived from the published package files rather than maintained by hand:

```json
{
  "mcpServers": {
    "memoryoss": {
      "command": "memoryoss",
      "args": ["-c", "/absolute/path/to/memoryoss.toml", "mcp-server"]
    }
  }
}
```

If you used the setup wizard, it writes the equivalent registration automatically.

### Marketplace tool annotation map

Anthropic requires a clear title and safety annotation per tool. memoryOSS currently maps them as follows in [src/mcp.rs](src/mcp.rs):

| Tool | Title | Safety annotation | Why |
|------|-------|-------------------|-----|
| `memoryoss_recall` | `Recall Relevant Memories` | `readOnlyHint: true` | Reads stored memory only |
| `memoryoss_store` | `Store New Memory` | `destructiveHint: true` | Persists new user/project data |
| `memoryoss_update` | `Update Existing Memory` | `destructiveHint: true` | Mutates existing stored data |
| `memoryoss_forget` | `Delete Stored Memory` | `destructiveHint: true` | Deletes stored data |

### Submission examples

These are the three practical examples prepared for a future Claude Desktop / local MCP submission:

1. Project continuity: “Before we touch deployment docs, recall anything we already decided about staging-first rollouts for this repo.”
2. Preference capture: “Remember that I only want concise summaries and never raw memory dumps unless I ask.”
3. Memory hygiene: “Find the outdated memory that says staging is optional and delete it if it is still stored.”

### Manifest / MCPB template

The release pipeline now generates an Anthropic/local-MCP manifest artifact with this shape:

```json
{
  "manifest_version": "0.3",
  "name": "memoryoss",
  "display_name": "memoryOSS",
  "version": "0.2.0",
  "description": "Persistent memory for AI agents with local MCP tools.",
  "author": {
    "name": "memoryOSS Contributors"
  },
  "homepage": "https://memoryoss.com",
  "documentation": "https://github.com/memoryOSScom/memoryOSS#anthropic-local-mcp-readiness",
  "support": "https://github.com/memoryOSScom/memoryOSS/issues",
  "privacy_policies": [
    "https://memoryoss.com/datenschutz.html"
  ],
  "server": {
    "type": "binary",
    "entry_point": "memoryoss",
    "mcp_config": {
      "command": "memoryoss",
      "args": ["-c", "${user_config.config_path}", "mcp-server"]
    }
  },
  "compatibility": {
    "platforms": ["darwin", "linux"]
  },
  "user_config": {
    "config_path": {
      "type": "string",
      "title": "memoryOSS config path",
      "description": "Absolute path to your memoryoss.toml file.",
      "required": true
    }
  }
}
```

This JSON is now shipped as `memoryoss-mcp-manifest.json`. A portable `.mcpb` container is still separate follow-up work.

## CLI Commands

| Command | Description |
|---------|-------------|
| `memoryoss setup` | Interactive setup wizard |
| `memoryoss serve` | Start the configured server mode (monolith or hybrid gateway) |
| `memoryoss dev` | Start without TLS (development) |
| `memoryoss mcp-server` | Start as MCP server (stdio, embedded) |
| `memoryoss status` | Show namespace health, lifecycle counts, worker state, and index health |
| `memoryoss doctor` | Diagnose config, auth, database, index, and Claude/Codex integration drift (non-zero on error) |
| `memoryoss recent` | Show recent injections, extractions, feedbacks, and consolidations |
| `memoryoss hud --namespace test --limit 5` | Terminal HUD for quick search/why/recent/review/import/export loops |
| `memoryoss bundle export --kind passport --namespace test --scope project -o project.membundle.json` | Export a portable memory bundle envelope and sign it with the local runtime identity |
| `memoryoss bundle preview project.membundle.json` | Preview bundle metadata, URI, and sampled contents without import |
| `memoryoss bundle validate project.membundle.json` | Validate envelope, nested artifact integrity, and trust state when config is available |
| `memoryoss bundle diff old.membundle.json new.membundle.json` | Diff two bundle envelopes offline |
| `memoryoss reader open project.membundle.json` | Open a bundle or raw published artifact in the offline universal reader, with trust verification when config is present |
| `memoryoss reader diff old.membundle.json new.membundle.json --format html` | Diff two offline artifacts in text, JSON, or HTML without a running runtime |
| `memoryoss review queue --namespace test` | List the current review inbox without raw UUIDs |
| `memoryoss review confirm --namespace test --item 1` | Confirm a queue item by inbox position |
| `memoryoss review reject --namespace test --item 2` | Reject a queue item by inbox position |
| `memoryoss review supersede --namespace test --item 1 --with-item 2` | Supersede one queue item with another by inbox position |
| `memoryoss passport export --namespace test --scope project -o passport.json` | Export a selective portable memory passport bundle |
| `memoryoss passport import passport.json --namespace test --dry-run` | Preview merge/conflict results before applying a bundle |
| `memoryoss adapter import --kind cursor_rules .cursor/rules/review.mdc --namespace test --dry-run` | Normalize a Cursor rule file into runtime records with preview |
| `memoryoss adapter export --kind claude_project --namespace test -o claude-project.md` | Export the current runtime state as a Claude Project artifact |
| `memoryoss adapter import --kind git_history . --namespace test --dry-run` | Preview recent Git history as candidate runtime memories |
| `memoryoss connector list` | Show supported ambient connector kinds and privacy defaults |
| `memoryoss connector ingest --kind docs --namespace test --summary "Release checklist lives in docs/releases/README.md." --dry-run` | Preview one ambient connector candidate before storing it |
| `memoryoss history show <id> --namespace test` | Show lineage, transitions, and review chain for one memory |
| `memoryoss history export <id> --namespace test -o history.json` | Export a deterministic history replay bundle |
| `memoryoss history replay history.json --namespace test --dry-run` | Preview a safe replay into an empty target namespace |
| `memoryoss history branch <id> --namespace test --target-namespace branch --dry-run` | Preview a branch-from-here into a new empty namespace |
| `memoryoss conformance normalize --kind passport --input passport.json --output normalized.json` | Reference reader/writer for published runtime fixtures |
| `memoryoss inspect <id>` | Inspect a memory |
| `memoryoss backup -o backup.tar.zst` | Backup all data |
| `memoryoss restore <path>` | Restore from backup |
| `memoryoss decay` | Run memory decay (age-based cleanup) |
| `memoryoss migrate` | Run schema migrations |
| `memoryoss migrate-embeddings` | Re-embed all memories with a new model |

## Architecture

- **Storage:** redb (embedded, crash-safe, single-file) — source of truth
- **Vector Index:** usearch (dimension follows the configured runtime embedding model)
- **Full-Text Search:** tantivy (BM25 + structured metadata fields)
- **Recall:** 4-channel retrieval (vector 0.30 + BM25 0.30 + exact match 0.25 + recency 0.15) with IDF identifier boosting, precision gate, MMR diversity, and trust weighting
- **Extraction:** Async LLM-based fact extraction with quarantine (confidence scoring)
- **Indexer:** Async outbox-based pipeline with crash recovery across all namespaces
- **Group Committer:** Batches concurrent writes into single redb transactions
- **Trust Scoring:** 4-signal Bayesian (recency decay, source reputation, embedding coherence, access frequency) — persisted to redb
- **Encryption:** AES-256-GCM per-namespace (supported: local key provider and Vault Transit; AWS KMS fails closed and is not yet a supported provider surface)
- **Security:** Constant-time key comparison, NFKC injection filtering, secret redaction (API keys, tokens, passwords), rate limiting, body size limits, path traversal protection

## Security

- All proxy endpoints require authentication
- Extracted memories start at confidence 0.2 (quarantine) — only memories with confidence ≥0.3 and passing trust scoring are injected
- Memory content is filtered against prompt injection patterns (NFKC-normalized)
- Secrets (API keys, tokens, passwords) are redacted before sending to extraction LLM
- API keys are compared in constant time (SHA-256 hash comparison)
- Request bodies capped at 2MB, responses at 10MB
- Rate limiting on all endpoints including passthrough

## Compatible With

Claude Code · OpenAI SDK · Codex CLI · Cursor · Aider · Continue · LangChain · Any OpenAI-compatible client

## License

AGPL-3.0 — free to use, modify, and self-host. If you offer it as a network service (SaaS), you must publish your source code. Commercial licenses available for SaaS providers who prefer not to open-source their modifications.