Letta memory-mutation adapter for Phionyx runtime evidence — every memory write, clear, forget, or consolidation emits a signed, hash-chained envelope with before/after diff.
Project description
phionyx-letta
Memory-mutation audit chain for Letta agents — every memory write, append, clear, delete, forget, or consolidation emits a signed, hash-chained envelope with a structured before/after diff. AGPL-3.0 · Python 3.10+ · alpha (v0.7.0 W3)
Phionyx-letta is the v0.7.0 W3 (F15) implementation of the memory diff audit layer described in the Phionyx runtime-evidence design. It treats Letta core-memory blocks the same way the rest of the Phionyx stack treats agent turns: every state change is captured in a hash-chained, tamper-evident envelope that a third party can replay without operator-side insider knowledge.
What it gives you
For each memory mutation:
- A structured diff summary — before/after content hashes, byte sizes, character-level added / removed / unchanged counts.
- A typed mutation kind — one of
write,append,clear,delete,forget,consolidate. - An optional forgetting reason — for
clear,delete,forgetmutations (e.g.explicit_user_request,retention_policy,consolidation_promotion). - An optional consolidation audit subblock — for
consolidatemutations, cross-references canonical pipeline block #43 (memory_consolidation) with the participating memory ids and algorithm identifier. - An optional cross-runtime parent reference — when the mutation
was caused by an upstream adapter envelope (langchain, openai_agents,
RGE v0.2), this envelope can point back at it via
subject.metadata.memory_audit.parent_envelope_ref.
All envelopes share Phionyx's canonical JSON + SHA-256 hash chain +
opt-in Ed25519 signing surface (HMAC for demo). The verifier semantics
match phionyx-mcp-server.audit_chain.verify_chain byte-for-byte.
Sixty-second usage
from phionyx_letta import (
MemoryMutationContext,
HmacSigner,
FilesystemEnvelopeStore,
build_memory_envelope,
compute_memory_diff,
GENESIS_HASH,
)
signer = HmacSigner(secret="REPLACE_IN_PRODUCTION_WITH_ED25519")
store = FilesystemEnvelopeStore(root="/var/lib/phionyx/letta_audit")
# Compute the diff between before and after content
diff = compute_memory_diff(
before="User prefers concise answers.",
after="User prefers concise answers. They speak Turkish.",
)
ctx = MemoryMutationContext(
trace_id="letta-trace-alex-001",
turn_index=42,
producer="letta.agent_alex",
block_id="block-9e3a-...",
block_label="core_memory.persona",
mutation_kind="append",
diff=diff,
)
envelope = build_memory_envelope(
ctx=ctx,
previous_hash=store.head("letta-trace-alex-001"),
package_version="0.1.0a1",
signer=signer,
)
store.append("letta-trace-alex-001", envelope)
Schema
phionyx.memory_mutation_envelope.v1 — one envelope per memory
mutation event. See examples/envelopes/v0_7_schema_portfolio.md in
the parent repo for the cross-runtime composition surface
(subject.metadata.memory_audit).
Top-level structure:
{
"schema": "phionyx.memory_mutation_envelope.v1",
"subject": {
"runtime": "phionyx-letta",
"version": "0.1.0a1",
"producer": "<letta agent identifier>",
"turn_index": <int>,
"event_type": "memory_<kind>",
"timestamp_utc": "<ISO-8601 UTC>",
"metadata": {
"memory_audit": { // W3.3 cross-runtime composition (optional)
"parent_envelope_ref": "envelope://sha256:...",
"schema": "phionyx.memory_mutation_envelope.v1",
"kind": "<mutation kind>"
},
"<producer-supplied keys>": "..."
}
},
"mutation": {
"block_id": "<stable Letta block id>",
"block_label": "<e.g. core_memory.persona>",
"mutation_kind": "<write|append|clear|delete|forget|consolidate>",
"diff": {
"before_hash": "sha256:<hex>",
"after_hash": "sha256:<hex>",
"before_size_bytes": <int>,
"after_size_bytes": <int>,
"added_chars": <int>,
"removed_chars": <int>,
"unchanged_chars": <int>,
"diff_text": null | "<unified diff>"
},
"forgetting_reason": null | "<reason>"
},
"memory_consolidation_audit": null | { // W3.2 — only for `consolidate` mutations
"block_ref": "pipeline_block_43:memory_consolidation",
"from_episodic": ["<mem-id>", ...],
"to_semantic": ["<sem-id>", ...],
"consolidation_method": "<algorithm id>",
"decay_applied": null | true | false
},
"integrity": {
"previous": "sha256:<hex>",
"current": "sha256:<hex>",
"signature": "<algo>:<hex>",
"canonical_json": true
}
}
Cross-runtime composition (W3.3)
When a Letta memory mutation is triggered by another adapter (a
LangGraph node, an OpenAI Agents tool call, an RGE v0.2 turn), the
upstream envelope's id can be passed as memory_audit_parent_ref:
envelope = build_memory_envelope(
ctx=ctx,
previous_hash=store.head(trace_id),
package_version="0.1.0a1",
signer=signer,
memory_audit_parent_ref="envelope://sha256:<upstream RGE envelope current>",
)
The resulting envelope carries subject.metadata.memory_audit so a
reviewer can walk from any upstream envelope to the memory mutation it
caused without needing matching schema ids. The reference is one-way
(memory envelope → upstream envelope) because the upstream envelope is
sealed at sign time and cannot be amended retroactively.
The reverse direction is recommended on upstream emitters that know
they cause memory mutations: emit your envelope first, then build the
memory mutation envelope with memory_audit_parent_ref set to your own
integrity.current. The two envelopes form a verifiable pair.
What this package does NOT do
- It does not instrument Letta automatically. You compute the diff
yourself (with
compute_memory_diffor your own logic) and callbuild_memory_envelopeat the right point in your code. A future release MAY ship a Letta runtime hook that intercepts memory writes; v0.1.0a1 ships the audit primitives only. - It does not store memory contents by default.
diff.diff_textis None unless the caller explicitly requests it (include_diff_text=True). Size deltas + content hashes are always recorded; raw text is opt-in. - It does not interpret mutation semantics. A
forgetenvelope withforgetting_reason="retention_policy"is just two strings to this package — the operator decides what they mean. - It does not certify compliance. Like the rest of the Phionyx stack, this is evidence-grade audit, not a regulatory attestation.
Status (v0.7.0 W3)
- W3.1 — per-mutation envelope. Shipped. 20/20 tests pass.
- W3.2 — forgetting + consolidation audit subblock. Shipped.
- W3.3 — cross-runtime composition. Shipped via
subject.metadata.memory_audit.
v0.7.0 W4 (HearthOS reference deployment + release) follows.
License
AGPL-3.0-or-later. See LICENSE in the parent repo.
Citing
If you use phionyx-letta in academic or policy work, cite the parent project: Abak, A. T. (2026). Phionyx Research — Runtime Evidence Layer for Agentic AI. ORCID 0009-0002-3718-4010.
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 phionyx_letta-0.1.0a1.tar.gz.
File metadata
- Download URL: phionyx_letta-0.1.0a1.tar.gz
- Upload date:
- Size: 27.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
415bf109e71a7552134cb5a1b09207217489c2dd1dd8f20cb47666f0b7aada10
|
|
| MD5 |
98375bf220c4c476098914ce705e4db4
|
|
| BLAKE2b-256 |
4fee771d5c9e72c47cf81942a0223a2cf7cbdd6f3956bffaa5f3b2e06dfddab6
|
Provenance
The following attestation bundles were made for phionyx_letta-0.1.0a1.tar.gz:
Publisher:
release.yml on halvrenofviryel/phionyx-letta
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
phionyx_letta-0.1.0a1.tar.gz -
Subject digest:
415bf109e71a7552134cb5a1b09207217489c2dd1dd8f20cb47666f0b7aada10 - Sigstore transparency entry: 1642263089
- Sigstore integration time:
-
Permalink:
halvrenofviryel/phionyx-letta@088c85508bbb97ebddf61f60fa44221207526d3c -
Branch / Tag:
refs/tags/v0.1.0a1 - Owner: https://github.com/halvrenofviryel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@088c85508bbb97ebddf61f60fa44221207526d3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file phionyx_letta-0.1.0a1-py3-none-any.whl.
File metadata
- Download URL: phionyx_letta-0.1.0a1-py3-none-any.whl
- Upload date:
- Size: 23.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
caf18f702d40d71645a843293bb15924d77feb59a0555a53ff0a3777849ff1d8
|
|
| MD5 |
9accd3bb25e964dbd6fa3e3ddf15facc
|
|
| BLAKE2b-256 |
4faf2aecb684a68425016d5ddd3429d0208485220386cb94be2ea30602e2fb5d
|
Provenance
The following attestation bundles were made for phionyx_letta-0.1.0a1-py3-none-any.whl:
Publisher:
release.yml on halvrenofviryel/phionyx-letta
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
phionyx_letta-0.1.0a1-py3-none-any.whl -
Subject digest:
caf18f702d40d71645a843293bb15924d77feb59a0555a53ff0a3777849ff1d8 - Sigstore transparency entry: 1642263256
- Sigstore integration time:
-
Permalink:
halvrenofviryel/phionyx-letta@088c85508bbb97ebddf61f60fa44221207526d3c -
Branch / Tag:
refs/tags/v0.1.0a1 - Owner: https://github.com/halvrenofviryel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@088c85508bbb97ebddf61f60fa44221207526d3c -
Trigger Event:
push
-
Statement type: