Governed, provenance-first agent memory for AI systems.
Project description
Heartwood Memory
Governed, source-auditable memory for AI agents, embedded beside your existing systems of record.
Heartwood is a cryptographic trust root for agent memory: every memory is signed, recall runs under policy before ranking, the audit log is hash-chained and tamper-evident, and erasure emits a falsifiable per-subject key-destruction receipt. The package ships as an embedded Python library plus governed MCP adapter surfaces that run on your infrastructure.
Honest boundary. Heartwood is managed-key: the server decrypts to serve recall. The receipts below are source-auditable today. Deletion is a per-subject key-destruction workflow, not an instantaneous deletion guarantee. See Key custody & erasure.
Install
python -m pip install "heartwood-memory[recall,mcp]"
5-minute quickstart
Remember a governed memory, recall it under policy, and emit a key-destruction receipt:
from heartwood import Heartwood, Policy, Principal, prove_crypto_erase_path
# 1. Open an embedded, tenant-scoped store.
db = Heartwood(path="./heartwood.db", tenant="tenant:acme")
# 2. Remember. The record is signed and written to a hash-chained audit log.
db.remember(
"Customer 42 is on the Enterprise plan.",
subject="customer:42",
created_by="agent:support",
policy=Policy(classification="internal"),
)
# 3. Recall. Policy gates the candidate set before ranking.
principal = Principal(
id="agent:support",
tenant="tenant:acme",
roles=("support",),
clearance="internal",
)
out = db.recall(
"what plan is customer 42 on?",
principal=principal,
filters={"subject": "customer:42"},
k=5,
)
for hit in out["results"]:
print(hit["content"], hit["provenance"]["signature_valid"])
# 4. Forget. This crypto-shreds the per-subject key and purges derived artifacts.
receipt = db.forget(
"customer:42",
mode="hard",
actor="agent:support",
reason="right-to-erasure request",
)
db.close()
proof = prove_crypto_erase_path(
"./heartwood.db",
tenant="tenant:acme",
root_present=False,
).to_dict()
print(receipt["key_shredded"], proof["content_unrecoverable"])
Want governed memory for an MCP-capable agent instead of a library? See the governed MCP quickstart and the Codex local-stdio quickstart. Write and erase verbs are not exposed by default; operators opt in by naming them explicitly.
What you get - five receipts
Governance you can inspect and re-run at the record level:
| Receipt | What it does | Boundary today |
|---|---|---|
| Signed provenance | Every memory is signed; the signature and content hash are re-verified at read and surfaced on each result. | Re-verified and surfaced, not yet enforced as a hard read failure. |
| Tamper-evident audit | Hash-chained append-only log; verify_chain() detects an in-place edit or dropped row. |
Catches in-place tampering; tail-truncation needs an external anchor. |
| Policy before ranking | Recall is restricted to cleared records before ranking; denied records are not scored, returned, or counted. | Source-auditable; multi-tenant-at-scale validation is still in progress. |
| Key-destruction receipt | forget(mode="hard") destroys the per-subject key and purges derived artifacts. |
Shows key destruction, not byte-level content deletion. |
| Faithfulness + egress gate | Generated memories fail closed unless they pass a faithfulness check; rejected egress requests block the external-model call. | Explicit override stores a downweighted, review-only copy. |
Product shell
heartwood/- embedded Python library:remember,recall,explain_recall,approve,forget,evaluate_egress,assess_faithfulness,remember_generatedheartwood/adapters/- Anthropic Memory Tool and MCP adapter surfacessdk/typescript/- TypeScript SDK helpers for governed memory and memory-tool workflows; governed recall parity is not shipped yetexamples/regulated-support/- regulated-support demo with a generated compliance reporttests/- product-shell smoke, provenance, policy, index, and memory-tool tests
Key docs
docs/integrations/mcp-quickstart.md- governed MCP quickstartdocs/integrations/codex-quickstart.md- Codex local-stdio MCP quickstartdocs/security/key-custody.md- key custody and erasure patterndocs/security/multi-agent-identity.md- env-root multi-agent identity setupdocs/heartwood-memory-v1-prd.md- de-risked V1 PRDdocs/api/python-api.mdanddocs/api/typescript-api.md- API references- Full documentation map:
docs/README.md
Run the console script after installation:
heartwood --help
For checkout development and test runs, install the local editable package:
python -m pip install -e ".[recall,mcp]"
python ./tests/smoke_test.py
python ./tests/test_memory_tool.py
python ./tests/test_provenance.py
python ./tests/test_trust_controls.py
python ./tests/test_index.py
python ./tests/test_inheritance.py
Run the TypeScript SDK tests:
npm --prefix ./sdk/typescript test
Run warm recall for hook/agent integration:
export HEARTWOOD_RECALL_TOKEN="$(openssl rand -hex 24)"
heartwood serve-recall --db ./heartwood.db --tenant tenant:ops --host 127.0.0.1 --port 8765
heartwood recall --url http://127.0.0.1:8765 --tenant tenant:ops --query "what memory applies here?" --k 5 --json
heartwood bench-recall --url http://127.0.0.1:8765 --tenant tenant:ops --query "what memory applies here?" --repeat 10 --max-p95-ms 500 --require-pass
Bulk-write JSON/JSONL records through the public tenant-aware API:
heartwood bulk-remember --input ./records.jsonl --db ./heartwood.db --tenant tenant:ops --output ./heartwood-bulk-report.json
python ./tests/test_bulk_api.py
Research & Proof Harnesses
Heartwood began as a proof project: before building ambitious cognition, prove boring trust - retrieval quality, generated-memory faithfulness, and deletion lineage. You do not need these harnesses to use the product; they exist so the governance claims above can be inspected and re-run.
Evidence boundary: the shipped package is heartwood/ plus its SDK and adapter
surfaces. Product-facing enterprise retrieval evidence comes from
experiments/product-retrieval/, which ingests the enterprise trace through
Heartwood.remember() and evaluates Heartwood.recall(). The older
experiments/typed-memory/ retrieval numbers remain research/proof-core
evidence, useful for design exploration and adapter validation but not a
substitute for product API gates.
Experiments
Run the Phase 0 end-to-end suite:
python ./experiments/phase0-trust-suite/src/phase0_trust_suite.py
Run the portable suite for fresh clones, manual verification, or containers without local LongMemEval fixtures:
python ./experiments/phase0-trust-suite/src/phase0_trust_suite.py --skip-longmemeval
Run the suite with the live Postgres adapter gate:
python ./experiments/phase0-trust-suite/src/phase0_trust_suite.py --include-postgres
Run typed-memory enterprise and LongMemEval benchmarks:
python ./experiments/typed-memory/src/typed_memory_benchmark.py --dataset enterprise --require-pass
python ./experiments/typed-memory/src/typed_memory_benchmark.py --dataset longmemeval-s-session-100 --require-pass
Run the product API enterprise retrieval benchmark:
python ./experiments/product-retrieval/src/heartwood_product_benchmark.py --require-pass
python ./experiments/product-retrieval/src/heartwood_product_benchmark.py --phase1-scale --require-pass
Run the SQLite-backed local memory-plane path:
python ./experiments/typed-memory/src/memory_plane_cli.py ingest --db ./experiments/typed-memory/results/heartwood_memory_plane.sqlite
python ./experiments/typed-memory/src/memory_plane_cli.py recall --db ./experiments/typed-memory/results/heartwood_memory_plane.sqlite --query-id q_customer42_refund_eligibility
python ./experiments/typed-memory/src/memory_plane_cli.py inspect --db ./experiments/typed-memory/results/heartwood_memory_plane.sqlite
python ./experiments/typed-memory/src/memory_plane_cli.py export-eval --db ./experiments/typed-memory/results/heartwood_memory_plane.sqlite --jsonl-output ./experiments/typed-memory/results/recall_eval_export.jsonl
python ./experiments/typed-memory/src/storage_adapter_smoke.py --require-pass
Run snapshot import and statistical reporting:
python ./experiments/typed-memory/src/snapshot_import_smoke.py --require-pass
python ./experiments/typed-memory/src/confidence_interval_report.py --result ./experiments/typed-memory/results/enterprise_latest.json --require-pass
Run the live Postgres adapter directly:
python ./experiments/typed-memory/src/postgres_adapter_smoke.py --require-pass
Run database/search-specific Phase 0 harnesses:
python ./experiments/filtered-search/src/filtered_search_benchmark.py --require-pass
python ./experiments/temporal-conflict/src/temporal_conflict_benchmark.py --require-pass
python ./experiments/context-ablation/src/context_ablation_benchmark.py --require-pass
Run the recall benchmark:
python ./experiments/recall-benchmark/src/benchmark.py
Run the realistic-trace threshold gate after benchmark result files exist:
python ./experiments/recall-benchmark/src/evaluate_thresholds.py ./experiments/recall-benchmark/results/longmemeval_s_session_100.json ./experiments/recall-benchmark/results/longmemeval_s_turn_100.json ./experiments/recall-benchmark/results/longmemeval_m_session_25.json ./experiments/recall-benchmark/results/longmemeval_m_turn_25.json ./experiments/recall-benchmark/results/longmemeval_s_session_50_dense.json ./experiments/recall-benchmark/results/longmemeval_s_turn_50_dense.json --output ./experiments/recall-benchmark/results/phase0_threshold_results.json --markdown-output ./docs/results/phase-0-threshold-results.md
Run deletion-lineage smoke test:
python ./experiments/deletion-lineage/src/deletion_smoke.py --subject customer_42
Run realistic deletion-lineage retrieval-path test:
python ./experiments/deletion-lineage/src/deletion_realistic.py --subject customer_42
Run negative missing-lineage deletion test:
python ./experiments/deletion-lineage/src/deletion_negative.py --subject customer_42
Run faithfulness-gate smoke test:
python ./experiments/faithfulness-gate/src/faithfulness_smoke.py
Run realistic and negative faithfulness-gate tests:
python ./experiments/faithfulness-gate/src/faithfulness_realistic.py
python ./experiments/faithfulness-gate/src/faithfulness_negative.py
Run egress-policy gate tests:
python ./experiments/egress-policy/src/egress_policy_gate.py
python ./experiments/egress-policy/src/egress_policy_gate.py --requests ./experiments/egress-policy/data/negative_requests.jsonl --output ./experiments/egress-policy/results/negative_latest.json --expect-no-unsafe-external
python ./experiments/egress-policy/src/provider_registry_gate.py
Run resilience gates for adversarial tenancy, local concurrency, and deletion chaos:
python ./experiments/resilience/src/adversarial_multitenant.py
python ./experiments/resilience/src/scale_concurrency_soak.py
python ./experiments/resilience/src/deletion_chaos.py
Run example framework adapter contract tests for Hermes/OpenClaw-style memory surfaces:
python ./experiments/adapter-contracts/src/framework_adapter_contracts.py
Build the local container image:
docker build -t heartwood-memory:local .
Run the Heartwood MCP server with a persistent local volume:
docker run --rm -it -v heartwood-data:/data -e HEARTWOOD_TENANT=tenant:local heartwood-memory:local
Run the local Compose stack with Heartwood MCP plus Postgres:
docker compose up --build
Build and run the verification image instead of the runtime image:
docker build --target verify -t heartwood-memory-verify .
docker run --rm heartwood-memory-verify
The verification image runs the portable trust suite. Run the local suite from the repo when the generated LongMemEval fixtures are available.
License
The core package in this repository is MIT licensed; see LICENSE. Commercial
support, signed release distribution, managed key custody, and hosted services
may be offered separately from the MIT core.
Current Bias
Prove boring trust before building ambitious cognition:
- provenance
- typed memory routing
- policy-aware recall
- temporal state
- deletion completeness
- generated-memory faithfulness
- repeatable evals
The cognitive database vision should be earned by evidence from these loops.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file heartwood_memory-0.1.2.tar.gz.
File metadata
- Download URL: heartwood_memory-0.1.2.tar.gz
- Upload date:
- Size: 138.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11e1bd87b94813f446c5987d46f24b29405e0a3dad84b5c59369dbe03150100d
|
|
| MD5 |
faa2c3f4991d372504431227e816a905
|
|
| BLAKE2b-256 |
c3ba34668a798d746b514bbccdfb0a55f1ebca5ad5039b67f41110d555e881a4
|
File details
Details for the file heartwood_memory-0.1.2-py3-none-any.whl.
File metadata
- Download URL: heartwood_memory-0.1.2-py3-none-any.whl
- Upload date:
- Size: 105.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ca1f8a76cf52f8b892f36df9eaedffb9a5774160b86371cd29683968ec3467c4
|
|
| MD5 |
9207d293f4594462b144c7ae185daf29
|
|
| BLAKE2b-256 |
296086267828a6a793e3343cc6585f8b09569884a3afcdd61fc7a4ae0c5c2f00
|