Skip to content

hermes-labs-ai/forgetted

Repository files navigation

πŸ«₯ forgetted

Your AI agent remembers everything. Now it doesn't have to.

PyPI Downloads Stars License Python CI


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.

Why?

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.

Install

pip install forgetted

Quick Start

Simple (file-level protection)

from 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")

With vector DB protection

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 up

Trigger detection (for chat agents)

from forgetted import is_forget_trigger, ForgetSession

if is_forget_trigger(user_message):  # "/forget", "off the record", etc.
    with ForgetSession(workspace):
        handle_conversation()

What Gets Blocked

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

How It Works

forgetted uses a layered defense:

  1. FileWriteAdapter (always on) β€” patches builtins.open to intercept writes to protected paths. Returns no-op file handles instead of raising β€” agent code doesn't crash, writes just vanish.

  2. Mem0Adapter (opt-in) β€” patches memory.add() and memory.update() during the window. Post-window cleanup deletes any memories that leaked through.

  3. ForgetSession orchestrates 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.

Write Your Own Adapter

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._active

Register it: ForgetSession(workspace, adapters=[RedisAdapter(client)])

Trigger Phrases

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"

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚           ForgetSession                  β”‚
β”‚  (orchestrator β€” context manager)        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”‚
β”‚  β”‚ FileWrite    β”‚  β”‚ Mem0         β”‚     β”‚
β”‚  β”‚ Adapter      β”‚  β”‚ Adapter      β”‚ ... β”‚
β”‚  β”‚ (safety net) β”‚  β”‚ (opt-in)     β”‚     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  checkpoint β†’ disable β†’ conversation    β”‚
β”‚  β†’ enable β†’ cleanup β†’ delete log        β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

What This Really Is

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."

Tested

99 tests (97 pass, 2 xfail) including an adversarial suite:

  • βœ… Write blocking via builtins.open (modes w/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.

Threat Model

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.

Limitations

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.

License

Apache-2.0 β€” Hermes Labs


About 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.

About

forgetted is a Python library for selective memory governance in AI agents: a context-managed window where 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. Mid-conversation incognito for agents, one with-block. By Hermes Labs.

Topics

Resources

License

Code of conduct

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors

Languages