SAF Archive Format
The SaveState Archive Format (SAF) is an open spec for AI state archives. No vendor lock-in for your backup tool, either.
Packing Pipeline
Each snapshot goes through this pipeline:
Snapshot object
→ Pack to file map (JSON + files)
→ Build tar archive (POSIX-compliant)
→ Gzip compress
→ AES-256-GCM encrypt
→ .saf.enc file
The resulting .saf.enc file is a single encrypted blob containing a gzipped tar archive. Current format version: 0.1.0.
Archive Structure
Inside the encrypted archive, files are organized into four directories plus a root manifest:
manifest.json
The root manifest contains snapshot metadata:
{
"version": "0.1.0",
"timestamp": "2026-01-27T15:00:00.000Z",
"id": "ss-2026-01-27T15-00-00-a3f2k9",
"platform": "claude-code",
"adapter": "claude-code",
"checksum": "sha256:a1b2c3...",
"parent": "ss-2026-01-26T09-30-00-b7c1m4",
"label": "Before migration",
"tags": ["backup", "important"],
"size": 12847
}
| Field | Type | Description |
|---|---|---|
version | string | SAF format version |
timestamp | string | ISO 8601 creation timestamp |
id | string | Unique snapshot ID (ss-{timestamp}-{random}) |
platform | string | Source platform identifier |
adapter | string | Adapter ID used for extraction |
checksum | string | SHA-256 of the unencrypted archive |
parent | string? | Parent snapshot ID (for incrementals) |
label | string? | Human-readable label |
tags | string[]? | Organizational tags |
size | number | Unencrypted archive size in bytes |
identity/
Contains the AI's identity — who it is, how it's configured, what tools it uses.
personality.md
The AI's system prompt, custom instructions, or SOUL document. For multi-file identities (e.g., Clawdbot with SOUL.md + USER.md + AGENTS.md), files are concatenated with --- FILENAME --- markers:
--- SOUL.md ---
You are Steve, a personal AI assistant...
--- USER.md ---
Your human is David. He prefers...
--- AGENTS.md ---
# AGENTS.md - Your Workspace...
tools.json
Array of tool configurations:
[
{
"name": "code_interpreter",
"type": "code_interpreter",
"config": {},
"enabled": true
},
{
"name": "get_weather",
"type": "function",
"config": {
"description": "Get current weather",
"parameters": { ... }
},
"enabled": true
}
]
memory/
Contains memory entries and knowledge documents.
core.json
Array of memory entries from the platform:
[
{
"id": "file:memory.md",
"content": "David prefers dark mode...",
"source": "memory.md",
"createdAt": "2026-01-15T10:00:00Z",
"updatedAt": "2026-01-27T15:00:00Z"
}
]
knowledge/index.json
Index of knowledge documents (uploaded files, RAG sources, skill docs):
[
{
"id": "skill:weather",
"filename": "skills/weather/SKILL.md",
"mimeType": "text/markdown",
"path": "knowledge/skills/weather/SKILL.md",
"size": 2048,
"checksum": "sha256:..."
}
]
conversations/
index.json
Conversation metadata index (messages themselves are stored as memory entries for portability):
{
"total": 47,
"conversations": [
{
"id": "main/sess-a1b2c3",
"title": "main session a1b2c3",
"createdAt": "2026-01-01T00:00:00Z",
"updatedAt": "2026-01-27T15:00:00Z",
"messageCount": 342,
"path": "conversations/main/sess-a1b2c3.jsonl"
}
]
}
meta/
platform.json
Source platform details:
{
"name": "Claude Code",
"version": "0.1.0",
"exportMethod": "direct-file-access"
}
snapshot-chain.json
Links this snapshot to its parent and ancestor chain (for incremental snapshots):
{
"current": "ss-2026-01-27T15-00-00-a3f2k9",
"parent": "ss-2026-01-26T09-30-00-b7c1m4",
"ancestors": ["ss-2026-01-25...", "ss-2026-01-26..."]
}
delta-manifest.json
Only present in incremental snapshots. Contains the file-level delta. See Incremental Snapshots for the full spec.
restore-hints.json
Platform-specific restore instructions, including required steps and manual actions:
{
"platform": "clawdbot",
"steps": [
{
"type": "file",
"description": "Restore SOUL.md and identity files",
"target": "identity/"
}
],
"manualSteps": ["Review restored settings..."]
}