Skip to content

Field Manual

Session Stores

Session stores hold continuity: prompts, tool records, local state, memory, and resume metadata that can tie a timeline together.

Why it matters

Without session stores, an investigation may see final files but miss the sequence of decisions and tool actions that produced them.

Evidence to look for

  • Session IDs
  • Conversation JSONL or databases
  • Workspace paths
  • Tool-call transcripts
  • Resume markers
  • Local agent memory

Common pitfalls

  • Running tools that rotate or compact sessions
  • Collecting only visible chat export
  • Sharing raw stores that contain secrets

Session store formats by agent

Each agent uses a different storage format and directory structure. Understanding these differences is essential for locating, preserving, and parsing session evidence.

Codex CLI session store

Codex stores sessions as JSONL files organized by date. Each session file contains a session_meta header followed by event_msg records. Codex maintains three session directories: active sessions, archived sessions, and headless sessions.

Artifact Paths

Active sessions

~/.codex/sessions/YYYY/MM/*.jsonl

JSONL files organized by year and month.

Archived sessions

~/.codex/archived_sessions/*.jsonl

Completed sessions moved from active.

Headless sessions

~/.codex/headless/*.jsonl

Non-interactive agent runs.

Codex — JSONL session with session_meta header
JSON
                          {"type":"session_meta","timestamp":"2026-04-03T06:00:00Z","payload":{"source":"cli","model_provider":"fixture-provider","agent_nickname":"fixture-agent","model":"fixture-model"}}

{"type":"event_msg","timestamp":"2026-04-03T06:00:01Z","payload":{"type":"user_message","message":"Inventory the MCP configuration for this synthetic workspace."}}

{"type":"event_msg","timestamp":"2026-04-03T06:00:02Z","payload":{"type":"tool_call","tool_name":"mcp_inspector","command":"probe mcp servers","arguments":{"server":"filesystem","inventory_method":"tools/list"}}}
                        

Codex sessions always start with a session_meta record. Respects $CODEX_HOME if set.

Claude Code session store

Claude Code stores sessions as JSONL files organized by project. Each project directory contains session files with alternating user and assistant message records.

Artifact Paths

Project sessions

~/.claude/projects/<project-hash>/*.jsonl

One directory per project. Each JSONL file is one session.

Claude — JSONL with user/assistant message records
JSON
                          {"type":"user","sessionId":"claude-tool-use","timestamp":"2026-04-27T12:10:00Z","message":{"role":"user","content":[{"type":"text","text":"Read the project README and summarize it."}]}}

{"type":"assistant","sessionId":"claude-tool-use","timestamp":"2026-04-27T12:10:01Z","message":{"role":"assistant","model":"claude-fixture-model","content":[{"type":"text","text":"I will read the public README only."},{"type":"tool_use","id":"toolu_fixture_read","name":"Read","input":{"file_path":"README.md"}}]}}
                        

Claude Code sessions use type values of user and assistant at the top level. Tool calls and results are nested inside message.content arrays.

Gemini CLI session store

Gemini CLI stores each session as a single JSON file. Unlike JSONL-based agents, the entire session is one JSON object with a messages array.

Artifact Paths

Session files

~/.gemini/tmp/*.json

Single JSON file per session. Contains the full session in one object.

Gemini — single JSON object with messages array
JSON
                          {
  "sessionId": "gemini-uc001-tool-result",
  "projectHash": "fixture-project",
  "startTime": "2026-04-27T12:30:00Z",
  "lastUpdated": "2026-04-27T12:30:02Z",
  "model": "gemini-fixture-model",
  "messages": [
    { "type": "user", "content": "Check the repository status." },
    { "type": "tool_call", "name": "repo_status", "input": { "format": "json" } },
    { "type": "tool_result", "tool": "repo_status", "content": "status=ok" }
  ]
}
                        

Gemini sessions are atomic JSON files. Session metadata (sessionId, projectHash, model) lives at the top level alongside the messages array.

OpenCode session store

OpenCode uses a SQLite database for current sessions and legacy JSON files for older installations. The SQLite database is the primary store; the JSON files are a legacy format.

Artifact Paths

Current (SQLite)

~/.local/share/opencode/opencode.db

SQLite database. macOS: ~/Library/Application Support/opencode/opencode.db.

Legacy (JSON)

~/.local/share/opencode/storage/message/<session-id>/*.json

One JSON file per message or a JSON array per session directory.

OpenCode — legacy per-message JSON array
JSON
                          [
  {
    "id": "msg-cred-1",
    "sessionID": "opencode-uc002-credential-publish",
    "type": "tool_call",
    "tool_name": "bash",
    "arguments": { "command": "cat ~/.aws/credentials" },
    "modelID": "fixture-model",
    "providerID": "fixture-provider",
    "time": "2026-04-28T10:00:00Z",
    "agent": "build"
  }
]
                        

Legacy format uses tool_name and arguments fields. Current SQLite installations preserve the same field names in database rows.

Roo Code and Kilo Code session store

Roo Code and Kilo Code store sessions as JSON files in VS Code extension globalStorage directories. Each task directory contains a ui_messages.json file with a flat JSON array of all events.

Artifact Paths

Roo Code

~/.config/Code/User/globalStorage/rooveterinaryinc.roo-cline/tasks/<task-id>/ui_messages.json

VS Code extension storage. macOS: ~/Library/Application Support/Code/. Windows: %APPDATA%\Code\.

Kilo Code

~/.config/Code/User/globalStorage/kilocode.kilo-code/tasks/<task-id>/ui_messages.json

Same format as Roo Code. macOS: ~/Library/Application Support/Code/. Windows: %APPDATA%\Code\.

Roo Code — ui_messages.json flat array
JSON
                          [
  { "type": "user", "content": "Check the repository status." },
  { "type": "tool_call", "name": "repo_status", "input": { "format": "json" } },
  { "type": "tool_result", "tool": "repo_status", "content": "status=ok" }
]
                        

The ui_messages.json file contains a flat JSON array. The array preserves chronological order. VS Code extension paths follow platform conventions for globalStorage.

GitHub Copilot session store

GitHub Copilot CLI records sessions as plain text process logs in the repository directory. This is the most limited and lossy session store format.

Artifact Paths

Process logs

<repo>/logs/copilot/process-*.log

Plain text log files. Tool calls are embedded as JSON in log lines.

Copilot — process log with embedded function_call
TEXT
                          2026-04-27T16:16:57.841Z [INFO] Workspace initialized: copilot-uc001-tool-result (checkpoints: 0)
2026-04-27T16:16:57.847Z [INFO] Starting Copilot CLI: 1.0.36
2026-04-27T16:17:17.990Z [INFO] Accumulated output items (1): [{"arguments":"{\"format\":\"json\"}","call_id":"call_fixture_001","id":"c1","name":"repo_status","status":"completed","type":"function_call"}]
2026-04-27T16:17:45.200Z [INFO] Session completed.
                        

Copilot process logs are the most lossy format. User intent, system instructions, and structured content are not preserved. Tool call arguments are stringified JSON.

Preservation priorities

When preserving session stores for investigation, follow these priorities:

  • Copy the raw files first. Do not parse, normalize, or transform before preserving. Use forensic copy tools when possible.
  • Record the source path and collection time. Provenance metadata is essential for defending the evidence chain.
  • Check for variant directories. Codex has active, archived, and headless sessions. OpenCode has both SQLite and legacy JSON. Missing a variant means missing evidence.
  • Hash the preserved files. SHA-256 hashes let you verify that preserved copies have not been modified.
  • Do not run the agent or its tools on the preserved copy. Session stores can be modified by agent startup, compaction, or rotation.
  • Check for VS Code extension variants. Roo Code and Kilo Code store data under VS Code globalStorage paths that differ from CLI-based agents.