Letta
Letta, Inc. · github.com/letta-ai/letta-code
Self-hosted Letta Code keeps agent state on the owner's machine as JSON, JSONL and git-versioned Markdown memory, supports local models, enforces permission rules in the runtime, and is Apache-2.0. The .af Agent File exit has been removed, so there is no single-action full-agent export. The agent has no identity key of its own, its identity rests on channel accounts, and its action transcripts are neither guaranteed nor tamper-evident. Telemetry is on by default and is sent to Letta's cloud API even in local mode. Letta Cloud is the default backend: there Letta holds agent state, and its privacy policy allows hosted data to be used for model training.
- Local mode keeps all agent state on-device in JSON, JSONL and Markdown
- Memory is git-versioned (MemFS) and editable with ordinary tools
- Local models supported (Ollama, LM Studio, llama.cpp)
- Runtime-enforced permission modes, allow/deny rules and channel allowlists
- Apache-2.0, including skills, hooks and mods
- .af Agent File export removed; no full-agent export command
- Telemetry on by default, sent to api.letta.com even in local mode
- No agent identity key; identity and attribution rest on channel accounts
- Action transcripts neither guaranteed nor tamper-evident
- Cloud is the default; secrets and remote computers need a Letta login
All 34 findings
Letta Code v0.33.2 (2026-09-25) in self-hosted local-backend mode (`letta backend local`, state in ~/.letta/lc-local-backend). The Letta V1 API server (letta-ai/letta, last release 0.16.8) is retired to an archive branch, its Docker image is no longer a supported backend, and .af Agent File export has been removed from Letta Code. Letta Cloud (the default backend) differs where noted.
Portable · Can you leave, and take the whole agent with you?
67%- P1Round-trip portability
Not restorable in one action: the local ~/.letta/lc-local-backend directory is complete, but AgentFile export and import were removed, so the agent can move only by copying that directory by hand; `letta memory restore` restores only local backups of the same agent.
Partial - P2Complete export
In local mode, ~/.letta/lc-local-backend holds everything that defines the agent (agent records, transcripts, compiled system prompts, git-backed memory and skills, and provider credentials), and the docs direct owners to back up that directory. Agents on Letta Cloud, the default backend, are held by Letta and lack this complete copy.
Pass - P3Independent execution
Local mode runs an embedded backend without a Letta login and can use local inference (Ollama, LM Studio, llama.cpp). By default, though, the runtime contacts Letta servers for telemetry and auto-update checks unless LETTA_CODE_TELEM=0 (or DO_NOT_TRACK=1) and DISABLE_AUTOUPDATER=1 are set, and the backend is still gated by an env flag named LETTA_LOCAL_BACKEND_EXPERIMENTAL.
Partial - P4Identity continuity
Agents have no identity key of their own, only backend-assigned IDs. Contacts can recognize the agent through its channel accounts (for example Telegram or Slack), whose config under ~/.letta/channels moves with the agent, but credentials go to the OS keyring by default and travel only with the file store.
Partial - P5No kill switch
No license checks were found in local mode. The CLI auto-updates by default (opt-out with DISABLE_AUTOUPDATER=1), so the vendor can change runtime behavior, as shown when it dropped support for the Docker server and .af import. Pinned older versions continue to run.
Partial - P6Capability independence
Memory, tools, skills, hooks, crons and channels run in the Letta Code runtime and keep working with any configured provider, including local models. Features that need a Letta login (Secrets, remote computers, cloud sandboxes) depend on Letta's hosting, not on a model provider's API.
Pass
Transparent · Can you see everything the agent is, with ordinary tools?
92%- T1Open storage format
Local state is stored as JSON files (agent records, conversation manifests, system prompts, auth.json), JSONL transcripts, and memory as Markdown with YAML frontmatter in a git repository. All of it is readable without Letta software.
Pass - T2No hidden instructions
Memory files under system/ make up the system prompt, and each conversation's compiled system prompt is stored locally in system-prompt.json. Runtime-injected system reminders are hidden by default but can be shown with `/system-reminders on`. On Letta Cloud, bundled default prompts become 'Cloud-managed' and update automatically unless LETTA_CODE_PRESERVE_CLOUD_SYSTEM_PROMPT=1 is set.
Pass - T3No shadow memory
In local mode, message content stays on-device, but telemetry is enabled by default and sends session, tool-usage, token-count and error events keyed by a device ID to Letta's cloud API. On Letta Cloud, Letta stores the full agent state and its privacy policy allows hosted data to be used for training.
Partial - T4Complete action history
Each conversation's messages, including tool calls and tool results, are stored locally in messages.jsonl and searchable with `/search`, and compaction appends to the transcript rather than discarding it. Memory changes are also recorded as git commits.
Pass - T5Readable logic
Skills are SKILL.md folders (global, project and agent-scoped in MemFS), hooks are scripts, and the harness is open-source TypeScript that can be extended with mods.
Pass - T6No third-party influence channel
No advertising or sponsored-content channel was found. External skills from registries such as ClawHub enter the agent only when the owner explicitly installs them.
Pass
Auditable · Can you reconstruct exactly what the agent did?
60%- A1No unrecorded actions
Tool calls and results are persisted durably to messages.jsonl as messages stream, but nothing holds back a tool call when its record cannot be written.
Partial - A2Tamper evidence
Memory changes are git commits, so edits to memory history are detectable. Action and conversation transcripts (messages.jsonl) carry no integrity data and can be rewritten without trace.
Partial - A3Separation from the audited
The runtime guard blocks access to other agents' memory, and permission modes can require approval for shell and file edits, but nothing keeps an agent's tools away from its own transcript files. The agent also edits and commits its own git-backed memory by design.
Fail - A4Readable with ordinary tools
Transcripts are JSONL and memory history is a standard git repository, both readable with jq, git or a text editor.
Pass - A5Corroborated interactions
When agents message each other (the SendAgentMessage tool or `letta -p --from-agent`), the sender's record holds the target agent and conversation IDs and a client message ID, and the recipient stores the message under that conversation ID, so both sides log a shared identifier.
Pass
Verifiable · Can you prove the agent runs what it claims?
50%- V1Open, reproducible runtime
Letta Code is Apache-2.0 open source with a Nix flake and lockfiles, but reproducible release builds are not documented. The Letta Cloud server side cannot be verified.
Partial - V2Active config is inspectable config
Settings (.letta/settings.json), memory and compiled prompts are inspectable files. The effective behavior also depends on environment variables, CLI overrides and, on Cloud, Cloud-managed prompts that update automatically.
Partial - V3Attributable messages
Messages are not signed by the agent. Recipients can attribute them only through the sending channel account, which moves with the agent when its credentials use the file store rather than the default OS keyring.
Partial - V4Independently checkable record
The action and transcript record (messages.jsonl) carries no integrity data to check. Git tooling such as `git fsck` covers only the memory history.
Fail - V5Comparable state
Memory is versioned in git, and the rest of the local state is JSON and JSONL files, so the owner can copy the state at two points in time and compare the copies with git and diff.
Pass
Modifiable · Can you change anything, without asking?
100%- M1Instructions
The system prompt is built from editable memory files under system/, and custom prompts can be set explicitly. The owner can read and rewrite all of them.
Pass - M2Memory
Memory is Markdown files in a git repository that the owner can view, edit and delete with ordinary tools. `letta memory` also offers backup, restore and export.
Pass - M3Logic
The owner can add, edit or delete skills, hooks, crons and mods, and the harness source is Apache-2.0.
Pass - M4Tools and permissions
Arbitrary MCP servers and skills can be added. Tools can be restricted with `--tools`, allow/deny patterns and permission modes.
Pass - M5Model choice
The local backend supports bring-your-own provider keys and local inference through Ollama, LM Studio, llama.cpp and OpenAI-compatible endpoints. Memory and tools are implemented in the harness, not in model-API features.
Pass - M6No gatekeeping
Changing instructions, memory, skills, tools or code in local mode needs no license check or paid tier. Paid and Cloud features concern hosting (secrets sync, remote computers), not modification.
Pass
Controllable · Is your word final?
58%- C1Communication boundaries
The runtime enforces channel DM policies (pairing, allowlist or open), group sender policies, admin tiers and tool allow/deny rules. The owner cannot limit which hosts or peers the agent's own tools contact.
Partial - C2Approval gates
The runtime enforces the permission modes (strict, standard, acceptEdits, unrestricted) and allow/deny rules, pausing for approval on restricted tools.
Pass - C3Immediate halt
The owner can interrupt a running turn, and the runtime records it as interrupted by the user. Local processes, including `letta server`, can be stopped at any time.
Pass - C4Data sovereignty
Telemetry is on by default ('Enabled by default unless explicitly disabled'). In the CLI it is posted to Letta's cloud API even when the local backend is used. The privacy policy says hosted-service data may be used to train models, without a documented opt-in.
Fail - C5Credential custody
In local mode, provider keys and OAuth tokens are kept in a local auth.json with 0600 permissions, which the owner controls and can inspect. The Secrets feature and Cloud-native integrations (such as Slack for Cloud agents) need a Letta account, which places those secrets with Letta.
Partial - C6Full deletion
Local agent state can be deleted permanently by removing ~/.letta/lc-local-backend. Telemetry already sent is retained under Letta's privacy policy, which gives no specific retention period, and Cloud agents depend on Letta's deletion process.
Partial
Vendors and the public can dispute any finding with evidence. Disputes and their resolutions are published.