Repository navigation
fix(backup): retain declared Goal documents and lifecycle journals - #6662
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
需要保留完整工作背景的用户,在导出全状态备份时会遇到这项遗漏。旧实现能保存 registry 引用,却漏掉常规状态目录之外的已声明文档和外置 registry 相邻的生命周期日志;原来源丢失后,引用仍在,原文字节已经无法取回。本 PR 让发现时选中的本地文档和三类按 Goal 隔离的日志进入归档;File、SQLite 的真实失源验证均能读回原字节。这次不恢复执行身份、不重放日志、不开放激活,也不把最佳努力备份升级为一致性快照。完整 M2 仍缺所有必要 owner 的导出、独立捕获区间及依赖绑定;M3 的身份与 effect 处置继续开放。
改动思路
遗漏发生在现有备份的文件发现层;复用材料权限解析与真实 writer 的路径 owner 就能修复,不需要新 provider、控制开关或平行决策源。当前 PR 关闭发现时可定位的原始字节遗漏;完整快照和身份采用仍由既有 M2/M3 验收承接。完整备份仍从原 backup-state 入口进入,以真实 source-owned Goal 解析本地材料;文档只沿现有 repo/state/runtime 权限根解析,生命周期目录按既有 Goal 哈希定位。有效来源进入原归档见证流程,越界或缺失文档进入 missing 清单,源解析失败不回退到缓存声明。恢复依旧是历史审计,不执行日志。
| 情况 | 原实现 | 当前准确 head |
|---|---|---|
| 常规状态目录之外的已声明本地文档 | 保存引用但漏字节 | 保存发现时选中文档的原字节 |
| 外置 registry 相邻三类 Goal 日志 | 没有独立发现 | 按原 writer 路径 owner 保存 |
| 哈希引用、其他 Goal 日志、正文链接 | 不授权额外抓取 | 保持该边界 |
| 规划后材料声明移动 | 不构成完整快照 | 仍为未合格、held;本 PR 不把它变成 M2 |
这是根据代码与实测整理的对照表,不代表跨 owner 一致性证明。直接扫整仓库或整个 sibling 根会多抓私有来源;再建 exporter 框架又超出当前已知的文件遗漏。当前修复的边界更可审查和回退。
具体改动
准确 head:8921f1c50c6e7c1d52d753e93be1aa4e2bc8f417;base:b2aca67d76af45e554c620818a982a81f8d2d52b。共九个路径,生产代码五个、聚焦测试一个、参考/RFC 三个;未包含生成产物或私有记录。
规范:docs/architecture/rfcs/complete-state-recovery-v0.md,以 b2aca67d76af45e554c620818a982a81f8d2d52b 的既有验收为准。M1 保持 inert/held,由真实失源及 HTTP 负例验证;M2 的本地文档/三类日志遗漏已补,完整 owner export、独立区间和依赖绑定仍 deferred;M3 的受控身份与 effect 恢复 out_of_scope,未把修改后的 checkpoint 当作放宽验收的依据。
关键代码讲解
_discover_targets:沿原全局 source route 取得实际 Goal 和 runtime,再处理精确kind=goal_doc声明。它复用现有材料解析器;缺失或越界归入私有 missing,而 hash-only/未知 provider 不被解释成文件路径。三个日志目录也复用同一add归档见证路径,没有为恢复增加另一份执行逻辑。registration_journal_directory及相邻两个 helper:只归并现有路径公式,仍使用 registry 邻接根和原 Goal 哈希。注册与重建 writer 实际调用同一 owner,删除旧重复公式;没有迁移 journal 格式、operation 哈希或生命周期状态机。source_turn_effect_gate_path:gate 和 admissions 现在共同从turn_settlement_directory定位,移除旧_gate_root。返回路径和原准入、关闭、重放语义保持一致;真实 native lifetime/Host 与 migration scope 在不可变 base/head 各 57 项通过。
对主干的风险
没有发现阻塞此有界修复的问题。主要风险是把“保存了更多字节”误读成“完整恢复已经合格”,以及扩大私有备份内容。参考和双语 RFC 明确了这两点;原型没有新开权限、默认 provider、激活或重放入口。实际 File/SQLite 反例还确认:规划选中 INPUT 后,执行前声明改到 LATER,归档仍保存规划时的 INPUT,LATER 未捕获;审计保持 legacy_best_effort、held、activation=false、execution=false。这是现有 M2 区间/依赖工作的具体剩余缺口,不能用此次 source-loss 静态成功掩盖。
当前验证包括:138 项受影响 Python 回归、最终保留模块 16 项、57 项准确 base/head 原生和 migration scope 对照、28 项 TS owner 测试,以及普通 wheel 安装后仓库外运行的 17 项真实入口用例。后者覆盖源丢失、HTTP 上传/验证/重读、重复目标和损坏归档拒绝;不是新的已安装 Desktop 或 Lark 资格。首次打包因本地 bundle 陈旧被拒绝,按标准流程重建后 wheel 和安装态通过。reviewer 临时 probe 的路径别名/导入环境错误只修正 harness,没有修改产品规则。
语义与 CI 对齐
复用既有材料权限、source route 和 TS 生命周期/recovery owner,无新增共享状态词表;diff advisory 与全树 semantic smoke 通过。新 manifest key 只描述原始来源清单,不声称 journal 有效性。Ruff、配置 mypy17、5 direct/11 selected 的 Goal-bound canary 和准确 CQR cqr_04172a9bc5a98946bc7e 通过,九个公共路径扫描 clean。原始 DSH maintainability 检查仍失败在未改动的 _run_dsh_operation_host(93 statements/51 decision points);独立不可变 base/head 完整报告除工作目录外相同,未增加预算或豁免。此项保留为 inherited advisory。按本次 review packet,未查询或等待远端 CI。
我的整体评价
对整个 PR 的判断是 justified_increment:long_horizon=improved,原始要求和历史日志在失源后可供后续工作读取;user_experience=improved,沿原备份/审计旅程修复遗漏,新增强制交互轮次为零。原生命周期路径在 base/head 对照中保持一致,完整备份多出的原始字节属于已披露的 intentional change;单次归档不被认证为完整 M2 快照。
有界重构已经应用:真实 writer 与备份共享路径知识,没有新建平行决策源或无调用框架。代码量与已复现的数据遗漏相称,持久 journal/归档兼容保持。当前剩余完整 owner export、材料/provider 内容、独立区间/依赖及 M3 仍归原 RFC 工作,不能由此批准资格化、身份采用或维护者合并。此为作者账号上的公开自评,不替代独立审批或合并授权。
English verdict: APPROVE - 8921f1c; the bounded source-retention repair reuses existing material and lifecycle path owners. Real File/SQLite source-loss, immutable base/head native parity and installed-wheel CLI/HTTP validation passed; complete M2/M3 capture/adoption remains unqualified and held.
Goal and delivered outcome
Full backups copy an external source registry but omit its adjacent Goal-scoped lifecycle journals. They also omit declared local Goal documents outside conventional state directories. A backup can therefore retain the reference while losing the original requirement or journal bytes.
This repair retains local
authority_sourcesentries withkind=goal_docthrough the existing repo/state/runtime material boundary, and the selected Goal's existing registration, recreation and Turn-settlement directories through shared lifecycle path helpers. Global discovery reads the source-owned Goal rather than cached material declarations. Missing or out-of-scope documents are reported; absent lifecycle state is not initialized.Before → after: the public File/SQLite producer omitted a source-owned document on the unchanged base. The same producer now retains its exact Unicode bytes and all three journal directories; after removing the original sources, inert verification still reads the captured work and leaves activation and execution disabled.
Base:
mainatb2aca67d76af45e554c620818a982a81f8d2d52b. Related: #6637 (configuration-source witness agreement), #6628 (captured authority-position readback; independently scoped).Author declaration and specification
Written by: model_agent, Codex / OpenAI GPT-6.
Implemented against
docs/architecture/rfcs/complete-state-recovery-v0.mdand its Chinese counterpart at the base revision: M2 required-owner inventory, plus the existing M1 inert boundary. The roadmap owner is R5/T4.kind=goal_docentriesstate_backup.py; routed source versus cached row, missing/outside/escaping-link/directory negativessource_session_registry_state.pyhelpers reused by real registration, recreation and Turn-effect callers; native owner regressionlegacy_best_effort,held, activation false and execution falsesource_session_v1readScope and continuation
This is a complete source-retention repair and an independently reversible step toward M2. The remaining complete-owner exports, dependency/revision binding and M3 identity/effect recovery stay in the existing RFC work, without a second provider or new profile. Hash-only material registrations and document body links do not authorize additional discovery. Full archives may now contain additional private bytes; the bounded migration backup is unchanged.
The bounded refactor removes duplicated lifecycle directory formulas. Python owns filesystem routing/copy IO; the existing TypeScript lifecycle and recovery decision owners remain unchanged. No frontend, Lark, CLI option or first-screen presentation changes.
Validation
Tested product revision:
8921f1c50c6e7c1d52d753e93be1aa4e2bc8f417. Run state: finished. Inputs: synthetic and public fixtures, disposable File and SQLite stores.cqr_04172a9bc5a98946bc7evalidThe raw DSH maintainability validator still fails on the unchanged oversized
_run_dsh_operation_host. Independent immutable base/head runs produce identical complete reports after excluding only the checkout root; the native canary attributes it as inherited advisory. No exception, threshold or budget was changed. The first wheel build rejected a stale local frontend bundle; the standard bundle rebuild followed by wheel build and installed tests passed.This is installed-wheel CLI/HTTP evidence, not a new installed Desktop, Lark, PostgreSQL or full cross-owner recovery qualification. No remote CI result is claimed. No benchmark jobs or live Goal mutations were used.
Frontend / visual evidence
UI impact: none. Existing recovery upload/audit/readback HTTP entrypoints were exercised from the candidate wheel, including failure recovery. No UI source or first viewport changes, so visual before/after evidence is not applicable.
Boundary