Your AI agent remembers everything. Now it doesn't have to.
forgetted is a small Python library that gives AI agents selective memory governance: inside a context-managed window the agent keeps full read access but its writes to memory files, session logs, deliverables, and (optionally) a vector store silently vanish and are cleaned up on exit. One with block, and your agent keeps full context but persists nothing.
Traditional incognito is all-or-nothing: no past, no future, fully isolated. forgetted keeps full read continuity while making the write side non-persistent for the duration of a window.
Part of the Hermes Labs reliability stack.
from forgetted import ForgetSession
with ForgetSession("/path/to/workspace"):
agent.chat("this conversation never happened")
# β No trace in memory, logs, or vector DB. Agent resumes normally.AI agents write everything: memory files, session logs, vector embeddings, deliverables. Sometimes you need context without consequences:
- π¬ Sensitive conversations that shouldn't persist in agent memory
- π§ͺ Experiments you don't want polluting your agent's knowledge base
- π Client data discussed but not stored
- π€ Brainstorming that shouldn't bias future responses
forgetted is not a prompt. It's software that wraps the agent's persistence layer β writes silently vanish, reads still work, and the agent resumes normally after.
pip install forgettedfrom forgetted import ForgetSession
# Everything inside is forgetted β writes to memory/, logs, deliverables vanish
with ForgetSession("/path/to/agent/workspace"):
agent.chat("tell me about the secret project")from forgetted import ForgetSession
from forgetted.adapters.mem0 import Mem0Adapter
session = ForgetSession(
workspace="/path/to/workspace",
adapters=[Mem0Adapter(memory_instance, user_id="roli")],
)
session.start(checkpoint_summary="Discussing API design")
# ... conversation happens with full context, zero persistence ...
session.stop() # re-enables all layers, cleans upfrom forgetted import is_forget_trigger, ForgetSession
if is_forget_trigger(user_message): # "/forget", "off the record", etc.
with ForgetSession(workspace):
handle_conversation()| Layer | How | Status |
|---|---|---|
Memory files (memory/*.md) |
builtins.open patch |
β Blocked |
| Deliverables / audit logs | builtins.open patch |
β Blocked |
Session logs (*.jsonl) |
Blocked + deleted on exit | β Blocked |
| mem0 / semantic memory | Method patch on add/update |
β Blocked |
| Any custom persistence | Write your own adapter | π Extensible |
forgetted uses a layered defense:
-
FileWriteAdapter(always on) β patchesbuiltins.opento intercept writes to protected paths. Returns no-op file handles instead of raising β agent code doesn't crash, writes just vanish. -
Mem0Adapter(opt-in) β patchesmemory.add()andmemory.update()during the window. Post-window cleanup deletes any memories that leaked through. -
ForgetSessionorchestrates everything: checkpoint β disable adapters β run conversation β enable adapters β cleanup β delete session log.
Reads are never blocked. The agent has full context β it just can't write new context.
Any persistence layer can be controlled:
from forgetted.adapters.base import PersistenceAdapter
class RedisAdapter(PersistenceAdapter):
name = "redis"
def disable(self):
self._client.config_set("save", "")
self._active = True
def enable(self):
self._client.config_set("save", "3600 1")
self._active = False
def cleanup(self):
for key in self._window_keys:
self._client.delete(key)
@property
def is_active(self): return self._activeRegister it: ForgetSession(workspace, adapters=[RedisAdapter(client)])
Built-in detection for natural-language triggers:
| Trigger | Example |
|---|---|
/forgetted |
"/forgetted" |
/forget |
"/forget" |
forget this |
"hey, forget this conversation" |
off the record |
"let's go off the record" |
forgetted mode |
"enable forgetted mode" |
don't remember this |
"don't remember this" |
βββββββββββββββββββββββββββββββββββββββββββ
β ForgetSession β
β (orchestrator β context manager) β
βββββββββββββββββββββββββββββββββββββββββββ€
β ββββββββββββββββ ββββββββββββββββ β
β β FileWrite β β Mem0 β β
β β Adapter β β Adapter β ... β
β β (safety net) β β (opt-in) β β
β ββββββββββββββββ ββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββ€
β checkpoint β disable β conversation β
β β enable β cleanup β delete log β
βββββββββββββββββββββββββββββββββββββββββββ
This is not a UX toggle. It's a memory governance primitive.
Like git: you branch, but you never merge back. The conversation exists in context, and the writes it would normally make to the agent's persistent state are intercepted instead. After the window closes, a normal read of the agent's memory and logs shows no trace of it β within the scope described in Limitations.
"I want context⦠but I don't want consequences."
99 tests (97 pass, 2 xfail) including an adversarial suite:
- β
Write blocking via
builtins.open(modesw/a/x/wb/r+, symlinks resolved, binary) - β Trigger detection (no false positive on "I'm so forgetful today", etc.)
- β Adapter error isolation (one failing adapter doesn't break others)
- β Exception safety (cleanup runs even if the conversation crashes)
- β Idempotency (double-start, stop-before-start, double-stop all safe)
Known bypasses (writes that do not go through builtins.open, such as Path.write_text/write_bytes and os.open) are documented as xfail tests rather than hidden. See Limitations below.
What forgetted blocks: Writes that go through builtins.open to protected workspace paths (memory/, DELIVERABLES.md, *.jsonl), plus mem0 add/update when the Mem0Adapter is registered.
What forgetted does NOT block: LLM API provider logs, network telemetry, OS-level forensics, and writes that bypass builtins.open (see Limitations). It is a convenience layer for agent-controlled persistence, not a security or containment boundary.
What you can rely on, within that scope: writes routed through builtins.open to protected paths are intercepted and return no-op handles, so a normal read of the agent's memory and logs afterward does not surface what happened inside the window. This is enforcement by effect (no-op handles + post-window cleanup), not a prompt instruction.
forgetted is a software convenience layer, not a security boundary. Grounded in the code and the xfail test suite, it does not:
- Catch writes that bypass
builtins.open.Path.write_text,Path.write_bytes,os.open, C-extension writes, and subprocesses write directly and are not intercepted. These are documented as xfail tests. - Erase data written before the window opened. It governs writes during the window only; pre-existing memory is untouched.
- Block reads. By design β the agent keeps full read context.
- Intercept writes outside the declared workspace path.
- Block network calls, API calls, or external tool use.
- Support concurrent or nested forgetted sessions on the same workspace β overlapping windows can break the guard's restore chain (xfail tests).
- Defend against an adversary inspecting LLM-provider logs, network traffic, or raw disk forensics.
For the full machine-readable behavior contract, see INTENT.md.
If forgetted is useful to you, please star the repo β it helps others find it.
Apache-2.0 β Hermes Labs
Hermes Labs is an independent AI-reliability lab building open-source tools that catch silent failure modes in production AI. More at hermes-labs.ai.