ragleap-memory 0.1.0 + ragleap-security 0.1.0 — One SQLite File, Real Erasure, Scope Enforced in SQL
I just released two new libraries: ragleap-security 0.1.0 (101 tests) and ragleap-memory 0.1.0 (89 tests). Both v0.1.0, both first releases, both with mutation testing.
TL;DR: Tenant isolation enforced inside SQL, not in app code. And erase() actually removes bytes.
ragleap-security — stdlib only
from ragleap_security import Scope, AuditLog, SecretStr, check_size
scope = Scope.parse("org:gov-dept/region:south/branch:chennai")
print(scope.covers(Scope.parse("org:gov-dept/region:south"))) # True
child = scope.narrow("facility:factory1")
org:gov-dept/region:south/branch:chennai/facility:factory1
log = AuditLog("audit.jsonl")
log.append({"op": "add", "scope": str(scope)})
log.verify() # hash-chain check
secret = SecretStr("sk-...")
print(secret) # SecretStr(***) — never leaks in repr
check_size(data, max_bytes=1_000_000)
5 modules, no deps. You can audit it in an afternoon.
Why hash-chained JSONL? Tamper-evident. If someone edits line 10, verify() fails because hash chain breaks. Not tamper-proof (can't prevent edit), but can detect.
Verified: 101 tests, 30/30 mutations killed, reproducible build matches PyPI.
ragleap-memory — the interesting part
Problem with most memory libs: They do SELECT * FROM memories WHERE tenant_id = X in app code. But they still return different errors for "not found" vs "not allowed" — leaking existence.
Our approach: scope filtering inside SQL, same response for missing vs outside-scope.
from ragleap_memory import SQLiteStore
from ragleap_security import Scope
store = SQLiteStore("memory.db")
scope_a = Scope.parse("org:hospital/branch:chennai")
scope_b = Scope.parse("org:hospital/branch:mumbai")
store.add(text="ICU bed count changed to 12", type="fact", trust="trusted", scope=scope_a)
Same scope → found
print(store.search("ICU", scope=scope_a)) # [fact]
Different scope → looks like missing, not "access denied"
print(store.search("ICU", scope=scope_b)) # [] — same as missing
Typed entries: episode (raw events), fact (distilled), summary (compressed). All default to untrusted — you must explicitly trust.
Operations that matter for enterprise:
id1 = store.add(text="Old threshold", type="fact", scope=scope_a)
id2 = store.supersede(id1, text="New threshold is 80", scope=scope_a) # history kept
store.forget(id2, scope=scope_a) # soft delete
store.erase(id2, scope=scope_a) # hard delete + vacuum
After erase, byte-level check:
grep -a "New threshold" memory.db → not found
grep -a "New threshold" memory.db-journal → not found
We actually tested byte-level search after erase on two SQLite builds.
Other ops: export (dump for migration), sweep_expired (TTL), compact (vacuum), optional audit log without entry text (privacy).
FTS5 search: Full-text search, not vector. Why? Deterministic, no embedding cost, works offline. For Hindi, Tamil, Arabic, Chinese with spaces — whole-word tested. Without spaces (Chinese/Japanese) — not split yet, known limit.
Mutation testing
We run scripts/mutation_check.py — it mutates code (change == to !=, remove WHERE clause, etc.) and checks tests kill it.
security: 30/30 killed
memory: 27/27 killed
If a mutation survives, your tests are weak. We fixed until all killed.
Reproducible builds
Build locally before tagging, compute SHA-256, build on CI after tagging, compare. If different, fail. For these releases, local SHA matches PyPI SHA.
ragleap_memory-0.1.0-py3-none-any.whl sha256 c60a1e4f91e323c04ba04d7628abb7028039206d2330921a7ca00ae053a3533e
ragleap_security-0.1.0-py3-none-any.whl sha256 e3f31d3703d552cde53080e6d6c56cef733954d61deeaba586bdce48db53075d
Not verified — honest
No Windows / NFS / multi-process writes / power-loss tests
No retrieval benchmark (precision/recall unmeasured)
Tenant isolation holds inside lib, but nothing else uses it yet
No independent security review — see docs/threat-model.md
Install
pip install ragleap-security==0.1.0
pip install ragleap-memory==0.1.0
Repo: github.com/ragleap/ragleap-core
Release PRs: #907 (security), #922/#924 (memory)
Workflows: 40016023080, 40060689857
This is foundation for human digital twins and org-wide memory with real isolation. Next: integrate Scope into agents.
If you care about multi-tenant AI, try breaking the scope isolation — I'd love a failing test.
Top comments (0)