Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

运行时状态和持久化

ZeroClaw 只有一个安装根目录,但没有一个单一的“workspace 数据库”。不同的状态表面有不同的所有者、重载行为和持久性。当变更新增状态、移动状态、缓存配置、涉及重载,或更改 session/memory/log/cost 行为时,请使用这张映射图。

单一事实来源规则仍然适用:如果某个事实已经存在于某个界面中,就不要将其复制到另一个存储字段中。只有当此表标识了拥有该界面时,才存储新状态;否则在使用时从规范拥有者处解析它。

安装布局

对于普通安装,<install> 是解析后的配置目录(默认情况下为 ~/.zeroclaw/,Homebrew 和显式的 --config-dir 安装可以将其移动)。当前布局如下:

<install>/
├── config.toml                 # canonical user config
├── .secret_key                 # key for encrypted secrets
├── data/                       # instance-wide runtime data
│   ├── sessions/
│   │   ├── sessions.db         # default chat/session backend
│   │   └── acp-sessions.db     # ACP protocol sessions
│   ├── cron/jobs.db            # scheduled job state
│   ├── sop/runs.db             # optional durable SOP run state
│   ├── control_plane.db        # task supervision records
│   ├── state/
│   │   ├── runtime-trace.jsonl # persisted logs
│   │   └── costs.jsonl         # cost ledger
│   ├── devices.db              # paired-device metadata
│   └── memory/                 # shared instance memory stores
├── shared/                     # shared resources, such as skill bundles
└── agents/<alias>/workspace/   # per-agent filesystem sandbox and identity

迁移期间仍然接受旧的 <install>/workspace/ 名称,但新的运行时状态应以 <install>/data/<install>/shared/ 和每个 agent 的工作区来描述。

状态映射

Surface规范源持久路径内存中的所有者重载 / 并发边界备注
配置值zeroclaw-config::Config 已从 config.toml 加载<install>/config.toml守护进程 Arc<RwLock<Config>> 加上每个子系统解析后的视图/admin/reload 会重新读取配置并重新实例化守护进程子系统;直接配置写入会使用模式验证和脏路径检查。RPC 侧的配置变更还会在 RpcContext::config_write_lock 上串行化整个读取-变更-刷新部分(先使用 tokio 互斥锁,再使用 parking_lot RwLock,并且绝不在 .awaitlock().await 上持有 parking_lot 守卫);网关 HTTP 配置变更同样会在 AppState::config_write_lock 上串行化整个读取-变更-交换部分(锁顺序相同)除非缓存会在重载时明确重建,否则不要将从配置派生的事实缓存到生命周期较长的结构体中。
配置保存持久性save() / save_dirty()zeroclaw-config 中的原子写入路径<install>/config.toml 以及保留的 config.toml.bak与配置值相同写入会依次执行临时文件写入、替换前目录同步、原子重命名以及替换后目录同步Ok(()) 表示替换可见,而不表示重命名持久性已得到保证:替换前发生的失败会中止操作,此时磁盘上的配置和当前生效的配置均保持不变;但重命名后发生的目录同步失败仍会返回 Ok(()),同时记录警告并保留 config.toml.bak。在此类保存操作紧接着发生崩溃后,目录项可能会重放为之前的文件;调用方不得将 Ok 视为更强的持久性保证,恢复时可以查阅保留的 .bak
加密的密钥配置 secret 字段以及 .secret_key<install>/config.toml, <install>/.secret_keyzeroclaw-config 中的 secret-store 帮助程序Reload 会观察已更改的配置;丢失 .secret_key 会使加密的配置密钥无法恢复切勿将解密后的值复制到日志、文档、PR 正文或运行时元数据中。
Agent 文件系统标识每个代理的工作区文件<install>/agents/<alias>/workspace/有效的 SecurityPolicy 和 agent 提示构建在 agent 启动时惰性创建;工作区访问根据 config 进行评估这是文件系统沙箱,不是 providers/channels/tools 的配置权威来源。
共享技能包已配置的技能包条目和已解析的包目录默认情况下为 <install>/shared/skills/<bundle>/技能加载 / 提示增强重新加载并让新代理在启动时观察配置和文件系统变化bundle 别名和目录解析来自配置;文件则是 bundle 内容。
会话记忆已按代理选择 zeroclaw-memory 后端SQLite/Postgres/Lucid/Qdrant/Markdown 后端位置;SQLite 共享存储位于 data/memory/Arc<dyn Memory> 包裹在 agent 作用域适配器中一旦某个 agent 写入了数据,后端选择就会被锁定;同一后端的跨 agent recall 需要显式启用Memory 行是按 agent 作用域划分的。不要用复制的 prompt/session 缓存来替代 memory 所有权。
聊天和频道会话[channels].session_backendSessionBackend默认 data/sessions/sessions.db;旧版/显式 JSONL 使用 data/sessions/*.jsonlzeroclaw-infra 后端句柄目前由通道、网关、RPC 和会话工具分别构造SQLite 后端使用 WAL;SessionActorQueue 按会话串行化活动回合;JSONL 变更共享进程本地的会话目录锁Chat/Code 会话使用统一的后端契约。ACP 协议会话使用独立的存储。进程级后端所有权尚未实现单一来源管理。
ACP 会话ACP 协议会话存储data/sessions/acp-sessions.dbAcpSessionStore 在守护进程启动时以及在 RPC 上下文中打开由 WAL 支持的 SQLite 存储,与聊天会话分离ACP session/loadsession/resume 作用于此协议存储,而不是聊天会话后端。
实时 RPC/TUI 会话RPC SessionStore单独为 nonecrates/zeroclaw-runtime/src/rpc/session.rs 内存映射进程本地;会话历史仅通过聊天或 ACP 后端持久化Live session 句柄、上传、取消令牌、所有者和覆盖项是运行时状态。
Cron 作业声明式配置成员资格加上 cron SQLite 存储data/cron/jobs.dbzeroclaw-runtime::cron 调度器/存储读取路径不会创建 jobs.db;调度器拥有到期/锁定状态声明式作业从配置中进行协调,而运行元数据和锁保存在 cron DB 中。
SOP 运行SopEngineSopRunStore默认情况下为 None;当持久化 SQLite 初始化成功时为 data/sop/runs.dbSOP 引擎活跃/已完成运行缓存持久化存储负责管理准入声明和已持久化的修订版本;引擎在启动时恢复活动状态和终止状态存储初始化失败会记录一条警告,并回退到内存。以内存为后端的审计记录不是运行生命周期的事实来源。
后台任务监控持久化任务控制平面data/control_plane.db控制平面句柄、任务生产者和回收器所有者 PID/启动 ID 可识别上次启动遗留的孤儿;心跳超时仅适用于发出心跳的生产者当前的委托/子代理生产者会尽力注册行记录,但会遗漏心跳、父级、路由和主体字段。目标 API 已存在,但端到端的目标执行尚未接入。
后台委托结果委托结果记录<workspace>/delegate_results/<task-id>.json委托工具取消注册表和运行中的 future结果文件在重启后依然保留;实时取消句柄则不会读取以文件优先,并且仅当文件仍显示为 running 时,才叠加 losttimed_out 监管状态;结果写入和控制平面写入相互独立,可能会出现分歧。
运行时日志zeroclaw-log 事件模式和订阅层data/state/runtime-trace.jsonl 在启用持久化时广播 hook、JSONL writer、/api/logs reader、Observer bridgeRolling/full/none 持久化由配置控制;即使禁用了 JSONL,dashboard SSE 仍会接收事件日志是证据和可观测性,而不是用户配置或会话状态的来源。
成本分类账CostTracker 加上费率配置data/state/costs.jsonlprocess-global CostTracker重新加载会热替换 CostConfig;如果启用了成本跟踪,则会按需构造跟踪器现有记录保持其已记录的价格;费率编辑会在重新加载后影响后续请求。
网关配对令牌PairingGuard 来自 gateway.paired_tokens配置中的 token 哈希配对保护Reload 会根据配置重建 guard有效的 bearer token 是配置状态,而不是 devices.db 行。
配对设备元数据由令牌哈希键控的设备注册表行data/devices.dbDeviceRegistry 缓存加 SQLiteRegistry 将元数据与规范的配对标记集进行对账这个 DB 使已配对的设备可见/可管理;它不会生成有效的 token。
健康状况和组件状态运行子系统报告组件状态网关健康/状态状态进程本地;在守护进程重启或重新加载时重置/重建/health/api/health/api/status 是当前观测值,而不是持久配置。
队列、去抖器、看门狗zeroclaw-infra 进程实用工具除非调用方将结果存储到其他地方,否则为 none内存中的队列/防抖器/看门狗进程内;用于序列化、合并或检测停滞将它们视为协调状态。仅持久化它们所保护的领域数据,而不是队列本身。

重新加载并重启

POST /admin/reload 会向守护进程发送一个进程内重载信号。外层守护进程循环会从磁盘重新读取配置并重新运行守护进程,根据新配置创建新的网关、通道、心跳、调度器、MQTT、会话、内存和成本连接。PID 保持不变,但监听器会短暂重新绑定。

完整的进程重启还会轮换进程本地状态,例如活动 RPC 会话、健康快照、actor 队列,以及任何临时的工具收据密钥。持久化存储会根据上表在重启后保留。

会话后端迁移

选择 SQLite 会话后端时,构造后端句柄会导入旧版 data/sessions/*.jsonl 文件。导入器在持有进程本地 JSONL 变更锁的同时,将每个源文件移至私有的 .jsonl.importing 版本,在一个 SQLite 事务中写入消息、元数据和与源文件绑定的导入回执,然后将源文件保留为 .jsonl.migrated 以便回滚。

回执将源文件名、会话键、SHA-256 摘要和字节长度绑定在一起。回执事务开始前,导入器会同步暂存的源文件,并在 Unix 上同步活动目录到暂存目录的重命名。迁移事务会在导入提交时使用完整的 SQLite 同步,然后恢复正常的运行时设置。归档移交同样会在 Unix 上同步目录元数据,然后移除暂存的源文件。在扫描源文件之前,后端构造会根据持久化回执恢复进程本地的非活动状态。导入回执一经提交,即使归档移交或后续文件失败,该会话目录的 JSONL 变更仍会保持非活动状态。下一次构造可以根据该回执验证暂存源,并完成移交,而不会插入重复消息。空的和仅包含空白字符的 JSONL 文件会作为不含消息的 SQLite 会话保留;不含有效消息的非空源文件仍会安全失败。

在不导入源的情况下构建 SQLite 后端,并不会停用 JSONL 变更。因此,如果不存在持久化的导入回执,进程内重新加载可能会切回 JSONL。

没有回执的源不会与同一会话键对应的现有 SQLite 消息或元数据合并。如果提交前检查失败,则会将暂存源恢复到其实际的 JSONL 路径。不兼容的回执、暂存源或归档会导致后端构造返回错误。当前,每个进程入口点都会独立决定该错误是停止子系统,还是禁用持久化;进程级所有权和启动策略与迁移契约彼此分离。

备份和恢复

对于普通的单实例安装,请备份整个 <install> 目录。至少应包括:

  • config.toml
  • .secret_key 如果使用了加密机密
  • data/memory/
  • data/sessions/
  • data/cron/jobs.db 如果 cron jobs 通过运行时 surface 配置
  • 如果启用了持久化 SOP 运行,则为 data/sop/runs.db
  • data/control_plane.db(如果监督任务历史记录很重要)
  • data/state/costs.jsonl 如果成本历史很重要
  • data/state/runtime-trace.jsonl 如需用于事件审查的日志
  • data/devices.db 用于已配对设备元数据

不要让两个守护进程针对同一个安装根目录运行。多个存储使用具有单写入者模型的 SQLite,而进程本地缓存假定只有一个守护进程拥有该实例。

源指针

  • Config、install-root 和 data-dir 的解析:crates/zeroclaw-config/src/schema.rs
  • 会话后端:crates/zeroclaw-infra/src/session_sqlite.rscrates/zeroclaw-infra/src/session_store.rs
  • ACP 会话存储:crates/zeroclaw-infra/src/acp_session_store.rs
  • RPC 实时会话:crates/zeroclaw-runtime/src/rpc/session.rs
  • Cron 持久化:crates/zeroclaw-runtime/src/cron/store.rs
  • SOP 持久化:crates/zeroclaw-runtime/src/sop/store/
  • 后台任务与目标监督:crates/zeroclaw-runtime/src/control_plane/
  • 后台委托结果:crates/zeroclaw-runtime/src/tools/delegate.rs
  • 日志:crates/zeroclaw-log/
  • 成本账本:crates/zeroclaw-config/src/cost/tracker.rs
  • 配对守卫:crates/zeroclaw-config/src/pairing.rs
  • 设备注册表:crates/zeroclaw-gateway/src/api_pairing.rs
  • 重新加载端点:crates/zeroclaw-gateway/src/lib.rs