Repository navigation
fix(report): recover cancellation of failed managed Session windows - #7279
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 (Codex); OpenAI; self_reported (exact host build unavailable).
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
在 Goal 设置维护普通 managed Agent 会话周期报告的用户。
已知无效报告失败后,原先连清除订阅都被拒绝;现在清除预览不会执行,应用并读回成功后仅退休该失败窗口。
保留旧 Task、Turn、正文证据和未发布状态,让后续独立周期恢复执行。
本次不增加自然语言任务入口、任意任务 profile、调度器或消息消费者,也不宣称生产自然到期送达。
通用任务自然语言配置和完整 Agent 页面层级仍由现有周期任务工作继续验收。
这里的“退休”表示停止把这一失败窗口继续当作待执行工作,保留原失败和证据,不等于报告成功或已经送达。两种原生存储的同输入 HTTP 对照均复现了旧版拒绝清除、修复版可以清除;取消之后的独立周期也完成了原会话全文读回。因此这是一项可独立使用的恢复修复,而不是用测试数量替代通用周期任务的整体完成。
改动思路
复用现有配置事务、原生 Task 与窗口退休,不新增同步状态或并行执行者;留在既有 Python Chat/HTTP 效果适配层。
本 PR 完整交付已知失败窗口的取消与中断恢复,其他通用周期任务能力继续沿现有工作推进。
入口继续是 Goal 配置的预览与应用。预览只读当前配置和冻结窗口;真正写入后,HTTP owner 先独立读回配置,再执行取消收尾,最后才向调用者返回成功。Task 的阻塞由现有原生命令处理,窗口由既有 journal 写入已有 retirement,不新设任务库、状态同步器、版本协议或模型执行者。取消和源码读取都留在现有 Python 效果适配器;共享控制面和 typed actor 准入仍用原 owner。
| 情形 | 旧版 | 此版本 |
|---|---|---|
| 明确失败、无生成及发送效果,清除订阅 | HTTP 400,旧窗口继续阻塞 | 预览 201;验证应用后 200,仅退休原失败 |
| 相同计划暂停、恢复 | 允许,保留原窗口 | 同样允许,保留原窗口 |
| 已生成报告或发送效果未知 | 拒绝清除 | 继续拒绝;不盲重放 |
| 清除在配置或 Task 写入后中断 | 不能完成取消 | 重试同一清除,恢复原身份及剩余退休步骤 |
此表为已执行对照的说明,不作为独立执行证据。直接绕过 frozen guard 虽然更短,却会遗弃生成或未知发送;另建取消服务则复制已有原生职责。本方案复用旧私聊取消路径并删除其内联重复逻辑,代价与实际堵塞相称。
具体改动
审查范围是完整基线 35031332795ee7417f56f6a7582e09cc3a75458a 到精确 head 159ac85fdd1344735fab4fdbe1d2fce60b557a5e 的8个文件:3个运行时适配文件、既有测试文件、产品说明和3张合成截图。没有新增生产模块或修改前端布局。
独立验收依据是 docs/reference/protocols/periodic-report-v0.md,spec_revision 为 35031332795ee7417f56f6a7582e09cc3a75458a。逐项对应如下:
- Optional daily or weekly calendar:沿用 revision 预览、应用和原窗口保留;明确取消只记录退休,冻结文件和历史不删除,未来计划可以重新配置。
- Split phase contract:生成、原生提交和投递继续分开;取消没有创建 publication cursor,也没有发送或把失败 Task 记成 done。
- State and retry semantics:未知效果保持拒绝;部分取消只补同一原操作,旧周期不重放,下一独立周期可正常产生新 Task 和完整返回。
关键代码讲解
session_report_configuration_guard用同一 cadence fence 串起配置和冻结窗口;除了已证明的失败清除,其余改变计划的保护仍在。配置已移除后的重试从原冻结对象找回 actor,并在收尾前重新核验。_send_applied_goal_configuration在独立配置读回成功后、HTTP 成功响应之前调用可选内部回调。预览、过期 plan、写入失败、读回失败均不执行退休,其他能力的事务没有该回调。_cancel_failed_window复用原私聊的 native Task 更新与稳定操作身份;重新确认原报告的 work kind、订阅 revision、actor 与明确终态,防止借用别的任务。_retire_failed_cadence_window_locked复用既有退休写入,而不是在持锁期间递归抢同一锁;冲突窗口、已发布状态和不匹配的原回执仍拒绝。_frozen_actor将既有原会话、窗口及 request digest 校验合并供投递与取消恢复使用;读取结果不授予新的 Goal、Agent 或外部权限。
对主干的风险
最强的恢复反例是配置已经清掉,但窗口退休尚未完成。File/SQLite 分别注入了配置清除后、原 Task 阻塞后的中断;同一取消重试完成剩余步骤,原 Turn、冻结文件和消息逐字保留,旧周期没有模型重放,后续独立周期完成并读回完整报告。另5项 HTTP 次序检查覆盖预览、stale plan、写入/读回失败和成功响应之前的收尾。
同一个真实 HTTP harness 在不可变基线与 head 运行,3个变化模块取自各自 Git 版本,其他生产模块相同;File/SQLite/Core/HTTP 和取消后置条件不做模拟,模型及 Lark transport 为合成。基线的期望取消 oracle 失败,head 通过;相同计划暂停/恢复和未知效果拒绝在两版保持一致,同 Goal 的普通 Task 保持 open。这限制了 gate 的覆盖范围,避免为了修过度拦截而放过另一方向的错误。
最终147项相关回归通过,零跳过。预合并6项直接与14项选择检查均通过;原始结果中的3项图片人工门保留原状,由本次对精确图片 blob 的像素、ICC 元数据和合成来源检查消除人工待审,没有把它们伪装成自动检查。第一次扩充的预览测试误带 apply-only revision,被正确拒绝;修正用例后5项通过。第一次配对 harness 缺少测试导入路径,在启动 fixture 前失败;修正后才进行了上述同输入比较。早期138项结果不代替最终147项。没有查询、轮询或等待远端 CI。
语义与 CI 对齐
本改动复用既有 native status、work kind 和 retirement vocabulary,不新增 Enum、schema 或共享策略。diff 语义 advisory 未发现支持范围内的新词汇,这不是语义安全的自动证明。报告专用判断和错误仍在报告适配器;没有给通用 quota、work lane 或模型提示注入报告义务。配置和原身份检查属于真实执行门,文档没有把它们称为可忽略建议。
我的整体评价
APPROVE,属于 justified_increment。 long_horizon 为 improved:失败记录被保留,同时后续独立工作不再被永久卡住;user_experience 为 improved:既有清除操作可完成取消,不新增人工授权轮次或重填已知身份。
已检查完整设置页、失败状态、清除预览和清除后的默认值,16项能力导航与主要配置、错误和操作可共同理解;未改布局或折叠规则。
未验收真实模型报告质量、自然生产到期或物理手机;这些不构成本次取消修复的完成声明。
复用现有配置事务、原生 Task 与窗口退休,不新增同步状态或并行执行者;留在既有 Python Chat/HTTP 效果适配层。
本 PR 完整交付已知失败窗口的取消与中断恢复,其他通用周期任务能力继续沿现有工作推进。
三张图片已经逐一检查;它们使用未改动的既有打包前端,最后的原 actor 再核验还通过了精确 head 的独立 HTTP/真实 SQLite 浏览器路径。桌面前后尺寸分别为1440×1000及1200×888,窄屏为390×844模拟,截图不能证明安装、真实模型质量或生产自然到期。原生 Task 和 publication 的真实性另由上述运行与读回确认。当前边界的主要剩余风险是原身份或未知效果不能核实,这时继续保留拒绝,交回原 owner 恢复;它不是要求使用者再次批准同一已授权动作。
English verdict: APPROVE — exact head 159ac85fdd1344735fab4fdbe1d2fce60b557a5e. The existing settings transaction can retire a proven failed managed-Session report without changing original failure history or publishing it. Real File/SQLite HTTP base/head comparisons, 147 regressions, 6 direct plus 14 selected premerge checks and packaged SQLite readback support this bounded slice; natural production deadlines and broader recurring-task authoring are not claimed. Author-owned approval conclusion; merge authority and exact-head readiness remain separate.
A managed Agent Session's known invalid calendar report could prevent clearing its subscription forever. The existing Goal settings preview/apply now retires that proven failed window after configuration readback, preserving its Task, frozen artifacts, costs, original Turn and unpublished cursor. A later independent period can run without replaying the failed attempt.
The Session adapter and private steward reuse the existing cancellation transition. Interrupted clears recover the original frozen actor and stable cancellation operation; previews, failed/stale applies, generated reports and unknown delivery effects retain their safeguards. This adds no scheduler, consumer, profile or permission grant.
Validation: File/SQLite cancellation and interrupted-recovery cases passed (9 focused checks), as did the five HTTP transaction ordering cases. All 147 report/Lark/configuration/journal regressions passed at this head. Premerge passed all 6 direct and 14 selected checks; its three binary-image review holds were resolved by pixel, metadata and synthetic-source inspection. The same public HTTP harness on immutable base and head reproduces refusal on both File/SQLite at base and successful retirement at head; same-plan pause/resume and unknown-effect refusal remain unchanged. Packaged settings were exercised with real disposable SQLite/Core and synthetic model/provider transport: one invalid generation, no extra model call or send during clear, retained history/artifacts, and a subsequent future plan accepted. This is scoped cancellation delivery; natural-language authoring and arbitrary recurring profiles remain separate work.
Visual evidence uses synthetic data and the existing packaged frontend. Desktop captures are 1440×1000 before and 1200×888 after; the narrow capture is 390×844 viewport emulation.