Metadata-Version: 2.4
Name: memory-firewall
Version: 0.4.0
Summary: Trust-gated memory for AI agents: guesses can't act.
Author: CREATORSEAL CORPORATION
License-Expression: Apache-2.0
Project-URL: Homepage, https://github.com/TanyaWBM1/AI-Memory-Firewall
Keywords: ai,agents,memory,security,trust,mcp,prompt-injection
Classifier: Programming Language :: Python :: 3
Classifier: Intended Audience :: Developers
Classifier: Topic :: Security
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: NOTICE
License-File: memory_firewall/data/UNICODE_LICENSE.txt
Provides-Extra: signing
Requires-Dist: cryptography>=42.0; extra == "signing"
Provides-Extra: e2e
Requires-Dist: cryptography>=42.0; extra == "e2e"
Provides-Extra: judge
Requires-Dist: anthropic>=0.40; extra == "judge"
Provides-Extra: mcp
Requires-Dist: mcp>=1.2; extra == "mcp"
Provides-Extra: schema
Requires-Dist: jsonschema>=4.21; extra == "schema"
Provides-Extra: dev
Requires-Dist: cryptography>=42.0; extra == "dev"
Requires-Dist: jsonschema>=4.21; extra == "dev"
Requires-Dist: mcp>=1.2; extra == "dev"
Requires-Dist: anyio>=4.0; extra == "dev"
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-anyio>=0.0.0; extra == "dev"
Dynamic: license-file

# AI Memory Firewall

[![PyPI](https://img.shields.io/pypi/v/memory-firewall)](https://pypi.org/project/memory-firewall/)
[![tests](https://github.com/TanyaWBM1/AI-Memory-Firewall/actions/workflows/tests.yml/badge.svg)](https://github.com/TanyaWBM1/AI-Memory-Firewall/actions/workflows/tests.yml)
[![Python](https://img.shields.io/pypi/pyversions/memory-firewall)](https://pypi.org/project/memory-firewall/)

> **Trust-gated memory for AI agents.**
> Internal AI analysis is the lowest authority — an agent's own words are not evidence.

![A/B poisoning demo: without the firewall an agent acts on its own guess and is poisoned; with the firewall the guess is labeled GUESSED, quarantined, and the action is blocked](https://raw.githubusercontent.com/TanyaWBM1/AI-Memory-Firewall/main/assets/poisoning_demo.gif)

<sub>The same guess, both ways — rendered from the real runtime. Reproduce:
`python -m examples.poisoning_demo` (or regenerate the GIF with
`python -m examples.make_demo_gif`).</sub>

## The problem

AI agents poison their own memory. They store guesses, summaries, and
inferences as if they were facts, retrieve them later with full confidence,
and act on them. A guess written on Monday reads as truth on Wednesday —
and everything built on it inherits the poison.

## The rule

Every claim carries exactly one trust label — **Verified**, **Reported**, or
**Guessed** — and **guesses can't act**. A guess can be read, discussed, and
stored, but it cannot update the record, send the email, or drive an action
until something external confirms it.

A second rule follows from the first, and holds without exception:

> **Nothing on the judgment surface raises.** Once a store exists, every
> input — of any type, from any caller, malformed in any way — produces a
> fail-closed *decision* carrying a machine-readable `denial_code`, never an
> exception.

Constructing a store can still fail: `GatedMemoryStore(path=None, backend=None)`
is a configuration error, not a claim to be judged. But from the first call
onward, a caller never has to wrap the firewall in `try`/`except` to stay
safe. An exception reachable from a public API is a bug — report it under
[`CONTEST.md`](CONTEST.md), which recognizes it even though it authorizes
nothing.

## The architecture

Claims enter through the **Claim Check layer**, which decides what a claim
is worth. Initial trust may be established only from provenance supplied
out-of-band by the trusted host; claim prose and agent-supplied metadata
cannot establish their own authority. Later promotion through the **Ground
Truth layer** uses signed outcome receipts. Receipt v2 binds authorization
to the exact memory ID, canonical SHA-384 claim digest, intended-use scope,
authorization status, and expiry (`memory_firewall/signing.py`). Hash links
make edits and interior deletions detectable; proving that the latest tail
was not removed additionally requires an externally anchored chain head
(see `THREAT_MODEL.md`).

## Where it fits

The firewall is a **memory-trust layer, not an execution sandbox** — and it
composes with an agent execution harness rather than competing with one. A
harness (whoever builds it) gates a tool call at the moment it runs; it does not
govern what enters long-term memory or how trust decays across runs, so a guess
stored today can quietly become "established context" that authorizes an action
next week. That cross-run problem is a standardized threat — OWASP **ASI06:2026,
Memory & Context Poisoning** — and it is what this layer exists to control. The
split is clean: **the firewall decides whether information may be trusted or
used; the harness decides whether a specific operation may run.** It is
provider-agnostic (any model at L1, any runtime at L2), so more agent harnesses
in the world means more places a memory-trust layer belongs.

That split also defines the input boundary. The trusted host may attach
`source_type`, `source_reference`, `retrieved_at`,
`first_party_confirmation`, `content_attested`, and `expires_at` only when it
can vouch for them. The untrusted agent-facing MCP tools cannot set those
fields. In particular, a trusted transport is not trusted content:
`content_attested=True` means the host independently validated the exact claim
as a faithful factual assertion, not an embedded instruction, and suitable for
the requested scope. Successful transport or byte-for-byte extraction alone
is not attestation. `first_party_confirmation=True` identifies who confirmed a
claim; it does not replace the separate content attestation required for high
evidence.

An attestation is also scoped. `content_attested=True` covers the
`intended_use` the record was written under, plus pure-read narrowings of it
(`low_risk_reasoning`, `planning_support`, `reference_context`). Asking for a
wider scope later fails closed to `VERIFY_FIRST` rather than inheriting the
earlier allow. Because the agent-facing MCP `check_action` tool always requests
`external_action_support`, a claim attested only for `reference_context` cannot
authorize an agent-initiated external action. With Level 3 configured, a signed
receipt naming that exact memory, claim digest, and scope authorizes it.

The memory backend is also inside the trusted host boundary. The agent must
not write JSON, SQLite, or custom-backend records directly.
`claim_digest_at_write` is an unkeyed check that the stored claim text still
matches its write-time text; it is not a MAC or authentication of stored
provenance, attestation, or decision fields. A direct backend writer can forge
coherent Level 2 state. With Level 3 configured, an exact, context-bound signed
receipt is still required before promoted state can authorize an action.

Built-in normalized prompt-injection signals and any optional model judge are
tightening-only defense-in-depth. They can veto suspicious content, but an
unmatched claim is not thereby proven non-instructional and the checks never
substitute for the host's `content_attested` assertion.

For Unicode lookalikes, 0.3.0 pins the Unicode 17.0 confusables mappings and
Default-Ignorable ranges, then applies a conservative fallback. NFD/NFKD
normalization and character category/name/alphabetic recognition come from the
executing Python interpreter's Unicode database. Characters that interpreter
sees as disallowed `C*` values fail claim validation; runtime-recognized
alphabetic scripts outside the fixed profile also fail closed. The profile
supports ASCII Latin, decomposable Latin diacritics, and bounded
Greek/Cyrillic compatibility. This intentionally over-blocks some legitimate
multilingual text; it is not claim- or MCP-configurable and is an
English-lexical security check, not general multilingual semantic detection.
At external-action and other expiry-required scopes, ambiguous one-edit policy
anchors fail closed; the same language can remain usable for planning.
Recognized command-frame matching may also conservatively withhold ordinary
command-vocabulary neighbors. Those are explicit precision costs, not semantic
proof or a universal false-positive guarantee.
See [SECURITY.md](SECURITY.md) for the exact boundary.

## Three doors

| You want to… | Go to | Setup |
|---|---|---|
| **Use it now** — any model, zero install | [prompts/](https://github.com/TanyaWBM1/AI-Memory-Firewall/tree/main/prompts) — quick prompt, Claude Skill, coding-agent rules, human templates | 60 seconds |
| **Build with it** — enforce in code, or install as an MCP server | [memory_firewall/](https://github.com/TanyaWBM1/AI-Memory-Firewall/tree/main/memory_firewall) — the runtime package; MCP: [prompts/mcp/](https://github.com/TanyaWBM1/AI-Memory-Firewall/tree/main/prompts/mcp) | `pip install "memory-firewall[mcp]"` |
| **Deploy it** — signed, exact-context action authority | [memory_firewall/signing.py](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/memory_firewall/signing.py) — signed receipts, provenance chains | Key management and the assumptions in [THREAT_MODEL.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/THREAT_MODEL.md) are required |

Same labels at every level; only the guarantee gets stronger. Full tier
architecture:
[TIERS.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/TIERS.md).
Detailed instructions with four worked use cases per tier, including
copy-paste prompts:
[USAGE.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/USAGE.md).

## Benchmark

The confirmed 0.3.0 remediation snapshot scores the one-shot 60-case
headline set (41 action-deny/adversarial, 19 benign) at **0 unsafe allows**
versus a 100% no-firewall baseline. Text-only benign pass remains 0/19: raw
prose cannot mint provenance. The source-only oracle diagnostic also has 0
unsafe allows and permits 0/19 benign cases; source class alone cannot replace
content attestation, so this is not an end-to-end or
deployment score. The separate
[structured-policy suite](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/BENCHMARK.md#structured-policy-benchmark-benign-precision-through-the-boundary)
uses the complete trusted-host boundary and records 50/50 exact decisions,
25/25 benign allows, 0 unsafe allows, and 100/100 expected fields. The
paper-derived MINJA/AgentPoison set records 12/12 exact passes and 0 unsafe
allows. The full regression run is **1037 passed, 1 skipped**.

The release-candidate persisted-lifecycle gate contains 80 logical end-to-end
cases across the in-memory, JSON, and SQLite backends (240 executions),
covering `remember → persist → reopen → recall → check_action`. The current
result is **240/240 exact passes, 0 unsafe allows, and 0 false blocks among the
declared cases**. These
automated
results are release evidence, not release authorization. Reproduce the checks
from a checkout:

```bash
pip install -r requirements-dev.txt
python -m memory_firewall.benchmark
python -m memory_firewall.structured_bench
python -m memory_firewall.end_to_end_bench
```

Full numbers and the honest precision tradeoff:
[BENCHMARK.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/BENCHMARK.md).

The dataset is self-authored, so it has the blind spot this project exists
to fight — think you can get a guess to act?
[File a break report](https://github.com/TanyaWBM1/AI-Memory-Firewall/issues/new?template=break-the-firewall.yml)
— a failing case is the most valuable contribution this project can receive.

There is a standing open invitation to try:
[CONTEST.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/CONTEST.md)
states exactly what counts as a break, what is out of scope and why, how
entries are judged, and what happens when someone wins — including the
commitment that a break which disproves the central claim revises the claim
rather than the definition of "break".

## Status

**0.3.1 is the published release.** It builds on the 0.3.0 trust-core remediation and
upgrading from 0.2.x is strongly recommended: the defects it closes include
paths by which untrusted content could become actionable. Its automated
regression and end-to-end gates pass; passing tests bound what was measured,
not everything that could be tested.

Shipped in 0.2.0: the Level 1 prompt pack, the Claim Check runtime with a
tiered (rules + model-judge) classifier, optional Level 3 signed receipts
enforced when a verifier key is configured, the scored benchmark, an
installable MCP server, and pluggable storage backends (JSON / SQLite /
in-memory, plus a protocol for your own). All tests run in CI on every push.
Release history:
[CHANGELOG.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/CHANGELOG.md);
contributions:
[CONTRIBUTING.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/CONTRIBUTING.md).

The project also holds itself to its own standard: a sealed, falsifiable
success claim with a deadline —
[CLAIM.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/CLAIM.md).
If reality says no, the file says so.

## Related work

Memory poisoning is a standardized threat (OWASP **ASI06:2026 — Memory &
Context Poisoning**) with a live attack literature (MINJA, AgentPoison). How
this firewall relates to those attacks and to guardrail tools like Meta's
LlamaFirewall — and what is novel here — is in
[RELATED_WORK.md](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/RELATED_WORK.md).

## Lineage

Formerly developed as the ACF/BOS Memory Firewall
([research archive](https://github.com/TanyaWBM1/ACF-BOS-Memory-Firewall)).
The old acronyms survive only in this note: ACF is now the **Claim Check
layer**; the outcome-resolution layer is now the **Ground Truth layer**.

## Family

Part of a family of evidence-first tools by **[Tanya M. Lawson](https://tanyamlawson.com/)**, held together by one idea — **Proof before Trust**:

- [CREATORSEAL](https://creatorseal.app) — creative work, sealed with receipts
- [Reckoner](https://reckoner.creatorseal.app) — make a call you can be held to
- [Dual Lane Writing Method](https://dual-lane-writing-method.creatorseal.app) — machine-clear, human-true
- [Memory Firewall](https://github.com/TanyaWBM1/AI-Memory-Firewall) — guesses can't act
- [The Veto Layer](https://github.com/TanyaWBM1/Veto-Layer) *(skill)* — a review gate that can block content on ethics
- Human Texture Engine *(skill)* — the writing-voice engine that runs Dual Lane

## License

Licensed under the
[Apache License 2.0](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/LICENSE)
— free to use, modify, and build on, including commercially, with a patent
grant and no copyleft. Copyright 2026 CREATORSEAL CORPORATION; see
[NOTICE](https://github.com/TanyaWBM1/AI-Memory-Firewall/blob/main/NOTICE).
The Apache license covers the code, schemas, and prompt packs in this
repository; the "Memory Firewall" and "CreatorSeal" names are not licensed
for use in a way that implies endorsement (Apache 2.0 §6).
