跳转至

旧版状态迁移

openclaw doctor --fix 负责持久化的文件到 SQLite 迁移。本页介绍每个迁移来源,以及在某个来源持续受阻时应如何处理。

六月之前的 Telegram 和 iMessage 缓存、Active Memory 会话切换、Nostr 总线和配置文件状态,以及 Microsoft Teams 对话、投票、SSO 令牌和反馈学习内容不再从 JSON 文件导入。如果这些来源仍然存在,Doctor 会保留它们,并引导你先通过 2026.9.5 升级并运行其迁移。现有 SQLite 状态仍然具有权威性。仅当退役的 Telegram thread-bindings-*.json 文件是常规文件、且内容恰好为版本 1 和空 bindings 数组时,Doctor 才会将其归档为已完成的空操作。非空、格式错误、符号链接或其他不确定的文件仍会保留以供操作者审查。如果归档已验证的空文件失败,Doctor 会保留原始字节以便稍后重试,并报告可恢复的警告。此清理失败不会阻塞更新。

已退役的 subagents/runs.json 文件也会被忽略并保持原样;临时运行记录绝不会从这些文件中恢复。

遗留状态迁移

当 Doctor 选择类似 ~/.clawdbot 的旧版主目录时,它会在将该目录移动到 ~/.openclaw 之前排空未完成的数据库工作。它会在移动和旧版别名创建期间保持对源位置的独占所有权,然后在导入插件元数据或升级 SQLite 模式之前,取得结果路径的所有权。显式设置的 OPENCLAW_STATE_DIR 会保留其选定的位置。如果别名创建失败且移动被回滚,修复将在原始位置的所有权下继续,并报告回滚情况。

openclaw doctor --fix 负责通用的持久化文件到 SQLite 迁移。它会验证并认领每个可识别的来源,写入并验证规范行,记录迁移回执,然后移除已退役的来源。Gateway、节点主机和本地 CLI 启动时会将通用旧版修复留给 Doctor。常规的版本化数据库打开、原生初始化以及有效当前配置的恢复仍然可用。狭义的重启通知导入器也服务于随六月更新程序一起写入的后期更新通知,使用的是相同的迁移所有者和回执。

容器镜像入口点会在启动 Gateway 之前,针对挂载的状态和配置自动运行 openclaw doctor --fix --non-interactive。如果你覆盖了该入口点,请针对相同的挂载显式运行 Doctor。Doctor 会在独占维护所有权下执行所需的旧版修复,并在模式升级之前保留经过验证的 SQLite 副本,同时保留其正常的配置备份和旧版文件归档。Gateway 启动随后检查运行时就绪状态。不安全的必需存储会以退出码 78 及具体原因退出。被拒绝的默认代理或系统代理绝不会产生健康的就绪响应。未使用的旧版存储(包括没有代理所有者的零散 agent/settings.json 文件)保持原样并推迟处理。Doctor 会报告保留的来源并继续独立的迁移;启动时会报告剩余的就绪提示。提示绝不会掩盖单独的必需存储拒绝。

如果 Doctor 在代理 schema 或媒体迁移期间被中断,请停止使用该状态的其他 OpenClaw 进程,并重新运行 openclaw doctor --fix。只有当记录的迁移所有者的主机、PID 和进程启动身份证明该进程已结束时,Doctor 才会收回该迁移所有权。未提交的数据库更改会回滚;下一遍将恢复未完成的工作,同时保留迁移前的备份。没有进程身份的旧租约在重试之前保留其现有到期时间。

仅因先前拒绝而受阻的步骤会保留 refusal.code: "blocked-by-prior-refusal",并在 originatingRefusal 中包含首次拒绝的 stepId、原因 code 和人类可读的 message。在重试受阻步骤之前,请先解决该原始失败。这些字段会随 stepReceipts 一起传递,包括 Doctor 拒绝错误;它们与 migration_runs 和 migration_sources 中持久化的导入回执是分开的。较旧的执行回执可能会省略 originatingRefusal。

如果受阻的所有者可以在不写入的情况下独立验证其输入,则已验证的输入错误会保留自己的 step-refused 回执和警告。较早的失败仍会作为 originatingRefusal 附加。Doctor 将这一点应用于旧版 TUI 上次会话 JSON:即使较早的维护心跳已退出,格式错误的输入仍保持明确。有效或不存在的输入仍会被先前的失败阻塞。此诊断检查不会授权后续迁移或写入。

doctor --fix 会在其停止消息和健康警告中包含失败的检查、拒绝代码和原因,使用与 openclaw update repair 相同的失败事实。其受限摘要会在衍生受阻步骤之前列出观察到的拒绝;完整回执列表保留完整链条。

Doctor 会在预检期间导入可识别的旧版工作区设置文件,然后 Workshop 迁移才会访问工作区状态。现有的规范 SQLite 设置记录优先,包括 SQLite 中不存在的里程碑。Doctor 不会在其上重放过时的里程碑。在移除已验证的设置文件或中断的认领之前,Doctor 会将其精确字节保留在原始文件旁边,形式为 <source>.migrated.<sha256>.<unique-id>。SQLite 迁移回执会记录该归档路径,并为每个不同的里程碑记录一行(legacy=... canonical=...),Doctor 也会打印这些内容。如果没有规范设置记录,Doctor 会正常导入旧版里程碑。成功的修复会移除运行时阻塞;下一次运行不会重复工作区设置迁移。无效文件以及工作区身份/版本冲突仍会保留以供检查。

更新演练只在其复制的状态目录内写入。演练不会复制工作区文件,因此提案、回滚和备份记录中保留的绝对路径仍然是只读清单。Doctor 会报告它保留未动的旧版工作区文件数量;它不会退役这些文件或提案历史。候选版本安装后,真正的 Doctor 会针对操作者的状态执行正常的导入、归档和迁移。

声明文件位于已复制状态之外的插件迁移,会作为单个插件操作被延迟处理。Doctor 会完整保留这些文件及待处理标记,并报告该延迟;配置修复仍会照常运行。Reef 的遗留目录也遵循此规则,包括其已归档文件。

已完成且有意保留文件的代理删除,在更新和迁移发现期间会被暂缓处理。Doctor 会记录一条可恢复的警告,指明代理名称、数据库路径,并提供 openclaw doctor --fix 修复指引。这些存储不会阻止活动代理的迁移或更新演练。如果共享认证源被保留,其迁移会记录一次跳过,相关认证修复将等待;无关的 Doctor 修复则继续执行。在迁移被保留的存储之前,请先恢复预期保留的代理。待处理的文件删除会沿用删除所有者的既有安全检查。

当删除历史缺失时,Doctor 会报告被暂缓修复的未验证存储数量。普通的会话创建和数据库租约会记录未知的删除历史并继续运行;缺失的行或重建回执不会使代理被删除或不可用。运行时不会在现有状态上重新创建空日志。即使共享数据库及其注册表已不存在,幸存的隔离/完整性数据库仍是先前状态的证据。在没有代理路径的情况下重新打开共享状态,会保留未知的删除历史;被保留的外部存储在维护之前仍需要 Doctor 重建。经验证的全新 SQLite 设置会正常初始化日志,不会出现缺失历史警告。仅遗留的 JSON 会话文件本身不需要重建日志。当删除历史不可用时,会话 SQLite 导入和恢复会保留现有的代理数据库及其附属文件,从而在不导入或归档的情况下保留遗留来源。已记录的删除和重建保留,以及带有导入回执的被保留插件输入,仍受到保护。无法读取的历史不会抹除可读取的删除身份或已记录的保留。openclaw doctor --fix 会重建日志,并在现有迁移表中记录一份列出被保留数据库路径的回执。重建会保留这些存储,而不会迁移或弃用它们。运行时准入独立于 Doctor 的修复保留。请查看这些路径,并使用 Doctor 打印的非交互式 openclaw agents add 命令恢复预期保留的代理,或使用 openclaw agents delete 确认删除。未配置的代理必须先恢复,然后才能删除。对于自定义数据库文件名,请先恢复原始的 session.store 配置;当 agents add 无法选择被保留的存储时,它会拒绝创建空的替代文件。如果 Doctor 无法验证自定义存储的所有者,它会使日志保持不可用状态,并将该路径报告为失败的 agent-deletion-journal 检查项。解决保留问题后,请重新运行 Doctor。

无效配置同样会使日志不可用:在 Doctor 能够验证所配置的所有权路径之前,它无法记录完整的恢复清单。请先修复配置,然后重新运行 openclaw doctor --fix,以便在重建之前发现并保留外部存储。

由 2026.7.35 写入的完整历史共享模式早于删除日志出现。Doctor 能够识别该模式,并在共享模式迁移期间、于同一轮迁移中迁移代理数据库之前初始化日志。这不适用于缺少日志的现代数据库,也不适用于已记录的恢复保留。当删除历史恢复使存储保持未验证状态时,显式修复会以非零状态退出;失败的检查项会指明原因和恢复步骤。

即使不再有新的迁移,或者你拒绝了另一次迁移,Doctor 也会报告被中断的认证配置文件归档恢复。如果恢复无法完成,其警告会包含失败原因,并保留待处理的恢复来源;不要为了消除警告而删除它。

doctor --fix 仅在其旧回执没有凭据指纹、当前规范存储中不再保留任何已迁移凭据,且已保留的归档仍与记录的源哈希匹配时,才会修复不一致的已完成认证迁移。Doctor 会通过正常的已验证迁移流程重新导入。带有指纹的已完成回执、仍存留的已迁移凭据或没有归档的情况均不会被改动;因此,在已验证迁移之后删除凭据不会从备份中恢复它们。

Doctor 还会弃用策略为空的 exec-approvals.json 存根(即 defaults 和 agents 均为空),包括没有版本号的存根,以及仅包含套接字元数据的存根。它会将原始字节归档为 exec-approvals.json.migrated.<sha256>.<unique-id>,记录弃用操作,并保持现有 SQLite 策略不变。当 SQLite 中没有 approvals 行时,Doctor 会导入任何非空的套接字路径或令牌,以便正在运行的 exec 主机保留其凭据。被中断的 .doctor-importing 存根使用相同的修复路径。未知字段、不支持的版本以及非空或格式错误的策略不会被当作空存根处理。

对于格式错误的遗留 exec-approvals.json,Doctor 会保留原始字节,并报告第一个验证问题,例如 agents entry #2.allowlist[1].lastUsedAt: expected a finite number。代理条目从 1 开始编号,按 JavaScript Object.keys 的顺序排列;允许列表索引从 0 开始。这可能与 JSON 文本顺序不同,尤其是在使用数字键时。要在本地定位第 2 个条目,请使用 Object.keys(JSON.parse(raw).agents)[1],其中 raw 是文件内容。诊断信息不会包含代理键和策略值,迁移回执也不包含诊断细节。JSON 语法错误和无效 UTF-8 会分别报告独立的错误原因。

请先在本地修复被保留的文件,然后使用相同的 OPENCLAW_STATE_DIR 设置重新运行 openclaw doctor --fix(如果之前未设置,则保持未设置)。在迁移成功之前,exec approvals 会一直保持阻断状态。在重新启动任何因该修复而停止的 Gateway 之前,只要遗留文件或被中断的 .doctor-importing 声明仍然存在,显式修复就会以非零状态退出。不要删除该文件,也不要扩大其策略范围以绕过验证。

代理数据库架构升级会连同数据库路径以及观察到的升级前和升级后版本一起报告,且独立于媒体重写。媒体持久化消息仅当转录会话或轨迹行被重写时出现,并包含两个计数。同时执行两者的运行会报告两者;未发生变化的重新运行则两者都不报告。

Doctor 在媒体/架构迁移步骤之前解析已配置的代理数据库和自定义会话存储。该前置步骤在 auth-profile 导入、会话修复以及会话后插件修复之前运行,包括预检检查了一个尚未注册的自定义存储的情况。

媒体修复检测会在第一个需要修复的事件处停止。修复事务在提交前仍会验证每一条转录和轨迹行;任一存储中后续出现的无效 JSON 会回滚媒体更改。没有媒体修复的数据库仍会接受完整验证扫描,包括在导入或恢复之后。

规范 SQLite 转录归档缺失的文件副本会产生可恢复警告,其中包含总数以及每个数据库最多五个示例路径。媒体和历史转录迁移仍会完成,保留规范 SQLite 二进制大对象,并让已删除的副本保持缺失。这些警告不会阻止剩余的迁移步骤或数据库就绪状态。

Doctor 会在更新防护和准入检查之间共享其初始车队架构和所有权检查。数据库读取器使用有界工作线程池,包括为已关闭 WAL 数据库创建的私有快照,因此大规模车队不会在每次检查时为每个代理启动一个新进程。修复在报告完成前仍会验证生成的架构;只有成功恢复一个错放的副本,才会清除该副本的所有权拒绝。

Device Pair 的旧版 JSON 导入会在写入前检查命名空间容量。如果缺失的条目无法容纳,doctor 会发出警告并保持源不变。导入还会在报告完成并归档源之前,验证源键和已存在的目标键仍保留在 SQLite 中。保留警告会使源保持可用于检查和重试;不要删除它以消除警告,因为它可能包含 SQLite 未保留的状态。在重新运行 openclaw doctor --fix 之前解决容量问题。

Microsoft Teams 委托 OAuth 令牌仍从 msteams-delegated.json 迁移,该文件由受支持的六月版本写入。Doctor 在归档源之前验证导入的凭据,并保留一个不同的现有 SQLite 令牌。

Doctor 还会在共享 auth 仍使用旧版 agents/main/agent/openclaw-agent.sqlite 所有者时报告。openclaw doctor --fix 会将其 auth profile 和 runtime-state 行复制到 state/openclaw.sqlite,验证精确负载,删除源行,并且仅在事务成功后记录新的所有权。Auth 解析没有双读回退:迁移前旧数据库是完整的;迁移后共享状态数据库是完整的。一旦迁移完成,删除 main 不再危及车队凭据。

如果共享目标已包含所有具有相同凭据内容的旧版 profile,Doctor 会保留更丰富的目标并完成清理,包括空的旧版 profile 集合或较旧的行时间戳。凭据比较忽略 JSON 对象键顺序,但保留每个字段;它不会按时间戳选择凭据。不同的凭据、仅存在于源的 profile、格式错误的子集负载或不同的 runtime-state 行仍被视为冲突。Doctor 会列出冲突的 profile ID,以及它们的凭据是不同、格式错误还是缺失于目标。存储元数据和 runtime-state 冲突会分别报告;凭据值和任意元数据永远不会打印。

停止 OpenClaw 进程,并在本地协调之前备份警告中命名的两个数据库。对于每个不同的 profile,选择要保留的凭据,并使其完整条目在两个存储中一致;将仅存在于源的 profile 复制到目标中,而不替换无关的 profile。在指定记录中解决格式错误的负载或不同的存储元数据和运行时状态,然后重新运行 openclaw doctor --fix。不要删除任一数据库或迁移回执以消除冲突。待处理的迁移回执会在中断的清理过程中保留原始源摘要。迁移完成后,没有待处理迁移回执的 main-agent 行仍保持为普通的按代理覆盖。

对于已退役的 QMD 内存后端,包括配置重写和派生工作区清理,请参阅 从 QMD 迁移。

这包括位于 <state-dir>/mcp-oauth/*.json 下的已退役 MCP OAuth 文件。修复前停止 Gateway。Doctor 会将有效凭据导入 <state-dir>/state/openclaw.sqlite,当两个存储都存在时保留现有的规范 SQLite 会话,删除过时的已持久化 OAuth state 值,并使用其回执防止重新创建的陈旧文件使已注销的凭据复活。已退役的 .lock 辅助文件采用失败关闭策略:如果 Doctor 报告陈旧所有者,请验证没有较旧的 OpenClaw 进程正在运行,删除该辅助文件,然后重新运行 Doctor。

在显式修复(--fix、--repair 或 --yes)之后,Doctor 会在报告完成前验证现有已配置、默认布局和已注册数据库的运行时架构就绪状态,包括迁移在注册前失败的存储。被阻止的必需迁移会以非零状态退出;停止 Gateway 和其他 OpenClaw 进程,然后重新运行修复。无关的咨询警告,包括归档转录修复失败,不会使就绪数据库在此检查中失败。缺失的数据库不会由就绪检查创建。

Doctor 还会在每个已解析的代理工作区、活动沙箱工作区以及显式配置的 agents.defaults.workspace 根目录中发现已退役的设置状态和中断的迁移声明。即使显式多代理名册仅使用其子目录,也会包含该共享根目录。Doctor 会通过现有迁移导入 <workspace>/openclaw-workspace-state.json 和 <workspace>/.openclaw/workspace-state.json 两者;它不会将根目录分配给代理,也不会移动 persona 和 memory 文件。

修复以非零状态退出,而保留的旧版状态仍会阻塞代理轮次,即使其数据已到达 SQLite。Gateway 启动和实时配置候选项仅检查它们将使用的工作区的就绪状态,而不是未使用的默认根目录。未就绪的实时候选项会被拒绝,最后正常运行的运行时保持激活。停止 OpenClaw 进程,如果实时写入在持久化之前被拒绝,请保存预期的工作区路径,并保持保留文件在原位。重启前运行 openclaw doctor --fix。就绪检查永远不会导入或删除旧版状态。

待处理的插件迁移

当 Doctor 在更新或修复过程中运行时,请等待该命令完成,然后再遵循中间插件警告中的恢复建议。更新器可能会完成包收敛并在退出前再次运行 Doctor。

Doctor 可以在已安装插件的元数据确认其没有需要运行的状态迁移或检查后,完成仅安装暂缓,包括其通道被禁用或它不再有配置项的情况。这会保留插件的激活设置和已保存的配置。先前记录的状态迁移或检查义务仍要求插件完成它们。

如果已安装的插件仍未报告迁移完成,请运行 openclaw doctor --fix。如果无法完成迁移,请将剩余警告报告给插件维护者。仅重复包更新并不能证明插件已迁移其保留状态。在迁移负责人报告完成之前,请保留保留状态和配置输入。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw