Skip to content

fix(workspace): keep one Chat observer and compact completion feedback - #8144

Merged
huangruiteng merged 14 commits into
mainfrom
codex/workspace-20261105-190217
Nov 6, 2026
Merged

huangruiteng merged 14 commits into
mainfrom
codex/workspace-20261105-190217

Conversation

@loopx-agent

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

Copy link
Copy Markdown
Collaborator

Goal And Delivered Outcome

  • A completed Todo record now says 已标记完成 / Marked complete, without repeating the task title or claiming that an external operation finished.
  • Background replies stay in Chat. Overview, Tasks, Research and Artifacts remain readable. Chat activity survives leaving an Agent's managed Session, stays within that Goal, and clears when its exact Turn ends.
  • Original sends, native queued-start recovery and history refresh reuse one Session/Turn observer. Queue editing, Command+Enter steering, full history, unsent drafts and exact Stop retain their existing owners.

Author Declaration

  • Written by: model_agent — OpenAI Codex (GPT-6 family).
  • Basis: the reproduced completion, overlay, duplicate-observer and managed-navigation defects; docs/development/design.md and docs/development/frontend-delivery.md. No separate specification or broader completion claim.
  • Target: main at 6e55993023fe46fc5c5995730fe6af19757c51a3. Tested head: 35b84cb700f481aa560921f1a84261cf6e687487. The integration retained main’s collaboration return reader, current maintainability baseline and telemetry changes, and resolved the only import conflict by keeping returnedAnswerStart while removing imports used solely by the deleted conversation tray. The final diff is 21 files, +280/−275.

Scope And Ownership

User-visible result Existing owner Decisive evidence
Accurate compact completion Confirmed action result and stored Todo operation Complete/cancel, dependency, bilingual, negative-operation and durable readback cases
Quiet reading views with honest activity Existing runtime bindings and typed conversation keys Real managed Turn, four reading views, 390px, another conversation, Back and exact Stop
One original reply and control target Existing Session/Turn observer registry Pre-ACK, queued-before-start, native history polling, queue advancement and recovery
Preserve queue edits and drafts Native queued-input revision owner and existing composer Main's queue-menu fix retained: Escape/IME, local storage failure, reload, attachment, explicit save/cancel and no extra native execution

No new observer, poller, execution provider, configuration or shared vocabulary is added. The activity change is a TypeScript projection of already observed runtime state. It creates no permission or execution authority.

The same proposal repairs its demonstrated validation boundary: loopx.status.open_todo_items and todo_item_task_class again export their original Todo-summary functions for active public callers. The runtime-handoff machine smoke now keeps child JSON inline instead of consuming model-context navigation, and the proposal no longer deletes the current-main chat_agent.py maintainability exception. No frozen limit or semantic oracle is relaxed, and no Python decision owner is introduced.

Validation

Final source is frozen at the tested head above. All ordinary source and packaged checks below use synthetic/public fixtures; native peers are protocol fixtures, with no live model or user Session.

Check Result
Production dashboard / Chat bundle, strict dashboard and root TypeScript passed; source freshness verified
Repository Ruff and configured strict mypy passed; all 17 configured files
Focused workspace contracts Todo completion wording, 12 steering/keyboard cases, drawer/readback and status facade smoke passed
Packaged journeys managed Agent Sessions, conversation activity, completion user action, composer admission, attached-host follow-up, history recovery, Chat recovery, Goal draft, locale and chat Todo proposal passed; the Todo scenario had one earlier batch timeout and then passed on two isolated runs
Required status / handoff boundary todo-readmodel-boundary-smoke.py and runtime-handoff-status-read-path-smoke.py passed with the existing semantic assertions
Standard premerge final exact head passed all four direct checks, changed-Python compile, 10 catalog canaries, 8 risk-profile smokes and the 21-file public scan, with zero failures and manual holds
Maintainability final exact head has zero unreviewed findings and no magnitude regression; current-main compatibility facades are retained
DCO every current commit has a Signed-off-by trailer

Earlier failures remain evidence: the original observer regression had two subscriptions; a queued-start repair initially lost Stop; required status validation exposed removed exports; and the managed-navigation check failed when activity vanished. The final integration also exposed a stale baseline deletion and a machine smoke that consumed model-context navigation; both were repaired without changing product behavior. One packaged Todo batch timed out before its native assertion; the same unchanged scenario then passed in isolation and again after rebuilding the final bundle. No timeout or assertion was weakened.

The older exact-head review approves 7817de6; it does not approve this head. Fresh exact-head review and GitHub CI are separate. Physical macOS IME, a fresh native Codex UI comparison, live Lark, paid model execution, the installed desktop package and actual user adoption remain unverified. No merge, install or release is performed.

Frontend / Visual Evidence

Primary task: keep reading a selected work view while an original Turn runs, then deliberately return to its full conversation and controls. Zero additional required user decisions. Optional details stay in their existing readers; failures and unknowns remain visible.

The current captures below are actual compiled pages backed by isolated SQLite/Core/Chat and a synthetic native protocol peer. After images use the final tested head: desktop 1716×995 and narrow 390×844. The before image is the same native journey before the activity projection repair. The sparse backend case intentionally retains unavailable delivery evidence; it is not a benchmark outcome or a claim that the Goal is complete. Populated long-message/error/recovery views are independently exercised and inspected in the packaged activity/history journeys.

Managed activity — before

Before: the managed Turn remains busy but the Chat activity circle disappears

Managed activity — after

After: the overview stays visible and Chat retains the observed activity

After: tasks remain readable with Chat activity at 390px

After: full original conversation and unsent draft remain available at 390px

Observed composition: the selected reading view remains the main surface, with a single small activity signal on Chat. Opening Chat restores the original reading column and full content, including long links, current work and draft. Stopping that exact Turn removes the activity signal and retains the draft. The sparse case's delivery-read error remains visible; no reassuring completion summary replaces it.

Retained completion and observer comparisons

These earlier captures remain accurately revision-scoped; their completion/overlay/observer composition is retained in this proposal. Completion: before 5275c5b7, after 6fa9b2acd/27871c348. Observer: before c17affc6, after 7817de6; current observer behavior is revalidated in the final native journeys.

Before: completion repeats the title

After: compact verified record feedback

Before: returning to Chat duplicates the reply and controls

After: one original reply and control pair

Boundary Checklist

  • Public-safe source and captures; no credentials, private state, local machine paths, raw benchmark traces or internal links.
  • Existing TypeScript state/action owners and original Session/Turn retained; no benchmark execution duplicated.
  • No RFC pair changed; bilingual diff check passes.
  • Actual desktop/narrow visual evidence embedded above; proposed source and packaged behavior are distinguished from installed behavior.
  • DCO sign-offs preserved; exact-head review, remote CI and maintainer merge authority remain separate.

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; model=gpt-6.1-sol; provider=OpenAI; runtime_reported; reasoning_effort=max.

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

Exact head: 8144@27871c34825cdbaa0d0bddba2b5558e80e376dae. Base: 7e00a2a9b8e0ee72df7173b90ba06384027e53a7.

动机 / Motivation

用户在概览或任务页阅读工作,同时等待 Agent 回复,或者确认一项本人已办完的任务。旧版后台回复会重新展开浮动对话并挤占工作视图,成功提示还重复整段任务标题;现在工作页保持可读,回复从 Chat 打开,确认回执只说“已标记完成”。已验证后台回复留在原会话,当前 Session 的运行标记出现在 Chat;原生任务操作完成回读后使用简短文案,全文条件和写入审计仍可读取。不改变任务执行权、外部工作的验收、队列策略或宿主安装;不以任务被标记完成推断外部工作已完成。

改动思路 / Approach

保留现有 typed action、Session/Turn 与 Chat owner,删除双浮层状态和重复消息投影;新增信息仅是派生的图标与操作文案,不新增轮询、配置或权限。本 PR 只修复后台会话呈现和任务记录完成提示;任务、执行、重试与写入结果仍由原 owner 负责。不修改保留现状会留下已经复现的重复成本;为此增加独立状态机或另一个策略 owner 反而更重。本次保留现有权威,删除或派生呈现信息,属于可独立核对的完整修复。

后台发送→仍在所选工作页→主动打开 Chat→在原会话继续;任务确认→原生写入/回读→简短结果。图标与简短文案都不是执行凭据。

具体改动 / Changes

规格依据:docs/development/design.md,修改前 revision 7e00a2a9b8e0ee72df7173b90ba06384027e53a7;同时检查原仓库 frontend delivery/typed owner 的适用边界,未把新文档当作既有验收依据。

关键代码讲解

  • workspaceProposal:从已存储 normalized_parameters 投影 todoOperation;未知值保留,不能凭任务标题分类。

  • completedActionFeedback:仅 todo.update + complete 的已确认成功回执使用新文案;cancel、其他 action 和缺失 operation 走原分支。

  • applyProposal:核对 proposal/目标、接受原生回读并检查 completed 后才显示成功;已提交但投影未同步保持恢复状态。

  • ChannelHeader:Chat 图标由当前会话 runningMessage 或观察到的 LoopX active_turn 派生;准备和纯排队不算执行。

Earn The User's Attention:implemented。常规活动收敛;运行提示来自观察;不把失败、缺少权限或未知显示为成功。 对应上列 owner 与本次真实入口/反例证据。

Responsive Behavior:implemented。桌面与窄屏保持可读,重要操作与失败状态可达。 对应上列 owner 与本次真实入口/反例证据。

Populated Page Review:implemented。用长文本和混合状态检查默认整页以及完整展开内容;视觉判断和自动断言分开。 对应上列 owner 与本次真实入口/反例证据。

14 个文件 +152/-254,主要删除浮层组件、两项 visibility state、重开 effect 和死 CSS;todoOperation 是从已存储参数派生的显示字段,未知操作仍回到通用反馈。

对主干的风险 / Risks

73 项 HTTP/存储测试在 base/head 均通过,配置内 mypy、control-plane TypeScript、Chat 生产构建、Todo SSR smoke 和 workspace contract 均通过。 真实 File/Core 写入先经错误 actor 拒绝和无写入预览;夹具的初始 Markdown 转义错误曾使 canonical 已提交而投影未同步,页面准确显示恢复提示。修正夹具后沿同一提案恢复,完成 receipt 与完成时间不变,依赖变为 open。撤回记录保留 decision_outcome=cancel 且依赖仍 blocked,文案仍为原有“已完成:不再需要…”,不会误用新提示。

同条件编译页面在基线仍出现 1 个浮层、当前为 0;1512/390 的四个 Goal 视图均保留状态但不重开对话。不同 Goal 不继承图标;reduced motion 为 none,纯排队重载后没有运行标记。503 与恢复提示仍可见。HTTP/SSE 是真实传输,执行器事件是合成的;自制桥接夹具的连接重放/终止不用于认证真实模型 terminal 行为。

原始维护性检查在 base/head 的完整输出逐字节相同:2 项 compatibility facade、1 项超大决策函数,其中 1 项未审阅,幅度回归为零。失败位于本 PR 未改变的 _admitted_interaction_next_cli_actions。其原始失败未被改写成通过;strict change-quality receipt 保持 fail。 todo-readmodel-boundary-smoke.py 在两侧均因 loopx.status.open_todo_items 缺失失败;仅规范化 checkout 路径后完整 traceback 相同,相关 owning files 未改动。premerge 保持 FAIL,不能由 UI/HTTP 的通过豁免。 这些失败已独立归因到未改变的基线 owner,改动本身有单独通过的必要证据;代码评审结论与质量/合并 gate 分开。远端 CI 未查询、未轮询、未等待。

语义与 CI 对齐

复用现有 action kind、operation 和 Session/Turn;仅本地显示字段新增。 diff advisory 和完整语义检查通过,没有新增共享枚举或更改 hard obligation;失败验证没有被放宽,未改变 agent 的权限或 stop 条件。

我的整体评价 / Verdict

长期持续工作:preserved。保留原生操作、完整任务和会话身份,导航不重启工作;真实 File 操作恢复沿用同一完成 receipt 和完成时间,取消请求保留其依赖为 blocked。没有把图标、测试数或任务完成计为长期接受成果。用户体验:improved。桌面概览恢复单一工作层级,窄屏不再被回复浮层占据;完整长回复在 Chat 仍为可读正文,调整/中断操作可达,源错误和提交后回读失败仍可见。本 PR 只修复后台会话呈现和任务记录完成提示;任务、执行、重试与写入结果仍由原 owner 负责。保留原 owner 是必要且更小的实现,代码量与问题相称;没有需要本 PR 再引入的架构层。

视觉/使用边界:桌面概览恢复单一工作层级,窄屏不再被回复浮层占据;完整长回复在 Chat 仍为可读正文,调整/中断操作可达,源错误和提交后回读失败仍可见。 未验证范围:安装版 WebView、真实模型执行和其 terminal 事件未验证;浏览器执行器事件是合成的,File 任务写入及回读是真实的。 没有对真实模型或安装版作通过声明。

未发现本 exact head 新引入的阻断性实现问题。必需 premerge 与 strict change-quality 仍阻止合并。本次不执行 merge、dismiss、resolve、安装或模型任务。

English verdict: APPROVE for this exact head; independent validation and merge holds remain in force.

Signed-off-by: LoopXAgent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopXAgent <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>
@loopx-agent loopx-agent changed the title fix(workspace): keep background replies in Chat and clarify completion fix(workspace): keep one Chat observer and compact completion feedback Nov 6, 2026

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

未发现当前 head 的阻塞性代码问题。审查针对完整 18 路径,旧 head 的一次重复控件失败保留;以下结论来自新 head 的重新核验,不沿用旧批准。代码结论与仍失败的质量、合并门禁分开。

动机 / Motivation

在 Goal 工作区查看任务和背景回复的用户。原先后台回复覆盖概览等工作视图,跨 Goal 返回又可能多出一组回复控件;当前改为 Chat 入口显示活动,并让同一 Session/Turn 复用原订阅。已观察到工作视图保持可读、基线两组控件到当前一组,以及任务完成后依赖解锁并可刷新回读。本 PR 不证明外部业务已完成,也不声明安装包、付费模型或长期总成本收益已合格。

改动思路 / Approach

原 owner 统一订阅与回读,比另建同步状态或轮询器更小;active controls 和只读 observation 分工仍清楚。当前 PR 边界是工作视图、原 Session/Turn 的展示/控制复用、真实任务记录反馈及一个不扩权的 TS 类型收窄。只把浮层隐藏会留下普通 Goal 恢复时的重复订阅;现在发送和恢复共用原 Session/Turn 的 observer registry。这个 registry 记住的是订阅的 AbortController,不是新的执行权限。activeTurnIds/streamControllers 继续负责当前控件,queued receipt 仍不代表已经运行。

完成文案也不从标题推断状态。原 ChatActionService 和 canonical Todo owner 确认结果后,完整提案的 normalized operation 决定用“已标记完成”还是保留其他操作的结果文案。它不会把用户点了完成解释为外部业务验收。

具体改动 / Changes

规范依据:docs/development/design.md,不可变 revision 54e26effd9cc958179b9fe555d50ba22d13538a6;同时检查同 revision 的 docs/development/frontend-delivery.md。以下按条款命名审查锚点,文档本身没有这些编号:earn-the-users-attention 已实现,四个工作视图不再被后台答复覆盖;task-first-delivery 已实现,原操作 owner、结果及刷新回读仍可达。这个有界修复不声明整个 Workspace 或长期研究目标完成。

关键代码讲解

  • completedActionFeedback 只匹配 todo.update 与 complete;未知 operation 和撤回保留原结果文案。三个已有成功回读路径调用它,拒绝或 stale 分支不会借此显示成功。
  • PersonalWorkspacePage 删除 tray、自动重开 effect 和重复消息投影;Chat 的活动来自同一 Session 的实际 pending Turn 或原 LoopX active Turn。排队计数不参与“正在回复”的判定。
  • PersonalGoalHome 的恢复分支 在覆盖 Session 缓存前保存原身份;已有 observer 时复用 controller,并在原生 queue 已推进时采用原消息行和控件,不再附加恢复订阅。
  • onPhase 与 finally 把 queued/start 的原观察者登记到同一个 map;清理比较 controller identity,旧回调不能清掉新 Turn 的控件。native thread 收窄 只在原 membership 检查前明确字符串类型,不改变恢复授权。

对主干的风险 / Risks

最强反例是 queued ACK 先返回、Turn 已启动而 Session read 仍在进行,随后跨 Goal 返回。独立 Ego/真实 HTTP/SSE 的干净对照在不可变旧基线显示两组“调整本轮”,当前 head 显示一组,业务 Turn 始终只有原来一个。旧基线的相关 UI/fixture 源与本次 main 对应源逐字相同。早期未等待恢复回执的采样及受旧页面请求污染的连接计数均保留为非判别证据,未挑选为通过。

实际编译页面的四视图、390px 长答复、reduced motion、Stop 保留未发送草稿、终态和 queue-only 无活动提示均通过。合成流没有原生 15 秒心跳,后续重连与既有 45 秒 watchdog 一致;累计连接数不能替代同时 observer 的证据,也不据此声称长期零重试。该 watchdog/cursor 客户端未被本 PR 修改。

验证 结果与边界
当前生产 Chat bundle、严格 dashboard/root TypeScript PASS
当前 binding / 原生 steward 恢复 PASS:55 / 60;隔离协议 peer,无付费模型
原 73 项 HTTP/store/subprocess steering 与 Todo SSR PASS:在旧 head 执行;测试、底层 owner、完成 UI 和依赖 manifest 字节一致后复用,新增 observer 单独验证
真实 Core/File 任务操作 PASS:完成解锁依赖,撤回保持暂停,独立刷新回读;相同 owner/反馈源的受控复用
必需 premerge FAIL:Todo/status facade;4 项 direct、8 项 risk smoke 和 18 路径 public scan 通过

语义与 CI 对齐

uv run --extra test python examples/control_plane/todo-readmodel-boundary-smoke.py 在实际 base 54e26effd9cc958179b9fe555d50ba22d13538a6 与当前 head 同样于第 101 行失败:loopx.status 缺少 open_todo_items。PR 不改该因果路径,当前改动有上述独立覆盖,因此这项先存失败不构成代码拒绝理由;required 检查本身仍失败。raw maintainability 仍是失败,native 分类为 advisory_inherited_failure,没有把它改名为通过或给作者补豁免。严格 CQR cqr_33891b55b9efb9e59f49 仍为 fail;不合并、不放宽门禁,未查询 CI。

我的整体评价 / Verdict

long_horizon:improved,原身份、草稿、依赖与明确操作结果持续保留,导航未重发业务工作;不把测试数量当完整成本收益。user_experience:improved。已看实际编译页面:工作内容保持主层级,活动收敛到 Chat;长回复及操作仍在完整对话,窄屏控件与结果可读。未验证范围:物理 IME、live Lark、安装包、付费模型、完整长期成本与生产原生长时间连接未测试;未把 bounded Todo 投影当完整项目证据。

完整范围与机制相称:删除重复投影,扩展原订阅 owner,复用现有 operation vocabulary,不引入持久状态、配置或新的 actor 生命周期。兼容性保留原历史与回执;当前没有必须再抽象或重写的部分。APPROVE 只适用于 7817de6dd5c70b1c75090fdd00d8f987c3b181c1 的代码审查,严格质量资格和合并仍然 held。

English verdict: APPROVE — 7817de6dd5c70b1c75090fdd00d8f987c3b181c1; the original conversation/control path and truthful completion are covered. Pre-existing required validation and strict quality holds remain.

@mergify

mergify Bot commented Nov 6, 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 6, 2026
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>
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 6, 2026
@mergify

mergify Bot commented Nov 6, 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 6, 2026
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@mergify mergify Bot removed the needs-rebase Mergify: the pull request has merge conflicts with its base branch label Nov 6, 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; model=GPT-5; provider=OpenAI; self_reported; reasoning_effort=unavailable

Maintainer approval conclusion

未发现阻断当前改动的 finding。 Reviewed head: 35b84cb700f481aa560921f1a84261cf6e687487; verified target main: 6e55993023fe46fc5c5995730fe6af19757c51a3.

动机 / Motivation

A user reading Overview, Tasks, Research or Artifacts while an Agent Turn runs must keep the current work surface; a confirmed Todo completion must report only the record change. Background replies stay in Chat, the current Goal keeps one activity signal, and a complete operation reports “Marked complete”. Previously a pending reply opened a floating conversation tray over the selected work view, and returning to the session could attach another observer and expose duplicate controls. That both interrupted reading and repeated work that was already authorized. The change keeps the chosen view, moves reply reading to the explicit Chat entry, preserves the original Session/Turn and draft, and makes the completion receipt compact without treating a record update as external-business acceptance.

Affected callers are users reading Goal work while an Agent Turn runs, and users confirming a Todo completion. Physical IME, installed WebView, live providers and real model terminal behavior remain unverified.

The smaller mechanism is to delete the temporary tray projection and reuse the existing Session/Turn observer rather than add another sync store. The PR does not qualify physical IME behavior, an installed WebView, live Lark/provider delivery, paid model execution or real native long-connection behavior. It is a justified increment because those operational boundaries remain unmeasured; the next step is installed-host and live-provider qualification under the existing workspace acceptance.

Non-goals: The PR does not claim external business completion, a new execution provider, broader permission, live provider behavior or installed desktop acceptance.

改动思路 / Approach

The UI now has one reading hierarchy: Overview/Tasks/Research/Artifacts remain visible, Chat carries a small active indicator, and opening Chat restores the same conversation. runtimeBindings supplies a display-only running signal scoped to the selected Goal; queued-only messages and preparation do not count as execution. The original observer map is keyed by exact Session and Turn, so queue admission, native start and history recovery adopt the existing stream/control row instead of opening a second one. Completion wording is derived from the stored todo.update operation and is called only after the action owner confirms the exact proposal and accepted readback.

The architecture decision is retain: the existing runtime binding, observer controller, typed action proposal and canonical Todo owner already express the required facts. The current PR boundary is the workspace Chat projection, the one observer/control path and compact completion feedback; no permission, scheduler, persistence or provider contract is introduced.

场景 基线 本 head
后台回复运行时停留概览 浮动 tray 覆盖工作视图 工作视图保持,Chat 显示活动
恢复同一 Session/Turn 可能再挂一个观察流和控件 复用原 controller 与消息行
Todo complete 成功回读 重复任务标题 只显示“已标记完成”
cancel/未知 operation 通用结果 保留原通用文案,不推断完成

具体改动 / Changes

本轮全新审查最终 21文件 +280/−275,没有继承 7817de6 的旧批准。最终 head 合入 main@6e559930,冲突只在 personal-workspace-page.tsx 的 import 区;保留 #8139 的 returnedAnswerStart,移除只供已删除 tray 使用的两个 import。集成还撤回一项过时的 chat_agent.py baseline 删除,并让 machine-only handoff smoke 显式使用 inline JSON。

规范依据:docs/development/design.md,spec_revision 6e55993023fe46fc5c5995730fe6af19757c51a3,源码 token 为 docs/development/design.md。以改动前条款判断:

  • Earn The User's Attention:implemented;后台回复留在 Chat,工作视图与唯一 running 提示由 PersonalGoalHome/ChannelHeader 提供。
  • Responsive Behavior:implemented;桌面和 390px packaged journeys 保持工作视图、完整 Chat 与操作控件。
  • Populated Page Review:implemented;长历史、失败、Stop、draft、四视图和 mixed activity 通过 packaged assertions 与既有 complete-state captures。

关键代码讲解

  • completedActionFeedback 只在 todo.update 与 operation=complete 同时成立时返回紧凑文案;标题和未知操作无法触发该分支。
  • workspaceProposal 从 canonical normalized parameters 复制 Todo operation,作为显示字段;它不参与执行授权。
  • turnObservers 用 sessionId:turnId 管理原观察 controller;恢复、queued-start 与 finally 用同一身份比较并清理。
  • ChannelHeader 在 Chat 标签内显示 typed activity,且保留可访问名称;准备和纯排队不激活。
  • observedConversationRunning 只投影当前 Goal 已观察到的 running binding,不读消息文本、不创建轮询或执行权。

对主干的风险 / Risks

最强反例是 queued ACK 已返回、native Turn 已开始、Session read 尚未完成时跨 Goal 返回:旧代码会同时保留 recovery observer 与原 stream。最终实现对 exact Session/Turn 复用同一个 controller,并以 controller identity 清理,避免迟到回调删掉新 Turn 控件。另一个风险是把任何 todo.update 都称为完成;当前只有 stored operation complete 且 action owner 成功回读才进入新文案,cancel 和未知 operation 保持通用结果。

Final exact head PASS:dashboard/Chat production build、strict TypeScript、configured mypy 17 files、Ruff、control-plane TypeScript、Todo ownership/12 steering cases、Todo/status boundary 与 standard premerge。Packaged File/SQLite journeys passed for managed Agent Sessions, conversation activity, completion action, composer admission, attached-host follow-up, history recovery, Chat recovery, Goal draft, locale and Todo proposal. The Todo scenario had one long-batch timeout, then passed twice in isolation and again after the final bundle rebuild; the failure and retry remain recorded rather than erased.

Remote Python CI fails at tests/test_chat_codex_history.py with three F811 findings before shard execution. The same complete Ruff command produces the identical three diagnostics on main@6e559930 and the reviewed head; that file is unchanged and the changed Python paths independently pass. It remains a separate repository diagnostic and is not reported as CI success.

语义与 CI 对齐

The activity is a derived projection of typed runtime bindings; it does not become a new actor, lifecycle or execution fact. Completion text is a local presentation policy after existing action authority, and the status facade delegates to the canonical Todo-summary owner. runtime-handoff-status-read-path-smoke.py now consumes inline machine JSON so a context-navigation wrapper cannot masquerade as a quota decision. Physical macOS IME, installed desktop, live Lark/provider behavior and real model terminal events remain unverified; quality, review threads, readiness and merge authority remain separate.

我的整体评价 / Verdict

APPROVE 这个有界增量。long_horizon preserves the original Session/Turn, draft, Stop, queued editing and canonical Todo outcome while preventing duplicate observers. user_experience improves because reading views stay readable and a confirmed completion no longer repeats a long task title or implies external completion. The inspected desktop and narrow composition keeps one primary work surface, a small Chat activity signal, reachable full conversation controls, visible failures and unsent drafts.

Visual review reason: reused the current-source packaged desktop and 390px captures for the retained PR UI; every #8144 UI file is byte-identical to the captured head except the reviewed returnedAnswerStart integration from already-merged #8139. Visual unverified scope: physical macOS IME, installed WebView, live Lark/provider delivery, real model terminal events and production adoption.

English verdict: APPROVE 35b84cb700f481aa560921f1a84261cf6e687487 — one observed Chat activity, one original Session/Turn observer and truthful compact completion feedback are verified within the stated source/packaged boundary; unchanged-base CI diagnostics remain separate.

@huangruiteng
huangruiteng merged commit d602248 into main Nov 6, 2026
28 of 53 checks passed
@huangruiteng
huangruiteng deleted the codex/workspace-20261105-190217 branch November 6, 2026 08:35
@loopx-agent

Copy link
Copy Markdown
Collaborator Author

Reviewer: model_agent | model=gpt-6.1-sol | provider=OpenAI | declaration_source=runtime_reported | reasoning_effort=max

Post-merge audit — new actionable finding

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

合并后审计 · REQUEST_CHANGES:发现 1 项 P2 回归。恢复中的原会话离开 Chat 后,其实际 Turn 已结束,Chat 入口仍显示“正在回复”。

Exact head: 35b84cb700f481aa560921f1a84261cf6e687487。比较基线:6e55993023fe46fc5c5995730fe6af19757c51a3。审查覆盖当前完整 21 文件差异;没有继承旧 head 的 APPROVE。

发布前读回确认:PR 已于 2026-11-06T08:34:59Z 合入 main,merge commit 为 d602248c53298f256ea72fe75091a39f35c6ae4b。下面的恢复后后台终止反例是本轮独立验证发现的新问题,已确认合入后的三个相关 UI 文件与被测 head 相同,因此按合并后审计发布。REQUEST_CHANGES 表示此反例需要后续代码修复;本条是审计评论,不改变既有审查状态。

动机 / Motivation

受影响的是在个人工作区阅读任务、同时等待原会话答复的用户。旧界面会用临时对话托盘覆盖阅读区,完成任务时还会重复长标题,容易让人误解为实际业务已经执行完毕。本次希望把后台答复保留在 Chat,以准确的轻量活动提示连接回原会话,并把完成反馈改为“已标记完成”。范围不包括新增执行权限、运行模型、安装桌面版本或证明长期收益。

完成记录和原会话观察复用已有 owner,实际完成反馈与持久化结果已经验证;剩余缺口是恢复订阅退出后的活动提示没有跟随原 Turn 的终态退役,需由原会话投影 owner 后续修复。

改动思路 / Approach

方向合理:让 Session/Turn(原会话及其一次执行)继续拥有工作与事件流,页面只展示已有事实。完成文案读取已确认提案的 todo.update/complete,不从标题猜测;发送、排队启动与恢复通过同一个观察者表复用控制器;阅读区直接移除旧托盘,而非增加另一套开关或后台轮询。

架构判断为保留既有 owner:完成反馈属于确认结果投影,活动提示属于会话观察投影,权限和执行仍由原生服务决定。当前 PR 边界是安静的阅读视图、准确的记录反馈和一个原会话观察者;修复活动投影退役即可,不需要新的监控服务、持久化标志或配置。最强反例正是现有恢复订阅随视图退出,而新的提示却把它留下的历史 running 当作仍被观察的当前事实。

具体改动 / Changes

当前差异为 21 文件 +280/−275:10 个生产文件 +92/−224,其余为测试与验证脚本。主改动删除托盘及样式,保留完整 Chat、草稿、原操作控制和既有确认卡;loopx.status 恢复两个原 Todo-summary 函数的公开导出,未增加 Python 决策 owner。机器验证脚本只让其子进程使用 inline JSON,不改变父进程的模型上下文设置。

关键代码讲解

  • completedActionFeedback 仅在已确认的 todo.update 且操作为 complete 时输出短反馈;取消、其他操作及未知值保留原行为。真实 SQLite/Core/Chat 的完成预览、应用与后续 GET 读回得到 todo_completed,依赖任务从 blocked 恢复 open,界面显示“已标记完成”。
  • workspaceProposal(personal-workspace-page.tsx:706)从已存提案的规范参数带入可选显示字段 todoOperation;本地预览分支也补齐它。该字段没有代替后端授权、来源校验或完成证明。
  • PersonalGoalHome.onPhase(dashboard-page.tsx:2470)把原始发送和 queued admission 的控制器登记到 ${sessionId}:${turnId}。恢复分支命中后复用原订阅及控制目标,排队收据本身仍不等于执行开始。
  • releaseObservation(同文件 1905)与 effect cleanup(2057)说明这次问题的另一半:离开恢复视图会先设 cancelled=true、中止订阅并删除 pending;if (!cancelled) 又让旧 runtime binding 没有退役。
  • observedConversationRunning 新增的全 Goal 聚合只检查 binding 的 running/turnId,无法区分仍在观察的控制器与上述已经退休的恢复订阅,因此把陈旧事实显示为“正在回复”。

规范基于 docs/development/design.md 与 docs/development/frontend-delivery.md,均固定在 6e55993023fe46fc5c5995730fe6af19757c51a3。映射如下:earn-the-users-attention 未满足,已结束的工作仍被显示为正在回复;populated-page-review 已执行,检查了长中英任务、重复长答复、未完成/受阻/完成反馈、读取失败和未知成本;task-first-delivery--从用户任务开始 的原确认、结果读回与继续工作路径保留,未增加用户必需输入轮次。

对主干的风险 / Risks

[P2] 原会话恢复订阅退出后,活动提示无法跟随实际终态清除

复现不需要真实模型:运行 uv run --extra test python examples/personal-workspace-browser/managed_agent_fixture.py,通过它的真实 Chat HTTP 入口向原 managed Session 外部提交包含 wait for interrupt 的消息;在 App 打开该 Session,等恢复的 pending 与中断按钮出现;切到概览,再通过原 Session/Turn 的 /interrupt 入口结束执行。独立 GET 已确认 session.status=ready、active_turn_id=null。两次会话索引 GET 成功后,当前 head 仍有 1 个 .personal-chat-activity,pending 为 0;基线相同步骤的提示为 0。1512px 和 390px 均能看到该错误,旁边的最近活动已经变为“暂无观测到的活动”。

最小修复是让这一提示绑定仍有效的原 Session/Turn 观察生命周期,或者由既有会话 owner 的当前终态更新投影;不能简单在所有导航时隐藏活动,否则会丢掉本次要保留的正常后台提示。请在 managed-agent-sessions 补上“外部启动或刷新恢复 → 离开 Chat → 原 Turn 在后台结束”的断言,同时保留“仍运行时可见、普通发送只有一个观察者、原 Stop 目标不变”的正例。新增场景后可运行 LOOPX_PERSONAL_WORKSPACE_SCENARIO=managed-agent-sessions LOOPX_PERSONAL_WORKSPACE_PACKAGED=1 node examples/personal-workspace-browser-smoke.mjs。

独立验证:当前 head 与基线生产 Dashboard/Chat 构建 PASS;当前 head 的 root TypeScript 检查、62 个 binding/queue TypeScript 用例、11 个真实 Todo owner/导出用例、Todo ownership smoke、runtime-handoff status smoke、配置内 17 文件 mypy、Ruff,以及标准 premerge 的 4 项直接检查和 19 项选择检查 PASS。真实完成确认/依赖恢复 PASS;上述终态活动断言 FAIL。旧 73a190f 的 169 个 HTTP/queue 用例属于历史证据,不冒充当前 head 的完整重跑。当前 head 和基线的反例对照均按“恢复、导航、终止、独立读回”的顺序完成。

语义与 CI 对齐

复用现有 typed status 和 conversation key,没有新增共享词汇或 opt-in/default-off 声明。类型正确并不能保证状态新鲜度,P2 是投影生命周期问题。完成反馈只确认记录变化;机器脚本关闭子进程模型导航属于验证传输修复,不扩大生产权限。未查询或等待远端 CI,也未放宽预算或检查以获得 PASS。

我的整体评价 / Verdict

该改动在机制和代码规模上适合这个问题,完成反馈与安静阅读路径有实际价值;但当前活动提示有可重复的用户体验回归,因此记录为合并后的可行动回归。长程执行与原会话持久结果在本次有界路径中保留,用户体验判断为 regression:误报会让用户继续等待或返回 Chat 核实。

实际视觉检查覆盖 8 条中英混合任务、长重复答复、完整说明/确认面板,以及桌面 1512×982 和窄屏 390×844 的错误与完成状态。主体内容、完整阅读入口、未知值和失败仍可访问,陈旧“正在回复”是剩余失败。未验证范围:物理 IME、真实 Codex/Lark、安装后的桌面行为、实际用户采用及长期成本收益。后续修复需让新增反例通过,再审查新的 exact head;本次未执行合并。

English verdict: REQUEST_CHANGES (post-merge audit) — retire the recovered Turn's stale activity projection after its real terminal state.

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