Skip to content

[P1] 建立可持久恢复的对话失败终态与兜底,保证错误可见且下一条消息可继续 #161

Closed

Description

@lyyzka

本轮验收范围更新(2026-10-20,依据用户 00:08 UTC 最新指示):继续完成基础能力、必要短测、审查及上线,并据实验收关闭;24 小时/更长 soak、完整负载、真实 provider 与全量 SPA 联合故障矩阵、供应商实际扣费凭证不作为本轮关闭前置条件,未完成项仍明确标为“未验证”,不会改写历史失败或计为通过。基础功能缺口仍须修复,不能仅修改文字关闭。

本 issue 的基础验收:失败/取消终态持久化、投递恢复、版本/lease fencing、授权和动作去重可工作;基础故障短测须验证有界恢复、无重复副作用及下一条消息可继续,不得把实际基础失败归为长测豁免。

本轮基础能力、必要短测、独立审查和生产上线已完成,依据最新范围验收关闭;交付 source 554e81ac / runtime3.5.6,详见下方2026-10-20完成回执。长期和完整矩阵未验证项保留为历史边界。2026-10-17 的“无需部署/停止生产操作”描述已被本次最新上线要求替代,下方原文与旧证据保留为历史记录。固定暂停的 3.5.3 soak 和已暂停自动核验保持不动;不做生产故障注入,不改凭据、安全设置或生产数据。

生产核查结论与计数口径

2026-10-16 对数据库、保留容器日志、已部署源码和已安装依赖进行了只读交叉核查。基线为镜像 9332947e099d27b7716236a99604fc548059f6ad / LingxiOS 3.4.7;不是当前本地未提交代码。

327 个历史 work:182 succeeded、90 failed、47 partial、2 blocked、6 cancelled。90 个 failed 都没有 resultId,其中 71 个前台 turn、19 个后台 memory work;47 partial 和 2 blocked 已有 committed result,说明既有部分结果兜底有效。最近 24 小时/当前发布后观察到的 5 个 work 均 succeeded,不能把历史总数当作今天新增事故。

failed work 主因 turn 后台 对应处理
共享模型预算耗尽 21 0 #157
context compaction / model context budget 20 + 1 0 #156
HTTP 402 10 9 #155
timeout 2 10 #155
control plane unreachable 9 0 #153 与本 issue
abandoned recovery limit 2 0 旧循环已有修复,本 issue 加回归
research evidence 初始快照不匹配 3 0 旧继承快照问题已有修复,本 issue 加回归
bounded kernel correction 后失败 2 0 #159
research evidence append 不匹配 1 0 保留版本/证据完整性检查,无法恢复时由本 issue 兜底

另外:1 条 result delivery 在无效缓存回执上失败 12 次,由 #154 处理;directory 的当前枚举缺陷由 #158 处理;客户端重连由 #160 处理。基础配置全面优化按要求独立为 #153。

根因与已修复项

实际发布依赖 dist/src/runtime/runtime.js:1291–1337 的 finishWithError 在有效 lease 下发 user-visible run.failed/cancelled 并 completeWork(failed),但不为普通异常提交结果;event/complete 写入本身失败时只写日志。失去 lease 时正确地停止写入,不能绕过 fencing。于是“失败 work 有状态/事件”不等于“会话有可持久重放、投递可恢复的结束反馈”。基础连接故障会进一步放大这一缺口。

不要重新上报已经修复的历史 bug:

  • 曾有两个 work 达到 1,187/80 attempts,造成大量重复 control-plane/lease 失败事件;LingxiOS 3.3.8 已限制 abandoned lease 恢复,当前 3.4.7 的第三次相关恢复可终结。当前发布后的 work 最大 attempts=1,不是仍在无限恢复。
  • 3 个继承 research evidence 的 work 在初始 binding/checkpoint 即失败。上游 3.4.7 已保留并重新授权继承的 request/evidence/attachment;历史错误早于该修复。另一个旧 evidence append mismatch 缺少原始诊断,不能虚构具体冲突字段。
  • 读回执 FK 已由产品 migration 0019 修正,生产已应用到 version 42。

可执行方案

  1. 定义一个持久、幂等的前台结束反馈:有验证过的结果就交付真实 partial;没有结果时提供明确失败/待恢复状态,保留用户请求、已提交动作和恢复入口。通知不能伪装成功,也不能泄漏后台记忆、prompt 或内部凭据。后台 work 不逐条刷用户会话。
  2. 使用现有公开 runtime API、result/delivery outbox 和产品系统消息机制,在正确的 lease/fence/请求版本下提交。稳定 identity 保证只展示一次并 suppressAgentWake,避免兜底再触发 mention。若当前 API 不支持,应在 LingxiOS 上游增加所需契约并发布精确版本,产品不直接改其 schema/内部状态或伪造 adapter。
  3. 对控制面暂不可用或丢 lease 的场景,由合法持有者/既有恢复维护流程在连接恢复后补齐终态与反馈;旧 Worker 不越权提交。明确 pending→reconciling→terminal 的收敛期限,补偿过程有退避与上限,重启后继续。
  4. 重试只发生在可证明安全的边界:临时读取/模型请求按预算有限重试;已经执行的写操作查 action ledger/receipt;unknown outcome 先核对,不重跑整轮。取消/撤权/确定性契约拒绝停止自动重试。后续用户消息不被旧失败或恢复任务锁住。
  5. 暴露互相独立的 work/result/delivery/client 状态与脱敏 correlation ID。事件数、尝试次数、失败调用数、失败 turn 数和待投递结果数不能混为一个“错误数”。run_events.delivered_at IS NULL 且 delivery_work IS NULL 的 SSE-only 记录不算积压;核查中的 5,743 条属于此类。

验收与关闭条件

  • 以故障矩阵覆盖预算/上下文、402/timeout、工具授权/版本、控制面短断、Worker 在工具写入后崩溃、lease 过期、IM 接受后失联、浏览器重连;每种都断言有界重试、终态可重放、下一条消息可继续、无重复业务副作用。
  • partial/blocked 已有可交付结果继续保留;用户取消只显示取消,不触发多余模型调用;撤权后不补发受保护内容。
  • 对已修复的无限 lease recovery、继承证据、读回执 FK 仅保留回归覆盖;不把它们误计为当前新增缺陷。
  • runtime 公开契约/产品 owning integration 与 tester-army/e2e / @e2e-dev/web 联合验证,提交可重复命令、脱敏状态时间线、录屏/截图、消息/动作次数和最终队列状态。涉及模型运行路径还需受控真实 provider 验证。

“不阻断对话”指故障可见、状态可恢复、用户可继续发言;全站断网或权限撤回时不能保证生成答案,也不能用越权或无限重试来掩盖失败。本轮只完成诊断和 issue 设计,没有部署、生产故障注入或用户消息重放。

Activity

  1. lyyzka commented on Oct 17, 2026

    @lyyzka
    ContributorAuthor

    追加状态:PR171/172/173 已合并 main;精确发布包3.5.1/schema12、实际不可变镜像迁移、完整 SPA 的6项 session/network/PG/Web-restart验收及10项 runtime/identity联合浏览器验收已有脱敏持久证据。402=1次、timeout=3次、context/budget/cancel=0次,持久终态不伪造结果,重读不重复,下一条可成功。

    最新证据与边界:https://github.com/LingXi-Org/LingxiLoop/blob/cad71ff73779d0f866526e727415de5bc34156e9/docs/evidence/runtime-measurements/README.md

    仍保留 open:父任务已确认没有新增可用的既有 provider/pricing 配置,因此没有实际 provider 调用。生产 Worker bubblewrap 被执行器 user namespace 限制;自动 Komodo rollout 仍在首次连接时失败,无 update ID。上述缺口不能用 fixture、Web/API-only观察或 workflow 跳过状态替代,亦未创建凭据、扩权、手动部署或修改生产安全设置。

  2. lyyzka commented on Oct 17, 2026

    @lyyzka
    ContributorAuthor

    持续开发已补齐总模型deadline的持久终态缺口:公开3.5.1原先返回execution_failed的回归已在正式3.5.2转绿,保留failed/no result、一次model_unavailable系统通知、一次失败provider请求和连接释放、持久结算,下一人类请求成功。慢ledger结算也不再覆盖首次deadline原因。

    产品PR174最终开发HEAD faea44a3a092d2caff49527ae3753c7f7de2d0bf;服务端106/106,定向集成17通过(通用入口跳过的一项真实IM测试已由专用20/20补验),官方browser11/11零跳过。真实WuKong结果outbox恢复保留same result/message identity、一次send/一条消息和不变model/action计数。见可重复命令及脱敏证据。PR最终CI尚在运行,未提前合并。

    这轮browser使用真实产品API/public Worker、PG和WuKong,model/login明确为隔离夹具,不冒充完整SPA或真实provider。此前完整SPA证据继续按3.5.1保留。本issue要求的受控真实provider及当前受限云执行器的生产Worker隔离资格仍未验收;不为通过测试扩权。部署依用户最新指示取消,不再作为开发阻塞。

  3. lyyzka commented on Oct 17, 2026

    @lyyzka
    ContributorAuthor

    后续结果:PR174已普通合并到main ba9014958f7ab0dc0636a18edd1339d9e9e76e60,main CI39016358468 全部开发门禁和不可变server镜像发布成功;update-manifests/deploy/rollout均按用户要求SKIPPED,没有生产部署。3.5.2公开包与双锁已接线。最终证据。此前说明的外部验收边界不变,issue保持开放,未冒充真实provider/账单/完整24h通过。

  4. lyyzka commented on Oct 17, 2026

    @lyyzka
    ContributorAuthor

    3.5.2的完整SPA会话/人类消息恢复补验已完成:PR175已普通合并到main 06ba56169ae8796bf6e067f4eecca0064145a816,6/6、零失败/重试/跳过。真实新建的独立PG/Redis/WuKong/存储与Web/control/D1覆盖了session恢复/过期、网络中断、PG暂停、Web重启及两种401发送竞态;老发送不越权重放,后续发送一次持久落库。保留13截图/6视频及实际计数。证据与逐项验收映射。

    对153/155/157/161的复查未发现新增产品/runtime代码缺口,当前新增仅隔离夹具及证据。完整Worker预检仍有明确环境失败:宿主setting up uid map: Read-only file system,独立默认安全配置容器No permissions to create new namespace,均exit1;未扩权。受控真实provider/价格配置未提供。完整Worker/真实provider及费用/完整观察时窗仍属外部验收条件,保持issue开放。

    这次通过的是3.5.2完整SPA登录后会话/消息链路,不包括captcha登录、模型辅助完整Worker对话或3.5.2耐久验证。原3.5.1 Web/API soak未动、未改版本标签;既有06:50UTC独立复查任务已经核验启用,没有重复安排。部署继续排除。

  5. lyyzka commented on Oct 19, 2026

    @lyyzka
    ContributorAuthor

    2026-10-19 本轮验收继续:既有隔离回归与3.5.2 SPA证据仍按原范围有效;当前云环境已具备现有provider测试配置与生产只读运维访问,正在补充受控真实调用/费用及最终版本验收。不会将fixture、CI门控跳过或旧3.5.1未完成soak当作这些外部条件通过。当前仍保持开放;PR185已审查并合并,最终发布按本轮依赖统一编排。

  6. lyyzka commented on Oct 19, 2026

    @lyyzka
    ContributorAuthor

    阶段更新:已审查的恢复相关代码和正式 LingxiOS 3.5.3 已随 PR194 / 成功发布流程 上线,实际运行时、镜像及 readiness 已核验。

    上游真实进程恢复证据,以及产品持久状态、重复交付和本轮用户输入恢复/重试专项均保留;正式包验收快照记录其真实源提交与范围。新隔离Web+Worker空闲耐久正在运行,但它不覆盖写入后崩溃与SPA恢复的完整场景。

    本 issue 保持开放:完整产品 Worker 写入后崩溃、恢复/交付和 SPA 联合验收仍待完成。未进行生产故障注入,正常发布成功不作为该项关闭依据。

  7. lyyzka commented on Oct 20, 2026

    @lyyzka
    ContributorAuthor

    按用户2026-10-20最新范围,基础能力、必要短测、独立审查与上线已完成,验收关闭。

    持久失败/取消终态、投递恢复、幂等副作用和下一条消息继续的基础能力通过验收。

    • PR208:3个真实Worker子进程。业务写入/result提交后ACK丢失并SIGKILL,接替进程控制面503/readiness503后恢复200,下一条成功,模型/动作/result均无重放。
    • PR208:IM已接受但ACK丢失后重建control服务实例,通过稳定nonce/history仅恢复1条通知;最终3 succeeded/1 cancelled/0 pending。该场景不是整个WebOS进程重启。
    • PR209:授权/撤权、发送前取消、已接受IM但receipt UPDATE取消后保留dispatch marker并按nonce/history核对;真实runtime terminal/result取消后同outbox只发送1次且不重跑模型,下一真实turn成功。

    生产已由正常 CI/CD 发布:source 554e81ac7fc59984d069a104d555adbf48092411,正式 runtime 3.5.6;精确 main CI/CD成功。Komodo 实际聚合回执为 Complete / success:true;四个 API/Worker 容器均为该 source 的同一已发布镜像、健康,当前 Docker OOMKilled=false 且 restartCount=0,两个同镜像迁移容器 exit 0,两轮 HTTPS 就绪/版本检查通过。镜像 manifest list sha256:ed3088feac9dacbfe6b639b6d6edd7b0b2c53a2b3ab58740a20f8b76e23aed56。产品迁移46/runtime schema12未新增;本轮没有重新通过直连SQL读取schema/lease,不能把迁移exit回执称为该项验证。

    交付:回调证据 · PR207 · PR208 · PR209 · PR211 · 上游PR32。

    未验证范围:提交前崩溃、完整lease过期/stale owner组合、真实WuKong与全量SPA联合矩阵、真实provider和长期观察未验证。 固定暂停3.5.3观察与自动核验未触碰;未做生产故障注入、真实provider调用或凭据/安全配置变更。旧文中的长期/完整矩阵复选框保留作为历史边界,不标为通过。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions