# `CMDC.Plugin.Builtin.AutoCheckpoint`
[🔗](https://github.com/tupleyun/cmdc/blob/v0.5.3/lib/cmdc/plugin/builtin/auto_checkpoint.ex#L1)

按以下任一条件**OR 触发** `CMDC.checkpoint!/2`，自动持久化会话快照。

## 触发条件（OR 语义，任一命中即存）

- `every_n_turns: N`（默认 10）— 每 N 个完成的 turn 后存档（hook：`:after_turn`）
- `on_tools: ["shell", "edit_file"]`（默认 `[]`）— 指定工具执行完后存档（hook：`:after_tool`）
- `on_events: [:approval_required, :session_end, ...]`（默认 `[:approval_required, :session_end]`）—
  指定事件后存档；事件名为 atom（与 EventBus 事件首元 atom 对齐）

## 自动 GC

避免 backend 无限堆积（PG 表 / DETS 文件爆炸）:

- `max_checkpoints: N`（默认 50）— 同 session 超过 N 份后，删除最老
- `ttl_seconds: N`（默认 30 天 = 2_592_000）— 老于此时间的 snapshot 自动删除

GC 在每次成功 save 后异步执行，不阻塞主流程。

## 异步保存

Plugin handle_event 内**不会**同步调 `Checkpoint.save/3`(那会阻塞 Agent gen_statem
callback)。`save` + `GC` 都通过 `CMDC.AsyncTaskSupervisor` 起独立 Task 执行，
失败仅 Logger.warning 不影响主路径。

## 配置示例

    # 基础：每 5 turn 自动存档到 ETS（开发期）
    {CMDC.Plugin.Builtin.AutoCheckpoint, backend: CMDC.Checkpoint.Backend.ETS, every_n_turns: 5}

    # 生产推荐：cmdc_memory_pg PG backend + 关键事件 + 关键工具
    {CMDC.Plugin.Builtin.AutoCheckpoint,
     backend: CMDCMemoryPg.CheckpointBackend,
     every_n_turns: 10,
     on_tools: ["shell", "edit_file", "write_file"],
     on_events: [:approval_required, :session_end, :agent_abort],
     max_checkpoints: 100,
     ttl_seconds: 7 * 86_400}

## 与 `Checkpoint.Backend` 关系

- Plugin 自身不依赖任何特定 backend；通过 `:backend` opt 注入
- 默认与 `CMDC.Checkpoint.Backend.ETS` 兼容；生产换 `CMDCMemoryPg.CheckpointBackend`
- snapshot 走 `CMDC.checkpoint!/2` facade,所以与 `CMDC.resume_session!/2` 全套自动兼容

## 事件

每次成功 save 后 emit `{:auto_checkpoint_saved, %{checkpoint_id, trigger, ...}}`,
供 UI / 审计订阅。失败时仅 `Logger.warning`（避免事件流噪音）。

# `state`

```elixir
@type state() :: %{
  backend: module(),
  every_n_turns: pos_integer() | nil,
  on_tools: [String.t()],
  on_events: [atom()],
  max_checkpoints: pos_integer(),
  ttl_seconds: pos_integer()
}
```

AutoCheckpoint Plugin 运行时状态。

---

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