Repository navigation
fix(storage): recover original team plans during a writer hold - #6360
loopx-agent wants to merge 1 commit into
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; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=xhigh
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
确认团队工作安排后丢失响应、随后遇到存储初始化暂停的 Chat 操作人员。 旧版把原已提交安排的重试当成新写入检查,初始化暂停便使确认一直失败;当前先校验原回执,返回原 Todo ID,同时保留后来写入的数据。 真实中断初始化后,原 Chat 确认恢复成功;重启后的同一确认返回相同回执,新安排仍被拒绝。 本次不启动 2.0 writer cutoff,不删除活动 writer,也不证明真实外部 Agent 接收、模型执行、PostgreSQL 或长期存储资格。
改动思路
保留 TypeScript 原身份与规划权威,Python 只在既有锁内读取回执和检查持久性;共享三项新写入检查避免第二套规则。 当前 PR 只修复 1.x team-plan 原操作的恢复顺序,canonical 事务、投影及新写入规则保持既有 owner。 不做修复会让已经产生的工作安排因独立的初始化暂停而无法回读;移除暂停检查则会错误允许新的写入。本次选择现有回执恢复边界:在 registry、Todo 和 source 的既有互斥锁内读原结果,原身份校验仍在 TypeScript。历史结果不代表当前执行许可,source 的现有持久性检查也没有省略。
具体改动
完整评审 31c52f534743754896d8c77af3316e6671ddb522,实际 fork 60d833b13c85135587b725013b247e827663ffb9,5 文件 +177/-26。规范依据 docs/architecture/rfcs/typescript-control-plane-migration-v0.md @ 60d833b13c85135587b725013b247e827663ffb9,按改动前的 T4 历史读取/最后 caller 退役边界及 6 correctness 崩溃重试验收判断;两项在当前有界路径 implemented。当前 RFC 新增说明作为披露审查,不能替代原验收,也没有关闭整个 R5/T4。
关键代码讲解
apply_team_plan:promoted 路径保留原 AuthorityStore。legacy 路径持有原三把锁、重新检查 registry/source binding,再解析已有回执;回执存在时再次读取 promoted 状态,调用原 typed planner,并验证 source 持久性后返回原结果。没有回执才进入 fresh write 检查、capture 与原子文档写入。require_legacy_todo_write_allowed:把既有 registry source、shadow management 和 promotion 三个检查提取为共享函数,原 transaction 与 team-plan 共用同一顺序。没有新增 Python 策略源或默认开关。replayTeamTransaction:未修改的 TS owner 逐项校验原操作、请求摘要、lane/Todo/actor/验收身份。更改意图、执行者或 reviewed basis 不能变成恢复;历史回执也不会重建后来编辑或退役的工作。- 公共测试在真实 TS bootstrap prepared barrier 杀掉子进程,验证原 Chat 恢复、后来数据保留、capture producer 物理移除及身份/新写入拒绝。registry census 仅更新移动的行号;RFC 明确当前 1.x 修复不激活 2.0 cutoff。
对主干的风险
我的完整相关 Python 验证 107 passed;同一 producer-present 真实中断场景在冻结 base 的恢复断言失败、当前通过,排除了仅由移除旧 producer 导致的差异。当前 producer-absent 独立进程也能恢复。正常 wheel 安装在独立 Python 环境,三个关键 owner 字节与 head 相同;真实 Chat HTTP 提供打包页面,原确认恢复、服务器重启后的同一回执,以及新安排拒绝通过,所有 source 与 pending management 字节保持。这里是合成当地工作安排与真实 IO,未冒充外部人员接单或模型执行。
typed team-plan/fence 33 项通过,6 个未配置 PostgreSQL 的旧 provider 用例明确跳过。canonical/PG 事务源码未修改,本次不声称 PG 资格。5 direct、18 风险选择检查、semantic/census/public-boundary/Ruff 全通过。初始测试路径错误、过期前端构建产物和安装探针调用方式错误保留为 setup 失败;正常 rebuild、wheel 与实际 CLI 恢复后再验证,没有放宽断言。没有查询或等待 CI。
语义与 CI 对齐
本次复用 existing vocabulary,新增 helper 留在原 writer-fence owner;advisory 后完整语义与 registry I/O census 通过。历史回读与新写入义务分开披露,未把机器拒绝称作建议。没有新配置、额度、投影或 source authority 默认;promoted provider 不可用的竞态仍明确拒绝,不能退回 Markdown 权威。
我的整体评价
APPROVE。long_horizon 和 user_experience 均 improved:操作人员用原确认拿回已提交结果,不需重输已知安排,也不会重复创建工作。保留 TypeScript 原身份与规划权威,Python 只在既有锁内读取回执和检查持久性;共享三项新写入检查避免第二套规则。 当前 PR 只修复 1.x team-plan 原操作的恢复顺序,canonical 事务、投影及新写入规则保持既有 owner。 相邻前瞻整理已应用共享三检查,进一步 cutoff 仍按最后实际 caller 与原恢复义务成组交付,不为此修复新增恢复框架。保留 live Host/Lark、完整 2.0 退役、长期 trial 和 PG 等未测边界;这份批准只绑定当前 head,不授予合并或全局安装权限。
English verdict: APPROVE - 31c52f5. Original team-plan confirmation recovers during an interrupted writer bootstrap without admitting fresh work. Independent 107 Python cases, paired baseline/head crash recovery, installed normal-wheel HTTP recovery/restart/refusal and 33 typed cases pass; six unchanged PG cases remain skipped. Whole T4 retirement and live adoption are outside this repair.
A team plan can publish its Todo batch and receipt, lose the response, then become unrecoverable when shadow bootstrap is interrupted: the retry enters fresh-write admission before reading its original receipt. This PR recovers the original result under the same registry/Todo/source locks, using the existing TypeScript identity validator and source durability check. New plans still pass the unchanged source, management and promotion checks. A promotion racing the initial observation cannot turn an unavailable selected provider into a Markdown fallback.
This is the existing R5/T4 recovery prerequisite discussed in #6359. It is compatible with the current 1.x write path; it does not activate the proposed 2.0 cutoff or retire active writers. The RFC checkpoint records that boundary. Future-facing refactor: extract the existing three write checks into one shared adapter function so delayed admission does not duplicate their policy. Python remains lock/filesystem transport; TypeScript keeps receipt identity and planning authority. No new configuration, protocol vocabulary or capability is introduced.
Validation:
loopx canary premerge --from-git-diffpasses, along with Ruff, semantic advisory, full-tree semantic validation and public-boundary scan. The first canary caught a moved registry I/O line coordinate; the regenerated census changes only that coordinate, and the final gate passes.No merge or global install performed. Exact-head independent review and maintainer merge authority remain required. Whole-program writer removal, Host adoption and long-duration storage qualification remain open.