Docs
Home GitHub npm

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:

snapshot.saf.enc (decrypted) ├── manifest.json ← version, timestamp, ID, checksum ├── identity/ │ ├── personality.md ← system prompt, SOUL, instructions │ ├── config.json ← settings, preferences, account info │ ├── tools.json ← tool/plugin/skill configurations │ ├── skills.json ← skill directories with scripts │ ├── scripts.json ← personal scripts, cron wrappers │ ├── extensions.json ← extension configs │ ├── file-manifest.json ← project file tree (paths + sizes) │ └── project-meta.json ← package.json, pyproject.toml, etc. ├── memory/ │ ├── core.json ← platform memory entries │ └── knowledge/ │ └── index.json ← knowledge base document index ├── conversations/ │ └── index.json ← conversation metadata index └── meta/ ├── platform.json ← source platform details ├── snapshot-chain.json ← incremental chain info ├── restore-hints.json ← platform-specific restore steps └── delta-manifest.json ← incremental delta (if not full)

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
}
FieldTypeDescription
versionstringSAF format version
timestampstringISO 8601 creation timestamp
idstringUnique snapshot ID (ss-{timestamp}-{random})
platformstringSource platform identifier
adapterstringAdapter ID used for extraction
checksumstringSHA-256 of the unencrypted archive
parentstring?Parent snapshot ID (for incrementals)
labelstring?Human-readable label
tagsstring[]?Organizational tags
sizenumberUnencrypted 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..."]
}