@hilbras/remembra 3.2.0 → 3.3.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/docs/clients.md CHANGED
@@ -92,6 +92,8 @@ REMEMBRA_API_KEY="your-secret" remembra --http
92
92
  | `REMEMBRA_ARCHIVE_TTL_DAYS` | `365` | Archived memory → deleted |
93
93
  | `REMEMBRA_HOST` | *(see security.md)* | HTTP bind address (loopback without key) |
94
94
  | `REMEMBRA_MAX_BODY` | `10485760` | Max HTTP request body bytes |
95
+ | `REMEMBRA_LOCK_TIMEOUT_MS` | `5000` | Max wait for the cross-process storage lock |
96
+ | `REMEMBRA_LOCK_STALE_MS` | `10000` | Age after which a lock with a dead/unknown pid is stolen |
95
97
  | `REMEMBRA_DEBUG` | *(unset)* | `1` logs the storage root path at startup (off by default: log hygiene) |
96
98
 
97
99
  LLM/embedding key setup: see **[providers.md](providers.md)**.
package/docs/security.md CHANGED
@@ -52,6 +52,9 @@ Retrieved memories should be treated as **data with provenance**, not commands
52
52
  | **Body size limit** | 10 MiB default (`REMEMBRA_MAX_BODY`), `413` on excess — pre-checks `Content-Length` and enforces while streaming |
53
53
  | **Digest validation** | `DigestInput` Zod schema on both MCP and HTTP paths |
54
54
  | **Atomic writes** | temp file + `rename()` (POSIX-atomic) — no half-written memories after a crash |
55
+ | **Advisory locking** | `<root>/.remembra.lock` (`O_EXCL`) + in-process FIFO — cross-process writes serialize; stale locks (dead pid / older than `REMEMBRA_LOCK_STALE_MS`) are stolen; waiters fail with typed `LOCK_TIMEOUT` (HTTP 423) |
56
+ | **Crash recovery** | one-time pass on first access: removes orphaned `*.tmp`, reconciles ids left in both active+archived trees by an interrupted archive/revive |
57
+ | **Structured errors** | every actionable failure has a stable code (`INVALID_INPUT`, `LOCK_TIMEOUT`, `LLM_ERROR`, …) mapped to HTTP statuses / MCP `[CODE]` prefixes |
55
58
  | **ID collisions** | 12-hex IDs (2⁴⁸) + existence check on store |
56
59
  | **Content-Length** | Set on every response |
57
60
 
@@ -83,7 +86,9 @@ remembra --http
83
86
  - **No encryption at rest** — files are plaintext markdown (by design: you can
84
87
  read and edit them). Use filesystem-level encryption if needed.
85
88
  - **No PII redaction** — what you store is what's written to disk.
86
- - **No write locking / journal** — single-writer assumption; concurrent writers
87
- from multiple machines are unsupported (atomic writes + the digest lock
88
- protect against crashes and same-process races, not cross-machine
89
- interleaving). `remembra export` for backups across machines.
89
+ - **Single-writer assumption per store, now cross-process safe** mutations
90
+ take an advisory lockfile (`O_EXCL`, stale-steal, typed `LOCK_TIMEOUT`), so
91
+ an MCP server, the `remembra maintain` CLI, and a session digest can run
92
+ against one store concurrently on one machine. Network filesystems with
93
+ unreliable `O_EXCL` semantics are untested; `remembra export` for backups
94
+ across machines.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hilbras/remembra",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "External memory for AI assistants — remember facts, decisions, roles and history across sessions. MCP server for OpenCode, Claude Code, Cline, Kimi Code and more.",
5
5
  "type": "module",
6
6
  "bin": {