recursive-agent 0.8.2

A Rust coding-agent platform: kernel, tools, multi-agent orchestration, HTTP API, MCP, and TUI
Documentation
---
type: Architecture
title: Sessions — Persistence and Lifecycle
description: How agent sessions are stored, resumed, and migrated. JSONL transcript format, .meta.json structure, and the session lifecycle.
tags: [sessions, persistence, transcript, episodic]
timestamp: 2026-06-18T10:00:00Z
---

# Sessions

Source: `src/session/` (writer.rs, reader.rs, lifecycle.rs, serialize.rs)

Every agent run is a session. Sessions are persisted to disk so:
- Transcripts survive crashes (Invariant #7).
- Episodic recall can search past runs.
- The self-improve loop can inspect failures.

## Storage Layout

```
~/.recursive/workspaces/<12-char-hash>/
├── path.txt                     ← workspace path back-reference
└── sessions/<session-id>/
    ├── .meta.json               ← session metadata
    ├── transcript.jsonl         ← one message per line
    └── cost.json                ← token usage and cost
```

Session ID format: `<ISO8601-start>-<workspace-slug>` (e.g. `2026-05-28T03:41:37Z-...`)

## .meta.json

```json
{
  "session_id": "2026-05-28T03:41:37Z-...",
  "created_at": "2026-05-28T03:41:37Z",
  "status": "complete",
  "model": "deepseek-chat",
  "message_count": 116,
  "cost_usd": 0.09352
}
```

`status`: `"incomplete"` while running, `"complete"` on clean finish, `"failed"` on crash.

## transcript.jsonl

One JSON object per line — either a `Message` or a tool-call/result pair:

```json
{"id":"msg_001","role":"user","content":"# Goal 131...","timestamp":"..."}
{"id":"msg_002","role":"assistant","content":"...","tool_calls":[{"id":"tc_1","name":"Read","args":{...}}],"timestamp":"..."}
{"id":"msg_003","role":"tool","tool_call_id":"tc_1","content":"...","timestamp":"..."}
```

**Invariant #8**: `Role::Tool` messages MUST immediately follow the
`Role::Assistant` message whose `tool_calls` lists their `id`. Any compaction,
trimming, or resume replay that orphans tool results will be rejected by the
provider with HTTP 400.

## Resume

`AgentRuntime` can reload a previous session's transcript and continue from
where it left off. The self-improve flow's auto-resume step checks that a
saved transcript exists before attempting resume.

## Migration

`src/migrate.rs` handles migration of legacy `.recursive/sessions/` and
`.recursive/scratchpad.json` paths to the new `~/.recursive/workspaces/<hash>/`
structure.

## Related Concepts

- [Agent Loop]agent-loop.md — how transcripts grow per turn
- [Layer 3 — Episodic]memory/layer3-episodic.md — searching past sessions
- [Invariants]invariants.md — Invariant #7 (transcript always saved), Invariant #8 (tool-call pairing)