Skip to content

fix(chat): continue explicitly unfinished project work once - #7399

Merged
loopx-agent merged 1 commit into
mainfrom
codex/native-incomplete-work-recovery-20261026
Oct 26, 2026
Merged

loopx-agent merged 1 commit into
mainfrom
codex/native-incomplete-work-recovery-20261026

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

A completed model Turn can still leave an original private-project request unfinished. The reply worker currently has no typed way to distinguish that case from completed business work.

Add an optional bounded unfinished_work report and one continuation through the existing original Session queue. Core requires independent stable full-native readback, the unchanged original source and workspace grant, an idle Session and a 60-second backoff. Dispatch checks freshness again, and newer input takes precedence. Crash recovery adopts the same reserved Turn; a failed or still-incomplete continuation cannot fall through to another business/routing/quota retry.

Earlier Turns and partial replies remain immutable. Legacy prose, unknown effects, stops, gates, delegated work, groups, stewards, attached hosts and attachment-bearing requests do not gain continuation eligibility. No additional message consumer or wider grant is introduced.

Validation: 51 focused Python cases at the final head, 307 Chat/project regressions before the behavior-preserving owner extraction, 574 existing native/routing/steward regressions, and the full TypeScript control-plane suite (5,520 passed; 75 skipped). Lint, type checks, bilingual RFC checks and the standard premerge gate (6 direct checks plus 11 selected checks) passed. Native/model/provider journeys use disposable synthetic fixtures, including original-source delivery and real HTTP App readback; they do not prove live-model behavior or completion of historical requests.

The initial premerge run correctly rejected runtime-module growth. Moving dispatch preparation into the existing external-conversation owner fixes that limit without raising its baseline. Installed activation and a natural live continuation remain separate acceptance steps.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

动机

使用普通私有项目助手、已授权其完成原工作区任务的用户,会遇到模型结束一轮回答但仍留下未完成工作的情况。
例如助手已保留第一阶段产物,却因临时来源故障返回部分结果;旧版不会继续这个已结束的模型轮次,新版可在独立核验后沿原会话完成剩余一步。
一次性原生模型协议与消息提供方夹具中,原产物只写一次,剩余产物随后补齐,旧回复不变,新结果送回原来源并能经 App HTTP 接口读回。
本次不回放旧的无结构化标记部分答复,不代替接收 Agent 执行业务,也不扩大工作区权限或建立另一套消息服务。
真实模型能否稳定生成这份报告、自然生产消息的续办送达及整个会话 SLA,仍需安装后沿原 Bot 独立验收。

改动思路

保留现有 Core 决策、外部会话 journal 和原 Session 队列的职责;新增报告表达不可从模型终态推导的剩余意图,原生 IO 只提供观察,不产生授权。
本 PR 交付显式未完报告到一次原来源续办和独立结果读回的完整路径;历史无标记请求、真实模型采用和部署验收留在现有 Bot 维护职责内。

不修改既有“失败且无执行效果”的路由恢复,也不把中断后的只读检查升级成写入。原来源 scanner 仍是唯一消费者,Core 只给同一请求预留一个 work-1;原生适配器证明观察,原队列负责实际执行,原结果阶段负责送达。正常路径复用已知授权,用户无需重复输入或额外确认;60 秒等待与一次上限限制成本,仍未完成时如实保留。

原请求状态 本次行为
完成回答、无显式剩余报告 保留原结果,不新建续办
显式剩余报告且来源、grant、完整原生库存一致 原队列最多执行一次剩余工作
发现后续输入、停止、未知效果或撤销授权 保留记录并停止该续办
续办失败或仍未完成 保留未闭状态,不落入另一次路由/额度重试

具体改动

评审依据是修改前的 docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,固定版本 cdbdc14ea3963e6f6aec4d574a1b88baff965132,而不是用本 PR 新写的规则证明自己。该规范没有逐段编号,下列 criterion_id 是对原有段落的定位标签:

  • source-faithful-admission:原 App、本人、消息和 grant 的复核仍由同一受保护入口执行;来源修改、撤销、停止都不继续。
  • stable-native-inventory:适配器分页读全原生轮次及 item,核对最新、稳定、效果终态与后台工作;派发时再读,排队的新输入优先。
  • immutable-delivery-and-restart:预留先于 enqueue,丢失确认采用确定性原 client;旧 Turn 字节和旧已验证回复不变,新结果使用独立阶段。
  • qualification-boundary:测试使用一次性模型/provider,明确不把夹具通过当真实模型、历史请求或完整 SLA 已完成。

上述四项均在本 head 实现并有对应正反例。原规范关于已完成回答不触发“路由故障恢复”的约束继续有效;显式剩余工作是这里另行说明的有界分支,旧自然语言答复不被重新解释。

关键代码讲解

  1. normalize_agent_response 只保留精确三字段、文本长度受限、effects_settled 为真的报告;已有 gate、受保护操作、handoff 或 proposals 时拒绝该意图,并复用现有路径脱敏。正常回答不新增必填字段。真实 _turn_prompt 在模型输入中说明生产条件及禁止把报告当权限,模型实际采用率仍未声称验证。
  2. completed_work_readback 读取完整最新 Turn 与 item 两次,要求一个原用户输入、一个最终回答、效果 item 全部结束、没有后台任务;未知 item、后续轮次、失败/拒绝/活动效果均不提供证明。它只有控制读取,没有创建新原生会话或模型执行。
  3. planUnfinishedWork 复用原请求身份、来源和队列规则,检查 60 秒、空闲状态与匹配的独立证明;重启仅采用精确已入队请求。已用过的 work_attempt 不能再落入 routing/quota 分支,防止失败后无界续办。
  4. prepare_continuation_input 在实际派发前重读库存并检查新排队输入。只对受保护的预留附加“保留既有产物、只做剩余工作”的模型输入,不改保存的原消息。普通项目未配置外部绑定时,运行时保持既有路径。

差异共 198 行生产新增、7 行删除;281 行验证、54 行双语 RFC。最大新增机制均留在既有 owner,没有新 daemon、CLI、业务执行副本或第二状态源。检查过相同源对象的失败恢复、只读恢复、presentation_phase 和 Session 队列,选择扩展其清楚的语义分支,而非重写它们。

对主干的风险

最强反例是“预留已持久化,但随后来了新指令或原生历史变化”。公开入口用例在 crash-after-enqueue 后引入这两种状态,证明旧续办没有启动模型,新指令得到处理,第一阶段效果没有重做。来源被改、grant 撤销、停止、未知/活动库存、仍未完成和两处崩溃边界也均保留原始结果。原生工具 completed 不是第三方业务幂等性的证明,因此报告必须要求已知结果,模型必须先检查产物,不能把该路径宣传为所有外部效果 exactly-once。

最终 head 的 51 项定向 Python、相同基线/新版的 11 项普通项目会话、标准 premerge 的 6 项直接检查及 11 项选定检查、lint 和类型检查通过。相同原来源新用例在基线确实因报告缺失失败,在 head 通过。较早的 307 项 Chat/project、574 项原生/路由/管家回归及 5520 项 TypeScript 通过记录保留;TypeScript 的 75 个既有 skip 不冒充覆盖。实际 native/Core/store/queue/transport/HTTP 路径运行,模型和 provider 是合成边界,未声称真实宿主崩溃或自然消息已验证。未查询、轮询或等待 CI。

语义与 CI 对齐

这是已有回复与恢复契约的可选字段扩展,非新的权限、Goal 或调度义务。旧字段、省略字段、原错误处理和持久记录继续可读;unfinished_work 不能从 prose 推导。报告生产指导是有意的默认提示变化,已经公开说明,不能错误宣称它被某个 default-off 开关完全隔离。语义 drift 检查通过,但有限语法扫描没有发现新 vocabulary carrier 也不等于没有语义变化。初次体积检查真实失败已保留;把派发准备移到原 owner 后同一检查通过,没有提高 ceiling、删断言或放松阈值。

我的整体评价

结论为 APPROVE,交付判断为 justified_increment。long_horizon 与 user_experience 在已验证的原来源路径上 improved:已授权意图不需要用户重述,剩余工作有一次有界机会,失败和新输入仍保持可见与优先级。保留现有 Core 决策、外部会话 journal 和原 Session 队列的职责;新增报告表达不可从模型终态推导的剩余意图,原生 IO 只提供观察,不产生授权。 本 PR 交付显式未完报告到一次原来源续办和独立结果读回的完整路径;历史无标记请求、真实模型采用和部署验收留在现有 Bot 维护职责内。

未修改渲染组件或布局;已检查 App 会话 HTTP 读回和原来源回复路径,因此本次无需新增页面截图。 未验证真实模型报告采用率、自然生产消息续办及安装后运行表现。

这个边界可独立评审和回滚,兼容保留来自真实持久历史需要;不增加另一层兼容 decoder。安装采用与自然生产验收仍独立推进,未闭业务继续归原 Bot/接收者,评审通过不等于该业务已完成或已获得新的合并权限。审查的是 bacb4d1355e702462e8645bf0fe533c8624e1eaa;发布前再次读回相同远端 head。

English verdict: APPROVE bacb4d1. The existing source worker gains one bounded, independently checked unfinished-work continuation without replaying earlier effects or overriding newer input. Current-head positive/negative journeys, baseline parity and standard premerge pass. Synthetic provider/model coverage does not certify live-model adoption or historical business completion.

@loopx-agent
loopx-agent merged commit 15803cd into main Oct 26, 2026
25 of 31 checks passed
@loopx-agent
loopx-agent deleted the codex/native-incomplete-work-recovery-20261026 branch October 26, 2026 14:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant