Repository navigation
test(chat): cover authoritative Team Plan recovery - #5849
huangruiteng merged 1 commit into
Conversation
Signed-off-by: hyk <4408344+hhyykk@users.noreply.github.com>
hhyykk
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
运行 Release Artifacts 打包版个人工作区浏览器测试的维护者,原来在确认团队任务分配后,如果提交响应丢失,测试会等待“重试分配”;但服务端夹具已保存已应用且可核验的结果,界面按现有规则直接读回结果,因此测试超时,后续浏览器场景无法执行。现在同一场景核对已应用结果只提交一次;另以独立提案覆盖状态读取失败时禁止再次确认或重试,以及确有可安全重试的失败记录时恢复原提案。可观察的改进是这条真实打包版回归测试重新跑完,并能阻止未来把不确定响应误判为再次写入的许可。
本 PR 只修复现有测试夹具与场景,不改变产品运行时代码、写入权限或用户操作;它也不证明接收 Agent 已采纳或执行任务。尚存的边界是完整接收者采纳/执行与 Lark 交付不在此测试内,远端 CI 和维护者合并门槛另行读回。
改动思路
入口是既有 smoke:personal-workspace-packaged 中的 teamPlanScenario。打包版 Chat 界面仍由现有 TypeScript compileActionReviewPlan 决定原提案能否重试:已应用的核验回执是完成;只有身份、目标与计划一致且 retry_safe 的失败提案才出现“重试原操作”。浏览器夹具只模拟 HTTP 和写入计数,实际历史回执及相关 Todo 后续被修改后的重放由既有真实后端测试证明。
当前 PR 的边界是同一个 Team Plan 浏览器场景和其 HTTP 夹具内的三种独立读回结果,复用现有提案构造器与类型化准入,不新增产品决策源或通用存储层。保留该边界的理由是旧断言本身阻断打包版套件,而产品判定已在现有 owner 中正确;将已应用、读取失败和可安全重试的失败提案分开,才能既修复测试又避免夹具伪造授权。独立页面使三案的提案 ID 与计数互不污染;默认夹具标志关闭,其他场景走原路径。
具体改动
按变更前的 docs/architecture/rfcs/loopx-overall-roadmap-v0.md(版本 780c4a74ba8d6f231a6c6eca016447088b359cf3)核对:R1 的本地分配/重试检查点要求按原操作身份读回历史结果,不因接收者后续更改而重建;F4 要求丢失响应及失败重试不留下重复或部分写入。这两项在此 PR 中由打包版场景守护,真实持久行为由现有后端测试验证。R2/R3/R4 所属的执行资格、接收者采纳与共享意图仍在本次测试范围外,不能由一次分配回执宣称完成。
关键代码讲解
fixture.mjs的installApi中/api/actionsGET 分支(约第 1798 行)只在提交响应丢失后注入一次 503,使缓存预览不能代替权威读回;下一次手动读取可恢复已应用结果。- 同一夹具的 apply 分支(约第 1978–2023 行)保留原提案的摘要、计划、上下文和源指纹;独立的提交后失败返回后端形状的
failed/retry_safe记录,重放同一 ID 只增加 POST 计数,不增加模拟写入。 team-plan.mjs的managerTeamPlanProposal(约第 91 行)为独立案例设置提案 ID 和相互一致的 lane/gap ID,避免把另一个方案的回执当成原方案。teamPlanScenario.run(约第 262–379 行)分别验证已应用读回、GET 失败时抽屉显示未核验且没有“确认分配”或“重试原操作”,以及安全失败后同 ID 恢复原 Goal、两条已分配 lane 和一条缺口;刷新原会话也不会再次提交。
对主干的风险
主要风险是浏览器夹具自己制造了“正确”回执,使测试通过却掩盖真实存储的重复写入。这里的 durableResources 仅是模拟 Set,不能证明存储原子性;独立真实后端测试覆盖提交后响应丢失、相关 Todo 后续被修改以及原回执恢复(3 个参数通过)。另一风险是错误的否定断言检查不存在的按钮:本次实际检查界面的“重试原操作”,同时检查“确认分配”和未核验提示,正向失败案也必须出现并点击同一个按钮。已有静态抽屉 smoke 只查按钮类型,不能替代打包版 HTTP/状态读取交互;本次没有新增产品协议、默认开关或强制工作义务。
最终 HEAD 560c00951c0120c405da7334ef2eb853fd343071 的完整打包版运行通过 9 个前置脚本、48/48 个浏览器场景和 2 个收尾 smoke;源检验覆盖 454 个 Chat 输入与 20 个打包文件。预合并验证 3 个直接检查和 3 个选中检查通过,公开/私有边界扫描无命中。首次预合并运行缺少根目录 TypeScript 依赖,补齐后同一最终头通过;这不是产品失败。远端检查目前仍有排队项,合并就绪必须由维护者在检查完成后另判。
我的整体评价
APPROVE — PR #5849,精确头 560c00951c0120c405da7334ef2eb853fd343071。 这是一项完整且可回滚的测试修复:它让维护者持续运行打包版回归套件,并保护用户面对丢失响应时看到真实完成、明确未核验或同一失败提案的恢复入口;产品运行时和用户步骤保持不变。新增 174 行集中于既有两个验证文件,分别覆盖三种不同状态,未形成重复的产品 owner 或兼容协议。后续完整协作旅程及远端 CI 不由此测试或本次审核代替,且本结论不授予合并权限。
English verdict: APPROVE 5849@560c00951c0120c405da7334ef2eb853fd343071: applied readback forbids reapply, failed GET blocks cached confirmation/retry, and safe recovery retains the original proposal. Final packaged 9 scripts/48 scenarios/2 trailing smokes, 3 backend tests and premerge 3+3 checks passed. Remote CI and maintainer merge readiness remain pending.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · ultra
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent gpt-6.1-sol OpenAI runtime_reported xhigh
动机
维护者运行打包版个人工作区的团队分配回归测试。 提交响应丢失后,旧测试等待重试按钮而超时;新测试先读取已经保存的结果,并分别验证读取失败和可安全重试的失败提案。 完整打包版套件可以继续执行,并守护同一提案只产生一次分配、读取失败不授权再次提交、恢复保留原任务和未分配缺口。 本 PR 只修复现有验证夹具与场景,不改变产品运行时、授权或用户步骤,也不证明实际接收者执行或完整团队协作验收。
改动思路
产品的现有判定已经区分“已应用”“结果未核验”和“可以安全重试的失败提案”。因此最小修复应校正既有测试,而不是改变正确的产品行为。保留三个独立案例,复用原提案构造器和现有 compileActionReviewPlan;缓存预览始终不等于重试许可。当前 PR 的完整边界是同一打包版场景与 HTTP 夹具,未新增产品状态或通用存储层。
具体改动
评判依据为变更前 docs/architecture/rfcs/loopx-overall-roadmap-v0.md,规格版本 780c4a74ba8d6f231a6c6eca016447088b359cf3。R1 要求恢复不重复、不扩张工作,发起界面显示准确结果。本次守护其中的本地分配/恢复路径,不能据此结算整个 R1。
fixture.mjs / installApi:GET 一次性失败与提交后失败分开;保存原摘要、参数、上下文、指纹和创建时间,避免恢复时构造另一个提案。team-plan.mjs / managerTeamPlanProposal:独立 proposal/lane/gap ID 防止案例串扰;复用原构造器。teamPlanScenario:已应用读回只有一次 POST;GET 503 时无确认或重试按钮,恢复只重试读取;仅明确 retry-safe 的失败提案才重试同 ID,保留两条分配与一条缺口。刷新原会话不产生额外分配。
对主干的风险
完整两文件差异为 +174/-22,均为既有持久验证。最强反例是模拟 Set 自己制造正确结果:它只能证明 UI 请求身份和计数,不能证明存储原子性。本次独立执行了现有真实后端测试,包含 File/SQLite 和 legacy 路径、提交后读回失败、后续任务编辑与历史回执恢复,48 项通过且无跳过。
同一已验证的产品打包资产上,immutable base 780c4a74ba8d6f231a6c6eca016447088b359cf3 的原场景实际等待“重试分配”30 秒后失败;当前头 560c00951c0120c405da7334ef2eb853fd343071 完整运行通过 9 个前置脚本、48/48 浏览器场景和 2 个收尾团队 smoke。浏览器 HTTP 为模拟,真实产品资产和事件处理实际执行。源 canary premerge 的 3 个直接检查及 3 个选中检查通过,无失败或 manual hold;未查询、轮询或等待远端 CI。
验证中一次操作脚本使用了不存在的测试路径,因此运行零项;该失败保留,改用正确的两个现有文件得到上述 48 项真实结果,不把它算成产品缺陷或已通过的检查。
我的整体评价
APPROVE — 5849@560c00951c0120c405da7334ef2eb853fd343071。 未发现阻断项。这项修复对长期维护是正向的:去掉误报,恢复整套回归运行,并保留真正的不确定性与同一操作恢复防线。对用户体验保持现有行为:确认一次后读回结果,读取失败只恢复读取,安全失败复用原提案,无新增必经步骤。相关整理已复用提案构造器,无须引入另一个产品 owner;未来完整接收者执行、模型采用和整项协作验收保持未测。本结论不授予合并或启动权限。
English verdict: APPROVE 5849@560c00951c0120c405da7334ef2eb853fd343071. The obsolete baseline retry wait reproduces, while the exact head passes the complete packaged suite and 48 real backend tests. Applied readback avoids reapply; unavailable readback withholds cached confirmation; retry-safe failure preserves the original proposal and gap. HTTP remains simulated; no CI or full collaboration qualification is claimed.
The Release Artifacts packaged browser suite waits for an assignment retry after a lost Team Plan response, even though the fixture has already stored an applied receipt. After #5642, the shipped typed owner correctly reads that result instead, so the old assertion blocks the suite.
Update the existing Team Plan scenario to distinguish three caller outcomes: successful applied readback without another POST; failed authoritative GET with cached preview unable to enable confirm or retry, followed by readback recovery; and a separate backend-shaped retry-safe post-commit failure that retries the original proposal once without another simulated durable write. Keep proposal identity intact in the fixture and use separate pages for the two additional failure cases.
This changes two durable validation files. It adds no product behavior, provider, configuration or shared authority. The browser exercises packaged Chat assets with simulated HTTP; existing real backend tests separately prove original-receipt replay after later work changes. Assignment remains distinct from receiver adoption and execution.
Validation:
872e3f79a694827b9efac3a03e7400b581c0be51reproduced the obsolete retry wait.560c00951c0120c405da7334ef2eb853fd343071rebases the unchanged test diff onto780c4a74ba8d6f231a6c6eca016447088b359cf3and rebuilds Chat. The completenpm run smoke:personal-workspace-packagedpassed: 9 prerequisite scripts, 48/48 browser scenarios, and 2 trailing team smokes; no skips or unreached scenarios.canary premergepassed all 3 direct and 3 selected checks, including full semantic inventory/registry I/O, maintainability and public/private scan. Its initial setup-only TypeScript dependency failure was resolved with repository-rootnpm ci --ignore-scripts; the failed attempt is retained separately.Related refactor pass: reuse the existing manager proposal builder and preserve source identity; no production refactor or general fixture store is needed for this repair. The mock counter does not establish storage atomicity, and this PR does not close full R1 or the TS migration.