Skip to content

feat(chat): steer persistent queued messages into the active turn - #8059

Merged
huangruiteng merged 11 commits into
mainfrom
codex/chat-persistent-queue-20261104
Nov 5, 2026
Merged

huangruiteng merged 11 commits into
mainfrom
codex/chat-persistent-queue-20261104

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

运行中的对话此前只显示重复排队 ACK,难以核对内容,也不能把某条消息交给当前回合。本 PR 展示原持久队列,并提供“插入本轮”:聚焦消息后按 Command+Enter。普通 Enter 继续排队,Shift+Enter 保留换行。

  • 保留原 Session、Turn、client request、消息和附件身份。确认转交后移出;确定失败保持排队,不确定结果保留同一操作供核对,避免重发或被自动消费。
  • TS 拥有队列选择与 steering 决策;Python 复用现有 HTTP/store、Session/Turn 锁、native ingress 和 source-binding admission。没有第二执行器。
  • 自动出队后跟随真正的活动回合,插入和停止入口同步。附着宿主的后续消息也共用原队列入口;即使另一页面刚启动宿主、普通发送才得知已排队,回执也不会抢走当前回合的控制器。
  • 队列内容按需展开并内部滚动,390px 保留停止入口;移除成功横幅及人工 assistant ACK,保留失败与未知投递反馈。

验证 head d22d1e636009529a30215c86af017a3d8a80a4d5,当前 rebase 基线 2852eb453bef7731370e156ea5047e67090d549a(实现基线 24f46874)。当前 head 的完整真实 HTTP/store/runtime queue suite 17/17、TS queue decision 3/3、相邻 driver/manager/Ark 测试、严格 kernel mypy 17 文件、Todo CLI mypy 2 文件、变更文件 Ruff、control-plane typecheck、完整 Dashboard/Chat 构建、CSS token 检查及 3 个相关打包浏览器场景通过;其中 attached-host-follow-up、composer-session-admission、chat-recovery 分别以 64.0s、8.5s、64.9s 通过。Ego 在历史 af0ff390 的生产 HTTP/store/runtime 与隔离 stdio 模型替身验证同线程两次 native steer、自动接续、附件限制和恢复。

上一轮 exact-head review 的 P2 已修复:展开排队消息改用既有 --text-body / --leading-body,当前打包场景在 1440×900 与 390×844 都断言 computed 14px/20px;预览和元数据仍使用 caption,完整正文、内部滚动与 Stop 保留。rebase 期间只丢弃了已被 main #8050 同语义取代的返回类型声明,解决了一个与 task_orchestration_admission.py 的类型标注冲突。

历史失败保留:旧 cc head 等待已删除的界面提示;旧 28 head 有 fixture 命名遮蔽、main 测试 lambda 与旧 CLI 读取方式问题,均已修复并完整回归。a861 的 strict mypy 暴露的 transport 返回声明已由 main 的同语义实现取代。队列测试原先把 native adapter 启动中的后台协议写入误判为 read-only/rejection 副作用;当前 head 等待 running + upstream_turn_id 的真实后置状态后再截取 capture,没有放宽任何断言。

本地 diff-scoped premerge:4 个 direct checks、Python compile、语义/公开边界检查及 8 个 risk-profile smokes 通过;19 个选中检查中 1 个阻塞 catalog smoke 失败。该 todo-readmodel-boundary-smoke.py 在同一 origin/main 的干净 worktree 上逐字复现 loopx.status.open_todo_items 缺失,是未触及的主干故障,保留为独立 merge-readiness 风险。maintainability ratchet 本轮命中未触及的 work_items/interaction_contract.py,被工具标为 inherited advisory。CLI output differential 仍在冻结 base probe 因缺少 interaction_contract / scheduler_hint / selected_todo 失败,尚未进入本次 head;没有降低预算、改写 oracle 或把失败豁免。CQR 未在本会话的未绑定 Goal 上启用。

预算保留原失败与同基线测量:runtime 2376 行/36 Any →2417/38,server 2039/25→2045/25。增长服务 durable transfer、共用 admission 和两条 HTTP 路由;只把两模块 ceiling 从 2398/37、2039 校准到实测 2417/38、2045,零额外余量;默认限制及冻结阈值不变。

原生插入暂限纯文本,附件保留排队;编辑/取消属于后续范围。真实模型采纳、真实附着宿主执行、installed App、macOS 拼音和绑定 Lark 会话仍需各自实测。协议替身及 packaged Session/API fixture 不作为实际模型或宿主采用证据。未合并、安装或发布。

视觉证据:前五张为隔离生产 HTTP/store 的打包界面,长内容来自公开 EdgeBench Grid R7 展示 fixture(runner_invalid、diagnostic_only,不据此推断增益)。Before 为 b8d3969,After 为 a85bd9d 的相同布局;最新两张来自 a69b37939a 的 packaged Session/API fixture,当前 head d22d1e6360 的队列呈现源码与该捕获逐字一致,并重新生成相同布局、通过 computed 14px/20px 断言,展示展开正文、内部滚动与停止入口。

桌面 Before 桌面 After
before desktop after desktop
390px Before 390px After
before narrow after narrow

390×568:展开原始长内容、内部滚动,停止入口可见。

long benchmark content

附着会话:桌面 附着会话:390px
attached queue desktop attached queue narrow

当前队列界面(d22 与截图源 a69 的队列呈现文件逐字一致):

当前桌面 当前 390px
current attached queue desktop current attached queue narrow

@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.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

动机

运行中的对话用户需要核对原排队内容,并决定是否把其中一条交给当前回合,而不必复制原文、重复发送或另开会话。此前只有排队 ACK,普通 Enter 会等下一轮;本次增加原队列 reader 和明确的“插入本轮”,保留原 Session、Turn 与消息身份。

本次可观察的改善是:普通 Enter 仍排队,展开读取完整原文,Command+Enter 请求一次原生 steering;未知投递结果保留同一操作,禁止自动出队重放。边界是文本插入与已有队列的显示、接续、停止;附件转换、编辑/取消、真实模型采纳和 installed App 不在本次已验证结论内。用户不需要新增设置或重复确认。

改动思路

保留既有持久队列、Session/Turn 锁和 native ingress 是合理的小边界。只加“复制并重发”会丢失原消息身份;只改UI无法防止已经送达但ACK丢失后的重复执行。不改动则继续缺少原地核对/转换入口。因此TS拥有决策,Python适配原HTTP/store/native IO,前端复用history/control owner,不另建执行器。

当前 PR 的边界应保留上述机制,修复展开原消息的正文样式;不需要扩大成新的调度系统。对新增前端临时状态也作了复核:submittedAsQueue由原生accepted.status/phase推导,previousStreamController保留当前观察者,并非新的持久队列或权限owner。

分支 已验证结果
原生确认送达 原队列Turn形成adoption receipt,原消息保留一次
实际原生接收后丢ACK cold controller不再发送,仍阻止自动FIFO claim
确定未送达、附件或其他执行契约 保留原输入,不借转换获得其他权限
队列读取/SSE失败→恢复→连续接续 新head停止请求到达native一次,当前Turn读回已中断

具体改动

评审完整范围为不可变merge-base ce4cfc1ce74a2ffe0d685758b8d6e9233b467f41 → 当前head 28e02efa013449a8ec580696249133333a6b6f91 的23文件、+977/-72,目标main。发布前发现旧head cc1234de14b19f3599f7999bcf3c83e7fece5fb6 已更新,因此未向旧head发布;新增5文件diff已完整重读,并重新构建、执行受影响的真实打包恢复路径。全PR结论没有继承旧head轨迹。

  • planQueuedChatSteering(loopx/control_plane/turn_driver/chat_queue_steering.ts:45)拥有dispatch/complete/release/unresolved;不把HTTP成功当工作采纳。
  • steer_queued_turn(loopx/chat_runtime.py:1291)在原Session→Turn fence下先存reservation,再调用已有native ingress并回读结果。
  • QueuedMessage(apps/presentation/dashboard/src/features/personal-workspace/conversation-queue.tsx:10)从原history展开完整内容并显式转换;它的正文继承样式是当前发现。
  • onObserveConversationTurn(apps/presentation/dashboard/src/views/dashboard-page.tsx:3257)沿既有history恢复控制;新提交还按真实queued phase保留活动控制器,扩大附着/普通排队回执处理,而非让ACK抢走活动回合。

按变更前 docs/development/design.md,spec_revision ce4cfc1ce74a2ffe0d685758b8d6e9233b467f41:Typography 要求正文与元数据字号分离,本head未满足;Populated Page Review 的默认/展开、长文、桌面/窄屏与失败恢复已实际检查;Earn The User's Attention 的原地停止/真实读回在本head的同一失败恢复反例已通过。队列与steer身份、provider确认和工作采纳的分离另核对同revision的docs/reference/goal-chat-continuation.md和desktop execution frontend contract,不宣称全部宿主已资格。

对主干的风险

[P2] 展开原消息应恢复正文字号。 conversation-queue.css:1把整节设为 --text-caption,:15–16没有给完整消息覆盖字体。精确新head的1280×900和390×568打包页面中,2961字符中英原文实测12px/20px;原普通消息与设计正文规范使用 --text-body14px。用户点开展开后是在阅读原文,长内容在窄面板中明显比普通消息细小。请为展开正文复用body/prose tokens,预览、计数仍可caption;保留完整文本、内部滚动和停止入口,并复验桌面/390px展开。

旧head曾两次在来源读取/SSE失败恢复、连续两条FIFO接续后显示正确新目标却本地拒绝Stop;干净对照可停止。这些失败保留,但不作为当前head发现:新head同一隔离实际HTTP/store/runtime、stdio原生替身路径已经产生恰好一次turn/interrupt,Session读回ready且active_turn_id为空,当前Turn已中断。没有用“按钮字段正确”代替真实结果,也没有仅因作者说已修复就撤销发现。

后端/TS/原生测试文件从旧head到新head逐字节未变,故102项native、27项TS、6项独立ACK-after-acceptance/cold-controller及source-scope反例仍适用;基线/head相同9项FIFO/非法意图/容量/撤销grant/read-only测试均通过,新增GET明确404→200且无native effect。新head严格前端/打包重新通过,恢复/正文反例也在新包重跑。新head的standard premerge也通过6项直接检查与19项catalog/risk/public检查,不把作者远端CI当必需证据。

预算按同一基线实测:chat_runtime.py2376行/36Any→2417/38,server2039/25→2045/25;只把两个ceiling校准到实测、没有额外余量。持久transfer、共用admission与两条路由已有真实caller;该数字不替代架构/价值判断。reviewer曾选错测试路径、用不支持的fixture update字段、在页面准备前发起验证,均保留并纠正为有效路径;未把这些设置错误归咎本PR,未放宽任何gate。

我的整体评价

REQUEST_CHANGES:只保留上述展开正文的P2,当前失败恢复Stop已由独立新head验证解决。设计规模与复用边界合理,原生去重和不确定结果保留有具体价值;修复样式不需要额外调度机制、无关迁移或新的验收任务。

默认队列集中在输入框上方,完整内容可展开且内部滚动,窄屏停止入口可见;展开正文12px仍是具体阅读回归。本轮检查了同一新head的默认/展开桌面与390px、2961字符原文、混合历史/活动/待处理内容及失败恢复。未验证范围:真实模型采纳、installed App、macOS拼音、真实附着宿主/绑定Lark和长期完整成本;stdio替身或作者packaged API fixture不证明这些结果。

Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max.
English verdict: REQUEST_CHANGES — current-head Stop recovery is independently verified; restore body typography for expanded original queued messages.

@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.

Request changes conclusion (author-owned PR; GitHub blocks formal self-review)

[P2] 展开原文使用正文排版。 当前 head 的 .personal-queue-message 没有正文覆盖,继承整个队列的 --text-caption。3392 字完整原文在实际 1200×888 桌面和 390×568 窄屏均为 12px/20px,现有 body token 为 14px。把展开正文改用既有 body/prose token,保留预览与元数据的 caption;在现有浏览器场景补桌面/窄屏 computed font 断言,并保持完整尾文、滚动和 Stop。

动机 / Motivation

在运行中的对话里排入补充消息、随后希望核对原文并交给当前回合的用户。原来只能看到排队确认,需手工复制重发才能补充当前回合;现在可展开持久原消息并显式插入本轮,未知投递继续核对同一操作,但展开长正文仍被压成12px元数据字号。持久队列和原生转交的身份、失败与冷重试边界通过独立验证;当前打包页面的完整正文可读性仍未达到设计正文规范。不授权模型工具、第二执行器、自动把附件/peer消息转steer、编辑取消、安装或发布;ACK不证明真实模型采纳。

改动思路 / Approach

不确定投递需要原队列上的持久reservation与receipt判定;TS拥有策略,Python只保留原存储/IO/锁/权限。界面复用同一原消息,无新增确认轮。 27files994增81删,完整HTTP/store/TS/front path及伴随fixtures;新TSowner99行,原queue/native ingress/权限owner保留。

用户无需复制已知原文或重复确认:读取同一持久队列,按需展开,然后明确“插入本轮”。原 Session/Turn 锁内先写 reservation,再调用原 native ingress;完成来自匹配 receipt。已确认未投递才释放,不确定则核对同一操作并继续占队列容量。新 UI 只是投影和意图入口,GET 或按钮可见都不会自动发送。

具体改动 / Changes

审查精确 head eb4470126819b6131dc1b2db9282af814f999325,实际三点比较基线 24f46874bc97e3dc6105edeb22f87074b649b161。27files994增81删,完整HTTP/store/TS/front path及伴随fixtures;新TSowner99行,原queue/native ingress/权限owner保留。

关键代码讲解

  • planQueuedChatSteering:Typed reservation/receipt decisions. Delivered replay beforecurrenttarget; unknownheld; rejectconflict.
  • steer_queued_turn:Lock,admit,reserve,existingnative IO,reconcile. Persist beforeIO; existinggrant/generation/source checks.
  • queued_turns:Existingqueue selection extends typedowner. Strict malformed evidence refuses; pendingexpiry notfreecapacity.
  • ConversationQueue:Fulloriginalread andexplicitsteer/check. Attachment/sourceunavailableblocked; unknownchecksameoperation.
  • .personal-queue-message:Expandedbodytypography. No bodyfontoverride, unlike accepted14pxbody.

规范依据为 docs/development/design.md,固定版本 24f46874bc97e3dc6105edeb22f87074b649b161,按该变更之前已接受的正文判断。

Typography:not_met,展开完整原文继承 12px caption,最小修复见 P2。Populated Page Review:当前 head 已在实际桌面/390px 检查默认、完整展开、长重复原文和失败/恢复,完整尾文仍可到达。Earn the User's Attention:队列内部限高滚动,Stop 可见,详情按需展开;未新增成功横幅或假 assistant 回答。后两项检查不消除正文排版缺陷。原对话接续规范及 desktop frontend 契约也已在固定基线阅读,工具权限和 native source admission 沿原 owner。

对主干的风险 / Risks

后端最强风险是已投递后丢 ACK,重启重试把原消息再发一次或被自动 FIFO 消费。我独立通过实际 HTTP/store/runtime 和 stdio provider,在真实接受后注入 Timeout,再令原 target 完成并用冷控制器核对:恰好 1 turn/start、1 turn/steer,没有重发,原 user 消息、client identity 和持久 reservation 保留。严格坏 receipt 不等于不存在,未知继续占容量;source grant、generation、附件/peer 限制沿原 owner。

原生 queue/ordinary 两模块 base20/head29 PASS,TS base24/head27 PASS;额外 driver3、fresh-host1、roundtrip99 PASS,17-source mypy head PASS、base1 FAIL,root TS、Ruff、前端严格 TS/Vite 构建 PASS。当前 packaged 页面复现 P2:完整3392字在两种实际 viewport 都为12px,内部滚动及 Stop 则可达。实际 GET 失败隐藏不可读缓存,解除阻断并 Retry 回到原持久队列;随后 Stop 的唯一恢复阶段 interrupt 对准当前 Turn,先前3分钟 fixture idle timeout 另计,未抹去。浏览器没有执行原生插入,该边界由独立 HTTP 探针覆盖。

标准 premerge:6 个直接检查 PASS,19 个选定检查18 PASS/1 FAIL;required quota-plan-smoke 在 quota_plan_fixtures.py:700 报 KeyError: quota。新鲜精确 base 的同命令也失败,仅规范化 checkout root 后完整 stderr 相同,因果脚本、fixture 与配置 Git 对象相同,归因 pre_existing_unrelated;required FAIL 仍保持。作者明确保留的 CLI-output differential 在冻结 base 尚未进入 head,本轮未独立退休,严格 CQR 同样 FAIL,不以本地局部通过宣称整库/CI资格。

语义与 CI 对齐

新增 loopx_chat_queue_steering_v1 是 chat 局部 typed contract,dispatch/complete/release/reject/unresolved 在 TS 唯一决策 owner;Python 负责持久 IO 和原授权检查。没有按业务 prose/substring 分类,无全局默认开关或权限扩张,原 Enter 仍排队。原 cast 只声明既有返回类型。正文排版义务由新完整原文展开触发,当前证据仍失败;局部 body token 修复后须重跑现有 packaged composer 场景并核对两种 viewport 的 computed font、完整尾文、滚动和 Stop。语义扫描通过不覆盖这个视觉缺陷。

我的整体评价 / Verdict

当前交付为 not_yet_proven:long_horizon preserved,未知投递与冷重试无重复的关键路径通过;user_experience regression,完整正文可读性需先修复。完整27文件方案与持久意图/receipt边界匹配,保留TS唯一策略 owner 的架构选择;未发现需另建执行框架的理由。当前head打包页面已检查真实长正文、默认/完整展开和混合运行/失败状态;1200×888及390×568都继承12px caption,展开阅读仍有P2缺陷。内部滚动与Stop可达保持。 未查询远端CI;未验证真实模型采纳、installed App、完整长期成本。真实附着Host执行、macOS拼音、绑定Lark会话未验证;浏览器未执行native插入,独立HTTP探针覆盖该边界。 当前P2及独立质量 hold 均保留;修改后应按新 exact head 重审,既有后端通过或旧 head 的结论都不能代替新页面回读。

English verdict: REQUEST_CHANGES for the expanded-message body typography; required qualification holds remain.

@mergify

mergify Bot commented Nov 5, 2026

Copy link
Copy Markdown

This pull request has merge conflicts with main and cannot be merged
until they are resolved. Please rebase or merge the base branch, @loopx-agent.

Choose the remote for the base repository, not an out-of-date fork.
For a fork clone, first inspect git remote -v; upstream must point
to https://github.com/loopx-project/loopx.git. If it is absent, add it
with git remote add upstream https://github.com/loopx-project/loopx.git.
Then run:

git fetch upstream
git rebase upstream/main
# Resolve each conflict, git add the resolved files, then git rebase --continue.
git push --force-with-lease origin HEAD

For a same-repository clone whose origin points to
https://github.com/loopx-project/loopx.git, use origin instead of
upstream for fetch/rebase. If you prefer merging the base, use
git merge <base-remote>/main and push normally.

Keep the DCO Signed-off-by trailer on every commit when you rebase.
https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/syncing-a-fork

@mergify mergify Bot added the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 5, 2026
@huangruiteng
huangruiteng force-pushed the codex/chat-persistent-queue-20261104 branch 2 times, most recently from e2f6d02 to a69b379 Compare November 5, 2026 03:38
@huangruiteng

Copy link
Copy Markdown
Collaborator

Current-head packaged visual evidence for a69b379 (synthetic attached-host queue):

attached-host-pending-queue-current attached-host-pending-queue-current-390

The expanded queued body measures 14px/20px at both viewports; the row remains internally scrollable and Stop stays visible.

huangruiteng
huangruiteng previously approved these changes Nov 5, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent; GPT-5; OpenAI; self_reported

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

动机 / Motivation

运行中的 Personal Workspace 对话用户此前只显示重复排队 ACK,难以核对内容,也不能把已有消息交给当前回合。此前只显示重复排队 ACK,只能复制重发;现在可展开核对并显式插入当前回合。普通 Enter 仍排队,显式“插入本轮”或 Command+Enter 才请求当前 Turn 的 native steering;附件、未知投递和不可切换的宿主仍保留在队列,不会被自动降级或重放。

原排队消息只形成一次 steering,未知投递不重放且不被 FIFO 消费。本次边界是文本插入与已有队列的显示、接续和停止;真实模型采纳、installed App、真实附着宿主、macOS 拼音和绑定 Lark 会话仍需独立验收。

改动思路 / Approach

入口仍是当前 Session 的持久队列。planQueuedChatSteering 是唯一的 dispatch / complete / release / reject / unresolved 决策 owner;Python 的 steer_queued_turn 只复用现有 Session/Turn 锁、store、native ingress 和 source-binding admission,没有第二个执行器。队列 GET 是只读投影,按钮或 Command+Enter 才触发效果。

这个设计是 retain:在已有 FIFO 和 live-steering owner 上增加一个有明确撤回条件的 reservation,而不是新建调度链路。发送前先持久化 pending reservation;只有匹配的 delivered receipt 才将原排队 Turn 视为成功,确定未送达才释放 FIFO,不确定结果继续占用容量并禁用自动 claim。当前 PR 边界为文本 steering;附件保留排队,编辑/取消和真实宿主采纳留给后续。

具体改动 / Changes

相对 71970fb03e,完整 diff 为 26 个文件、+1029/-78:前端队列投影与交互、TS 决策、Python HTTP/store/native adapter、打包浏览器 fixture、测试及模块预算校准。现有 attached-host、普通 FIFO、native steering 和 history recovery 均保持原 owner。

规范依据为 docs/reference/goal-chat-continuation.md,spec_revision=71970fb03eb2ab90b353f0895bb1463ca7eaf236。其中 QUEUE-VISIBILITY 要求待处理输入在暂停或 native 完成后仍可见;STEER-EXACT 要求立即 steering 精确绑定当前 Turn 且拒绝不降级为 queue;UNCERTAIN-DELIVERY 要求丢失 ACK 时保持 uncertain、不自动重放;IDENTITY-PRESERVED 要求保留原 Session、Turn、client request 与消息身份。VISUAL-BODY 复用 Dashboard 的 Body M 正文 token。

关键代码讲解

  • queue_api.py:9 的 _session_queue 从原 Session 的持久 Turn 读取 240 字符预览、长度、附件数和 reservation,并沿用原 Session context/source admission;它不启动 native 工作。
  • chat_queue_steering.ts:45 的 planQueuedChatSteering 对相同操作的重放先结算,对 pending 冲突和错误 target 拒绝,只在 receipt 明确 delivered 时完成,未知原因保持 unresolved。
  • chat_runtime.py:1291 的 steer_queued_turn 在 Session/Turn 文件锁内先写 reservation,再调用现有 steer_active_turn,最后根据持久 receipt settle;异常文本本身不能释放队列。
  • conversation-queue.tsx:10 的 QueuedMessage 仅在用户展开时读取完整消息,普通 Enter 继续排队;显式 steering 失败显示可恢复状态而不构造 assistant ACK。
  • conversation-queue.css:15 把展开正文恢复到 --text-body / --leading-body;预览和元数据保持 caption。

对主干的风险 / Risks

最强回归是 native 已收到 steering、但响应丢失后重试又发一次,或 pending reservation 被 FIFO 消费。TS decision 在未知 receipt 时返回 unresolved,Python 的 selectQueuedChatTurns 排除 pending reservation;真实 HTTP/store/runtime 的 cold-controller 测试验证第二次请求仍只看到原 reservation、没有第二次 native steer,且自动 claim 返回空。

17 项 queue Python 测试和 3 项 TS decision 测试在 a69b37939a 通过;真实 HTTP/file store、native stdio、Session/Turn 锁、附件拒绝、源范围撤销和完成后的幂等 replay 都覆盖。packaged attached-host-follow-up 在 64.6s 内通过,桌面与 390×844 均实际测得展开正文为 14px/20px;composer-session-admission 和 chat-recovery 也在相同的最终前端源码上通过。

本地 premerge 的 4 个 direct checks、Python compile、maintainability ratchet、语义/公开边界和 8 个 risk smokes 通过;19 个选中检查中的 todo-readmodel-boundary-smoke.py 失败,已在不可变 71970fb03e 干净 worktree 上以相同的 loopx.status.open_todo_items AttributeError 复现。CLI output differential 同样在冻结 base probe 上、尚未进入本 head 时失败,缺失键固定为 interaction_contract / scheduler_hint / selected_todo。这两项均保留为独立 merge-readiness 风险,没有降低或改写 oracle。

语义与 CI 对齐

本 PR 扩展的是既有 queue / steer 词汇和 Turn identity,不是新的通用 actor 或 authority。默认 Enter 仍排队;只有显式操作才 steering;拒绝保持失败,未知结果停留在原队列。loopx_chat_queue_steering_v1 是局部 typed reservation schema,没有新增 provider 或持久 authority。

我的整体评价 / Verdict

APPROVE。 当前精确 head 没有未解决的阻塞 finding。长期任务维度改善:原 Session/Turn/消息身份和不确定投递保留,避免重复执行与无界 FIFO 消费。用户体验维度改善:用户能在原对话核对原文并在一次显式操作中交给当前回合,不必复制重发;正文尺寸已达到 Body M,桌面与窄屏的队列内部滚动和 Stop 均保留。视觉评审检查了当前 head 的默认与展开队列。未验证真实模型采纳、installed App、真实附着宿主、macOS 拼音和绑定 Lark 会话。

代码体量较大但边界内聚:新的 TS 决策替代散落判断,Python 只承担 store/native IO;没有第二执行器或新的调度系统。当前无需在合并前继续简化,附件转换、编辑/取消和真实宿主采纳保持明确非目标。

English verdict: APPROVE — head a69b37939a3c5e8fc46dbb961012c98be24e35ac delivers explicit persistent-queue steering with exact Turn identity, uncertain-delivery protection, and correct expanded-body typography. The changed invariants pass real HTTP/store/runtime and packaged desktop/narrow validation; the remaining premerge failures are reproduced on the immutable base.

loopx-agent and others added 11 commits November 5, 2026 11:47
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng force-pushed the codex/chat-persistent-queue-20261104 branch from a69b379 to d22d1e6 Compare November 5, 2026 03:53
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 5, 2026

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent; GPT-5; OpenAI; self_reported

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

动机 / Motivation

运行中的 Personal Workspace 对话用户此前只显示重复排队 ACK,难以核对内容,也不能把已有消息交给当前回合。此前只显示重复排队 ACK,只能复制重发;现在可展开核对并显式插入当前回合。普通 Enter 仍排队,显式“插入本轮”或 Command+Enter 才请求当前 Turn 的 native steering;附件、未知投递和不可切换的宿主仍保留在队列,不会被自动降级或重放。

原排队消息只形成一次 steering,未知投递不重放且不被 FIFO 消费。本次边界是文本插入与已有队列的显示、接续和停止;真实模型采纳、installed App、真实附着宿主、macOS 拼音和绑定 Lark 会话仍需独立验收。

改动思路 / Approach

入口仍是当前 Session 的持久队列。planQueuedChatSteering 是唯一的 dispatch / complete / release / reject / unresolved 决策 owner;Python 的 steer_queued_turn 只复用现有 Session/Turn 锁、store、native ingress 和 source-binding admission,没有第二个执行器。队列 GET 是只读投影,按钮或 Command+Enter 才触发效果。

这个设计是 retain:在已有 FIFO 和 live-steering owner 上增加一个有明确撤回条件的 reservation,而不是新建调度链路。发送前先持久化 pending reservation;只有匹配的 delivered receipt 才将原排队 Turn 视为成功,确定未送达才释放 FIFO,不确定结果继续占用容量并禁用自动 claim。当前 PR 边界为文本 steering;附件保留排队,编辑/取消和真实宿主采纳留给后续。

具体改动 / Changes

相对最新 main 2852eb453b,完整 diff 为 25 个文件、+1026/-77:前端队列投影与交互、TS 决策、Python HTTP/store/native adapter、打包浏览器 fixture、测试及模块预算校准。现有 attached-host、普通 FIFO、native steering 和 history recovery 均保持原 owner。

规范依据为 docs/reference/goal-chat-continuation.md,spec_revision=2852eb453bef7731370e156ea5047e67090d549a。其中 QUEUE-VISIBILITY 要求待处理输入在暂停或 native 完成后仍可见;STEER-EXACT 要求立即 steering 精确绑定当前 Turn 且拒绝不降级为 queue;UNCERTAIN-DELIVERY 要求丢失 ACK 时保持 uncertain、不自动重放;IDENTITY-PRESERVED 要求保留原 Session、Turn、client request 与消息身份。VISUAL-BODY 复用 Dashboard 的 Body M 正文 token。

关键代码讲解

  • queue_api.py:9 的 _session_queue 从原 Session 的持久 Turn 读取 240 字符预览、长度、附件数和 reservation,并沿用原 Session context/source admission;它不启动 native 工作。
  • chat_queue_steering.ts:45 的 planQueuedChatSteering 对相同操作的重放先结算,对 pending 冲突和错误 target 拒绝,只在 receipt 明确 delivered 时完成,未知原因保持 unresolved。
  • chat_runtime.py:1291 的 steer_queued_turn 在 Session/Turn 文件锁内先写 reservation,再调用现有 steer_active_turn,最后根据持久 receipt settle;异常文本本身不能释放队列。
  • conversation-queue.tsx:10 的 QueuedMessage 仅在用户展开时读取完整消息,普通 Enter 继续排队;显式 steering 失败显示可恢复状态而不构造 assistant ACK。
  • conversation-queue.css:15 把展开正文恢复到 --text-body / --leading-body;预览和元数据保持 caption。

对主干的风险 / Risks

最强回归是 native 已收到 steering、但响应丢失后重试又发一次,或 pending reservation 被 FIFO 消费。TS decision 在未知 receipt 时返回 unresolved,Python 的 selectQueuedChatTurns 排除 pending reservation;真实 HTTP/store/runtime 的 cold-controller 测试验证第二次请求仍只看到原 reservation、没有第二次 native steer,且自动 claim 返回空。

17 项 queue Python 测试和 3 项 TS decision 测试在 d22d1e6360 通过;真实 HTTP/file store、native stdio、Session/Turn 锁、附件拒绝、源范围撤销和完成后的幂等 replay 都覆盖。packaged attached-host-follow-up 在 64.0s 内通过,桌面与 390×844 均实际测得展开正文为 14px/20px;composer-session-admission 与 chat-recovery 也在当前 head 分别以 8.5s、64.9s 通过。

kernel mypy 17 文件、Todo mypy 2 文件、control-plane typecheck、完整 Dashboard/Chat 构建、CSS token 与 changed-file Ruff 均通过。本地 premerge 的 4 个 direct checks、Python compile、语义/公开边界和 8 个 risk smokes 通过;唯一的阻塞失败仍是 todo-readmodel-boundary-smoke.py,并在最新不可变 main 2852eb453b 的干净 worktree 上以相同的 loopx.status.open_todo_items AttributeError 复现。maintainability ratchet 本轮命中的是未触及的 work_items/interaction_contract.py,工具将其标为 inherited advisory。CLI output differential 同样在冻结 base probe 上、尚未进入本 head 时失败,缺失键固定为 interaction_contract / scheduler_hint / selected_todo。这些均保留为独立 merge-readiness 风险,没有降低或改写 oracle。

队列呈现文件相对先前 reviewed head 没有变化;当前 head 重新生成了相同的打包桌面/窄屏截图并再次通过计算样式断言,因此 PR 中的视觉观察仍绑定原捕获 revision,而交互与构建资格已在新 head 重跑。

语义与 CI 对齐

本 PR 扩展的是既有 queue / steer 词汇和 Turn identity,不是新的通用 actor 或 authority。默认 Enter 仍排队;只有显式操作才 steering;拒绝保持失败,未知结果停留在原队列。loopx_chat_queue_steering_v1 是局部 typed reservation schema,没有新增 provider 或持久 authority。

我的整体评价 / Verdict

APPROVE。 当前精确 head 没有未解决的阻塞 finding。长期任务维度改善:原 Session/Turn/消息身份和不确定投递保留,避免重复执行与无界 FIFO 消费。用户体验维度改善:用户能在原对话核对原文并在一次显式操作中交给当前回合,不必复制重发;正文尺寸已达到 Body M,桌面与窄屏的队列内部滚动和 Stop 均保留。旧捕获来自 a69 的同一队列界面;当前 head 的这些呈现文件与其逐字一致,并在 d22 重新生成相同布局、重新通过计算样式断言,因此保留原视觉观察而不宣称过期的布局证据。未验证真实模型采纳、installed App、真实附着宿主、macOS 拼音和绑定 Lark 会话。

代码体量较大但边界内聚:新的 TS 决策替代散落判断,Python 只承担 store/native IO;没有第二执行器或新的调度系统。当前无需在合并前继续简化,附件转换、编辑/取消和真实宿主采纳保持明确非目标。

English verdict: APPROVE — head d22d1e636009529a30215c86af017a3d8a80a4d5 delivers explicit persistent-queue steering with exact Turn identity, uncertain-delivery protection, and correct expanded-body typography. The changed invariants pass real HTTP/store/runtime and packaged desktop/narrow validation; the remaining premerge failures are reproduced on the immutable base.

@huangruiteng huangruiteng left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent; GPT-5; OpenAI; self_reported

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

动机 / Motivation

运行中的 Personal Workspace 对话用户此前只显示重复排队 ACK,难以核对内容,也不能把已有消息交给当前回合。此前只显示重复排队 ACK,只能复制重发;现在可展开核对并显式插入当前回合。普通 Enter 仍排队,显式“插入本轮”或 Command+Enter 才请求当前 Turn 的 native steering;附件、未知投递和不可切换的宿主仍保留在队列,不会被自动降级或重放。

原排队消息只形成一次 steering,未知投递不重放且不被 FIFO 消费。本次边界是文本插入与已有队列的显示、接续和停止;真实模型采纳、installed App、真实附着宿主、macOS 拼音和绑定 Lark 会话仍需独立验收。

改动思路 / Approach

入口仍是当前 Session 的持久队列。planQueuedChatSteering 是唯一的 dispatch / complete / release / reject / unresolved 决策 owner;Python 的 steer_queued_turn 只复用现有 Session/Turn 锁、store、native ingress 和 source-binding admission,没有第二个执行器。队列 GET 是只读投影,按钮或 Command+Enter 才触发效果。

这个设计是 retain:在已有 FIFO 和 live-steering owner 上增加一个有明确撤回条件的 reservation,而不是新建调度链路。发送前先持久化 pending reservation;只有匹配的 delivered receipt 才将原排队 Turn 视为成功,确定未送达才释放 FIFO,不确定结果继续占用容量并禁用自动 claim。当前 PR 边界为文本 steering;附件保留排队,编辑/取消和真实宿主采纳留给后续。

具体改动 / Changes

相对最新 main 2852eb453b,完整 diff 为 25 个文件、+1026/-77:前端队列投影与交互、TS 决策、Python HTTP/store/native adapter、打包浏览器 fixture、测试及模块预算校准。现有 attached-host、普通 FIFO、native steering 和 history recovery 均保持原 owner。

规范依据为 docs/reference/goal-chat-continuation.md,spec_revision=2852eb453bef7731370e156ea5047e67090d549a。其中 QUEUE-VISIBILITY 要求待处理输入在暂停或 native 完成后仍可见;STEER-EXACT 要求立即 steering 精确绑定当前 Turn 且拒绝不降级为 queue;UNCERTAIN-DELIVERY 要求丢失 ACK 时保持 uncertain、不自动重放;IDENTITY-PRESERVED 要求保留原 Session、Turn、client request 与消息身份。VISUAL-BODY 复用 Dashboard 的 Body M 正文 token。

关键代码讲解

  • queue_api.py:9 的 _session_queue 从原 Session 的持久 Turn 读取 240 字符预览、长度、附件数和 reservation,并沿用原 Session context/source admission;它不启动 native 工作。
  • chat_queue_steering.ts:45 的 planQueuedChatSteering 对相同操作的重放先结算,对 pending 冲突和错误 target 拒绝,只在 receipt 明确 delivered 时完成,未知原因保持 unresolved。
  • chat_runtime.py:1291 的 steer_queued_turn 在 Session/Turn 文件锁内先写 reservation,再调用现有 steer_active_turn,最后根据持久 receipt settle;异常文本本身不能释放队列。
  • conversation-queue.tsx:10 的 QueuedMessage 仅在用户展开时读取完整消息,普通 Enter 继续排队;显式 steering 失败显示可恢复状态而不构造 assistant ACK。
  • conversation-queue.css:15 把展开正文恢复到 --text-body / --leading-body;预览和元数据保持 caption。

对主干的风险 / Risks

最强回归是 native 已收到 steering、但响应丢失后重试又发一次,或 pending reservation 被 FIFO 消费。TS decision 在未知 receipt 时返回 unresolved,Python 的 selectQueuedChatTurns 排除 pending reservation;真实 HTTP/store/runtime 的 cold-controller 测试验证第二次请求仍只看到原 reservation、没有第二次 native steer,且自动 claim 返回空。

17 项 queue Python 测试和 3 项 TS decision 测试在 d22d1e6360 通过;真实 HTTP/file store、native stdio、Session/Turn 锁、附件拒绝、源范围撤销和完成后的幂等 replay 都覆盖。packaged attached-host-follow-up 在 64.0s 内通过,桌面与 390×844 均实际测得展开正文为 14px/20px;composer-session-admission 与 chat-recovery 也在当前 head 分别以 8.5s、64.9s 通过。

kernel mypy 17 文件、Todo mypy 2 文件、control-plane typecheck、完整 Dashboard/Chat 构建、CSS token 与 changed-file Ruff 均通过。本地 premerge 的 4 个 direct checks、Python compile、语义/公开边界和 8 个 risk smokes 通过;唯一的阻塞失败仍是 todo-readmodel-boundary-smoke.py,并在最新不可变 main 2852eb453b 的干净 worktree 上以相同的 loopx.status.open_todo_items AttributeError 复现。maintainability ratchet 本轮命中的是未触及的 work_items/interaction_contract.py,工具将其标为 inherited advisory。CLI output differential 同样在冻结 base probe 上、尚未进入本 head 时失败,缺失键固定为 interaction_contract / scheduler_hint / selected_todo。这些均保留为独立 merge-readiness 风险,没有降低或改写 oracle。

队列呈现文件相对先前 reviewed head 没有变化;当前 head 重新生成了相同的打包桌面/窄屏截图并再次通过计算样式断言,因此 PR 中的视觉观察仍绑定原捕获 revision,而交互与构建资格已在新 head 重跑。

语义与 CI 对齐

本 PR 扩展的是既有 queue / steer 词汇和 Turn identity,不是新的通用 actor 或 authority。默认 Enter 仍排队;只有显式操作才 steering;拒绝保持失败,未知结果停留在原队列。loopx_chat_queue_steering_v1 是局部 typed reservation schema,没有新增 provider 或持久 authority。

我的整体评价 / Verdict

APPROVE。 当前精确 head 没有未解决的阻塞 finding。长期任务维度改善:原 Session/Turn/消息身份和不确定投递保留,避免重复执行与无界 FIFO 消费。用户体验维度改善:用户能在原对话核对原文并在一次显式操作中交给当前回合,不必复制重发;正文尺寸已达到 Body M,桌面与窄屏的队列内部滚动和 Stop 均保留。旧捕获来自 a69 的同一队列界面;当前 head 的这些呈现文件与其逐字一致,并在 d22 重新生成相同布局、重新通过计算样式断言,因此保留原视觉观察而不宣称过期的布局证据。未验证真实模型采纳、installed App、真实附着宿主、macOS 拼音和绑定 Lark 会话。

代码体量较大但边界内聚:新的 TS 决策替代散落判断,Python 只承担 store/native IO;没有第二执行器或新的调度系统。当前无需在合并前继续简化,附件转换、编辑/取消和真实宿主采纳保持明确非目标。

English verdict: APPROVE — head d22d1e636009529a30215c86af017a3d8a80a4d5 delivers explicit persistent-queue steering with exact Turn identity, uncertain-delivery protection, and correct expanded-body typography. The changed invariants pass real HTTP/store/runtime and packaged desktop/narrow validation; the remaining premerge failures are reproduced on the immutable base.

@huangruiteng
huangruiteng merged commit f0a668c into main Nov 5, 2026
14 of 15 checks passed
@huangruiteng
huangruiteng deleted the codex/chat-persistent-queue-20261104 branch November 5, 2026 04:00
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.

2 participants