Agent memory that forgets and distorts on purpose SelMem, an open-source Rust project by jbsalles, introduces selective reconstructive memory for large language models, enabling two instances to diverge by forgetting, gilding, and anchoring a particular past. The system, which runs with zero Cargo crates on Rust 1.75 and uses SQLite or flat files for persistence, aims for non-average, path-dependent continuation rather than maximizing coverage. The project includes a whitepaper and parameters document, and supports LLM backends such as OpenAI's gpt-4o-mini and local Ollama models. Selective reconstructive memory for an LLM entity. An LLM maps context to the next token. A stack of unmodified facts maximises coverage, not deviation: more evidence, same average path. SelMem sculpts a particular past — forgotten, gilded, anchored — so two instances can diverge. The aim is a non-average, path-dependent continuation, not a taller log. Selection, reconstruction, sleep, identity. Manifest: WHITEPAPER.md /jbsalles/Selmem/blob/main/WHITEPAPER.md Knobs: PARAMETERS.md /jbsalles/Selmem/blob/main/PARAMETERS.md — exploratory, not fitted. Zero crates. Rust 1.75. SQLite via system libsqlite3 . src/ core/ model, profile, store encode/ intake, scoring, embed, affect, identity recall/ retrieve, narrator, http dream/ night, drift, singularite persist/ file, sqlite net/ api, httpx, ui engine.rs the loop bin/ selmemd, selmem-chat experience → interpret → identity paint → gate ↓ ↑ lived book + sealed archive | ↓ | remember / speak meaning can move ↓ sleep weather · rewrite · merge · extinguish motif → belief → trait → who am i ↓ next experience is already colored The model never sees the archive. Only gist, core, schema, affect, fidelity, mood, living axioms. Claire and Silas are not characters. They are two sensitivities tender / austere on the same corpus. After nights they are not the same past. Zero Cargo crates. Persistence is a vault, not the memory: the organ lives in RAM MemoryStore ; on save it is dumped, on open it is reloaded. The model never talks to the vault. Two backends, same Snapshot profile , mood , store : | Path | Backend | |---|---| | .db / .sqlite / .sqlite3 | system libsqlite3 prepared statements, BEGIN IMMEDIATE | | anything else | flat SELMEM1 file | IDs are {prefix} {pid} {n} . The counter is raised on load for both backends. Dropped events leave no archive. Orphans are pruned on sleep and SQLite load. Link is dynamic. If ld cannot find -lsqlite3 no -dev package : mkdir -p /tmp/selmem-libs ln -sfn /usr/lib/x86 64-linux-gnu/libsqlite3.so.0 /tmp/selmem-libs/libsqlite3.so export RUSTFLAGS="-L /tmp/selmem-libs" ./run.sh does that when needed, then execs cargo . ./run.sh test ./run.sh run --release --example compare ./run.sh run --release --example llm night ./run.sh run --release --bin selmemd -- --help Rust only. No Python suite. | What | Where | |---|---| | Narrative scenes edit these | tests/cases/ .json | | JSON runner | tests/scenes.rs | | Physiology — decay, anchors, SQLite, Ebbinghaus | tests/engine.rs | ./run.sh test ./run.sh test --test scenes ./run.sh run --release --bin selmemd -- \ --bind 0.0.0.0:7420 \ --path claire.db \ --name Claire \ --profile tender \ --token secret \ --llm https://api.openai.com/v1/chat/completions \ --model gpt-4o-mini \ --api-key "$SELMEM API KEY" UI: http://IP:7420/ — paste the token at the top, talk. Local Ollama: --llm http://127.0.0.1:11434/v1/chat/completions --model llama3 Behind nginx: location / { proxy pass http://127.0.0.1:7420; proxy read timeout 90s; } export SELMEM LLM=https://api.openai.com/v1/chat/completions export SELMEM MODEL=gpt-4o-mini export SELMEM API KEY=sk-... export SELMEM EMBED=https://api.openai.com/v1/embeddings export SELMEM TOKEN=secret No endpoint: RuleNarrator + hashed vectors. The organ still runs. One thread per connection. /health and / do not take the memory lock. /turn is serialized on the organ one writer . Auth is Authorization: Bearer only — not ?token= . | Method | Route | Role | |---|---|---| | GET | /health | liveness no token, no lock | | GET | /who | living axioms trait belief motif | | GET | /lineage?schema= | history of a belief | | GET | /mood | mood | | GET | /audit?id= | sealed verbatim human debug | | POST | /live | encode | | POST | /remember | reconstruct | | POST | /speak | embodied reply | | POST | /turn | live + reply | | POST | /sleep | consolidate | | POST | /save | flush | - Two books: lived narrative / archive. The model never reads the second. - Two channels: self is sculpted, world is not. - Forgetting by default. Encoding threshold. - Unlabelled events get lexical affect FR+EN , then identity, then optional LLM interpret on the live sentence. - Living axioms color the next encoding before the gate. - Cherished memories embellish. Recalled disgust amplifies. Neglected disgust extinguishes. - Recall can shift meaning valence under current mood , not only wording. - Nearby episodes fuse into myth. Heavy anchors do not merge. - Axioms climb: 2 traces → motif, 3+ → belief, aligned beliefs → trait. Lineage stays. - Two profiles on the same corpus diverge. Fingerprint uses founders, traits, contradictions. - Proxy for originality: reconstruction sticks less than the unmodified log; clones are not interchangeable; world facts survive originality is path dependent not a taller log . - Persistence: .db SQLite or .selmem flat file . js let mut mem = SelectiveMemory::open "claire.db", EntityProfile::tender "Claire" ?; mem.live with input ; let recalled = mem.remember "that evening" ; let = mem.speak "do you remember?" ; mem.sleep ; mem.who am i ; mem.lineage "loyalty" ; singularity distance &fingerprint &a , &fingerprint &b ; Not RAG. Not a vector database. Not a personality in a system prompt. Not a neocortex and not a brain. An executive–autobiographical loop around a next-token transducer. No local neural encoder ships in-tree: pass --embed if you have one.