Profile Memory Bank¶
User-scoped AI Sessions are not associated with any specific organisation, so they cannot use the org-scoped ai_memory Hive. To give Claude durable context across user sessions, each Session Profile carries a memory bank: a small set of markdown files mounted into the runner's workspace at /workspace/.memory/ whenever a session is launched from that profile.
The memory bank is the user-side analog of ai_memory, scoped per profile rather than per org. Use it for things like:
- preferences ("always run terraform plans against
stagingfirst"), - recurring projects (a running plan, status notes, decision logs),
- learned facts about your environment (host inventories, compliance constraints, runbook pointers).
Each profile gets its own bank, so you can keep an "investigations" profile, a "reporting" profile, and a "research" profile with independent memories.
How memories are mounted¶
When a session starts from a profile that has memories:
- The session manager loads the bank, decrypts it, and ships it inside the encrypted session config.
- The runner writes each memory to
/workspace/.memory/<path>before Claude starts. - The runner injects a
## Profile Memory Banksection into Claude's system prompt that lists the current entry paths and explains how persistence works. This tells the model the directory exists, what it holds, and that edits there carry over to later sessions. Without the section Claude has no reason to look in.memory/, because the Agent SDK has no built-in convention for it. - While the session runs, the runner watches
/workspace/.memory/. Whenever Claude writes, edits, or deletes a file there, the change is debounced and synced back to the bank. Anything the model learns is available in the next session that uses this profile.
The system-prompt section is only injected for user-based sessions (D&R / org-scoped sessions never carry a profile and never see the bank). For empty banks the section instructs Claude to create the first entry rather than listing entries.
The directory belongs entirely to the bank: do not store transient files in .memory/, they will be wiped on the next session start.
Layout and limits¶
Memory paths use the same shape as the ai_memory Hive:
- relative path, forward slashes only,
- characters limited to
A–Z,a–z,0–9,.,_,-,/, - no leading-dot segments (so
.swp/~/.#…editor temp files are easy to filter out), - no
..traversal, - maximum depth: 5 segments,
- maximum path length: 256 characters.
Per-profile caps:
| Limit | Value |
|---|---|
| Entries per profile | 100 |
| Bytes per entry | 64 KiB |
| Aggregate bytes per profile | 5 MiB |
Bank entries are stored encrypted at rest using your user-specific key, the same scheme that protects environment variables and MCP server credentials in your profiles.
Lifecycle¶
- The memory bank is decoupled from session lifecycle. Deleting a session has no effect on its profile's bank.
- The bank is not part of session suspend archives. When a session resumes, it remounts the current bank, so edits you make through the API while a session is dormant take effect on resume.
- Deleting a profile cascades the deletion to every entry in its bank.
Managing memories¶
REST API¶
Authenticate with your LimaCharlie JWT (Authorization: Bearer $LC_JWT).
List entries¶
Returns metadata only. Fetch bodies separately.
curl https://ai.limacharlie.io/v1/profiles/$PROFILE_ID/memories \
-H "Authorization: Bearer $LC_JWT"
{
"memories": [
{
"path": "preferences.md",
"size": 412,
"content_hash": "9b2f…",
"created_at": "2026-05-01T10:14:32Z",
"updated_at": "2026-05-04T08:02:11Z"
}
]
}
Read an entry¶
curl --get https://ai.limacharlie.io/v1/profiles/$PROFILE_ID/memories/content \
--data-urlencode "path=projects/acme.md" \
-H "Authorization: Bearer $LC_JWT"
Create or update an entry¶
The path goes in the URL query string and the body is JSON. The markdown content goes inside the content field.
curl -X PUT "https://ai.limacharlie.io/v1/profiles/$PROFILE_ID/memories/content?path=projects%2Facme.md" \
-H "Authorization: Bearer $LC_JWT" \
-H "Content-Type: application/json" \
-d '{"content": "## Acme Corp\n- single-tenant deployment\n- compliance: SOC2"}'
The response includes a created flag (true on first insert) and a changed flag (false when the supplied content matched the existing entry, in which case the call is a no-op).
Delete an entry¶
curl -X DELETE --get https://ai.limacharlie.io/v1/profiles/$PROFILE_ID/memories/content \
--data-urlencode "path=projects/old-deal.md" \
-H "Authorization: Bearer $LC_JWT"
From inside a session¶
Claude can simply write to /workspace/.memory/<path>.md (or read from it) the same way it would any other file. Edits are synced back to the bank automatically. The model does not need to call any API.
Profile memory vs. AI Memory hive¶
Both stores share a "filesystem-style entry within an owner record" model, but they sit at different scopes:
| Profile memory bank | AI Memory Hive | |
|---|---|---|
| Scope | One bank per profile (per-user) | One record per agent (per-org) |
| Auth | LC user JWT | LC org/user creds with ai_memory.{get,set,del} |
| Mounted into runner | Yes, at /workspace/.memory/ |
No, accessed via limacharlie ai-memory CLI |
| Best for | Per-user durable context for interactive sessions | Cross-session agent state for D&R-driven sessions |
If your session has both an LC org binding and a profile memory bank, you can use them together: the bank for personal preferences and project notes, the hive for org-scoped operational state.
Security¶
- The runner is treated as untrusted code. It cannot make privileged API calls to the session manager.
- Memory writes from inside the runner travel over the same authenticated WebSocket the runner uses to talk to the proxy. The proxy validates path/size limits at the trust boundary and forwards to the session manager, which authoritatively re-derives the (user, profile) target from the persisted session record. A compromised runner cannot redirect writes into another user's profile.
- Bodies are encrypted at rest with your user-specific key.