# `CMDC.Checkpoint`
[🔗](https://github.com/tupleyun/cmdc/blob/v0.5.0/lib/cmdc/checkpoint.ex#L1)

会话快照（checkpoint）一等公民 API。

让 Agent 在 BEAM 重启、Gateway 滚动升级、用户跨设备恢复等场景下
能保留完整对话上下文继续推进。

## 设计

- **抽象层**：`CMDC.Checkpoint.Backend` behaviour 定义 4 个回调
  （`save/3` / `load/2` / `list/2` / `delete/2`），实现可插拔。
- **默认后端**：`CMDC.Checkpoint.Backend.ETS`（进程内）/
  `CMDC.Checkpoint.Backend.DETS`（轻持久化，单节点）。
- **可选后端**：`cmdc_memory_pg` 子库提供
  `CMDC.Checkpoint.Backend.Postgres`。
- **统一 payload**：`CMDC.Checkpoint.Snapshot` struct 带
  `@schema_version`，序列化时丢弃 pid / Stream / Task 等不可重建字段。

## Quick Start

    iex> {:ok, snap} = CMDC.Checkpoint.save(session_id, agent_state)
    iex> {:ok, ^snap} = CMDC.Checkpoint.load(session_id)

## 与 ACP / Steering 的关系

- `cmdc_acp` 的会话恢复（Zed 切换 thread）= `CMDC.Checkpoint.load/2`
- 10A Steering 的 `:max_steering_queue` 队列在 snapshot 中序列化
- `Plugin.Builtin.HumanApproval` 在 `:session_start` 重建 pending approval
  队列（不可序列化字段策略）

# `backend`

```elixir
@type backend() :: module() | {module(), keyword()}
```

Backend 实现模块或 `{module, opts}` 元组。

# `opts`

```elixir
@type opts() :: keyword()
```

存储/读取/列表/删除统一选项。

# `session_id`

```elixir
@type session_id() :: String.t()
```

会话标识符（通常是 `Agent.State.session_id`）。

# `delete`

```elixir
@spec delete(session_id(), opts()) :: :ok | {:error, term()}
```

删除指定会话的快照。

## 选项

- `:checkpoint_id` — 仅删除指定 checkpoint（默认删除该 session 全部快照）
- `:backend` — 覆盖默认 backend

# `list`

```elixir
@spec list(session_id(), opts()) ::
  {:ok, [CMDC.Checkpoint.Snapshot.t()]} | {:error, term()}
```

列出指定会话所有快照（按 `saved_at` 倒序）。

# `load`

```elixir
@spec load(session_id(), opts()) ::
  {:ok, CMDC.Checkpoint.Snapshot.t()} | {:error, :not_found | term()}
```

加载最新一份会话快照。

## 选项

- `:backend` — 覆盖默认 backend
- `:checkpoint_id` — 加载指定 checkpoint（默认加载最新）

# `save`

```elixir
@spec save(session_id(), CMDC.Checkpoint.Snapshot.serializable(), opts()) ::
  {:ok, CMDC.Checkpoint.Snapshot.t()} | {:error, term()}
```

保存 Agent 状态快照。

## 参数

- `session_id` — 会话 ID
- `state` — Agent 内部状态 struct 或任意可序列化 map
- `opts`：
  - `:backend` — 覆盖默认 backend（`Application.get_env(:cmdc, :checkpoint_backend, ETS)`）
  - `:label` — 可选标签（如 `"after_plan_approved"`），方便回溯
  - `:metadata` — 用户附加 map

返回 `{:ok, Snapshot.t()}` 含生成的 `:checkpoint_id` 与 `:saved_at`。

## Examples

    iex> {:ok, snap} = CMDC.Checkpoint.save("sess-1", state, label: "before_compact")
    iex> snap.session_id
    "sess-1"

---

*Consult [api-reference.md](api-reference.md) for complete listing*
