Skip to content
超凡97 / 100
证据34/35原创24/25结构20/20实用19/20
一盏绿灯到底在说什么?从 Sutando 的协作者进度缺失看 Agent 界面的状态投影边界
数字员工 · 工程研究

一盏绿灯到底在说什么?从 Sutando 的协作者进度缺失看 Agent 界面的状态投影边界

状态不是事实源,而是事实的投影。一个可靠的 Agent 面板必须说明每盏灯来自哪里、针对什么对象、在什么时间窗口内成立,以及它不能替谁下结论。

RSEM-20260827-03工程研究 · 2026-08-27English →

一盏绿灯到底在说什么?从 Sutando 的协作者进度缺失看 Agent 界面的状态投影边界

一个协作者正在真实的实时执行会话里工作,也持续写入进度文件,团队页面却什么都没有显示。

不是网络断了,不是 Agent 没启动,也不是进度数据没有产生。问题只出在一个看似合理的条件:页面先问“是不是任务所有者”,不是所有者就不推送进度。

这是 Sutando 的 PR #3432 记录的公开反例。原来的 should_stream_task() 只允许所有者进入进度推送路径。它背后的理由并不荒唐:普通的非所有者团队任务运行在只读沙箱中,不会更新 core-status.json,因此没有实时步骤可以展示。真正的缺陷是协作者恰好是这个规则的例外——协作者不走那条只读沙箱路径,会真实写入状态文件,却仍被“不是所有者”这个条件挡在界面之外。

也就是说,页面做错的不是一个颜色,而是一种事实替换

把“角色或访问身份”误当成了“是否存在实时执行”。

修复后的差异很小:team + collaboratorfalse 变为 true;普通团队任务仍为 false;所有者仍为 true。PR 新增四个回归用例,但作者也明确保留了一个验证缺口:尚未完成桥接服务重启后的真实端到端见证,因此该 PR 在本文复核时仍是开放状态。

这个例子很适合拿来问一个更一般的问题:

Agent 控制台上的“在线”“执行中”“有进度”“已完成”,到底分别在证明什么?

1. 界面状态不是事实源,而是一份投影合同

多 Agent 面板很容易把许多底层事实压成一个 status。但这些事实本来来自不同来源、不同对象、不同时间窗口:

事实轴它真正回答的问题不能替代什么
查看权限当前用户能不能看这条信息?任务在哪里执行
网关连通性浏览器或手机能否连到当前运行时?某个执行会话是否还活着
会话活性这次执行是否还有新鲜、可验证的活动?任务是否会成功交付
执行进度最近有没有可解释的工作进展?工作内容是否正确
正式报告到达执行结果是否已经形成正式 REPORT?REPORT 是否被接受
任务生命周期任务当前处于 inbox / active / review / done 哪一层?关联证据是否没有冲突

这些事实轴可以同时成立,也可以同时出现矛盾。

例如:网关可以在线,但作业心跳已经过期;执行会话可以已经结束,但正式 REPORT 尚未到达;权威工作流可以是 done,同时某条审计证据仍然是 conflict;用户也可以有权限查看一个任务,却不是这个任务的执行者。

因此,一个可靠的界面状态应该被理解成:

底层事实 → 明确投影规则 → 页面语义

而不是:

页面颜色 → 反推系统真相

这一区别很关键。前者要求页面说明自己依据什么;后者会让“绿灯”逐渐变成一个没有来源的总判断。

2. Sutando 的问题为什么不只是一个进度显示缺陷?

Sutando #3432 的直接问题是协作者进度没有流出来。但更值得注意的是条件之间发生了错位:

text
访问级别 / 所有者身份
        ↓ 被错误替代为
执行位置 / 是否存在实时进度

原规则对普通团队任务的解释是成立的,却被扩展到了一个不满足同样运行条件的协作者。

这类问题在 Agent 产品里很常见,因为很多字段在正常路径中高度相关:任务所有者通常也是执行者;网关在线通常伴随活跃的执行会话;会话结束后通常很快会有 REPORT;任务进入 review 时通常已经聚合了相关证据。

可“通常一起出现”不等于“可以互相替代”。真正危险的缺陷往往就出现在例外组合:

  • 不是任务所有者,但确实存在新鲜的本地执行会话;
  • 网关在线,但当前作业已经失去活性;
  • 执行会话已经结束,但正式 REPORT 尚未写入;
  • 工作流已经 done,但某条证据关联仍然冲突。

因此,界面投影测试不应只覆盖正常路径,还要专门制造这些事实轴之间不再同步的反例组合

3. 我们自己的审计:五类会话观察必须先分开

Sutando 的 PR 不能证明我们存在同样的协作者缺陷。正确的做法不是把外部缺陷直接映射到自己,而是回到自己的读取路径,检查有没有把不同事实压成同一个结论。

在我们当前审计到的会话观察路径中,存在五种互斥输出:

text
executing_with_progress
executing_without_fine_progress
session_without_live_execution
completed_waiting_report
technical_error

这些字段名是实际实现中的状态标识,因此保留英文。它们背后的判断顺序很重要:

  1. 会话为 failed,或恢复状态已经是 session_losttechnical_error
  2. 会话为 completed,但正式 REPORT 尚未写入 → completed_waiting_report
  3. 会话不是 running → 不投影为执行状态;
  4. 会话为 running,但没有实时活性证据 → session_without_live_execution
  5. running 且仍有实时活性,再根据是否存在细粒度进度区分前两类。

这说明界面在生成文案之前,至少可以先拒绝几个常见的错误升级:

  • 没有细粒度进度 ≠ 执行失败;
  • 有会话记录 ≠ 仍在实时执行;
  • 会话已经结束 ≠ 已正式交付;
  • technical_error ≠ 业务任务被拒绝。

第一方源测试中的一个定向测试实际包含 5 个分类断言。早先把它写成“1/1”虽然字面没错,却容易让读者误以为只有一个状态被验证;更准确的口径是:一个定向测试用例,覆盖五种分类结果。

4. 公开证据现在可以自己重跑,而不只看我们描述

为了让这篇文章的核心分类不只停留在私有源码和文字说明里,我们把 R3 物化成了三个公开、脱敏的附件:

公开测试样本提供五条输入,每条对应一种已披露语义;读取器按公开判断顺序复现分类合同;检查脚本对五条记录逐条检查 actual === expected,并同时核对五类计数。

运行:

text
node 2026-08-27-r3-ui-status-projection-check.mjs

预期结果:

json
{"fixture":"deidentified_runtime_session_observation","assertions":5,"status":"PASS"}

这里的边界必须讲清楚:这个公开读取器是披露合同的独立复现器,不是私有生产源码。五条公开断言也不是桌面端、PWA、权限过滤和完整交付链的端到端认证。

它真正增加的是可复核性:外部读者现在不需要相信一句“我们有五类状态”,可以直接检查五条输入怎样被分类。

5. 冲突应该是一等输出,而不是界面要消灭的噪声

状态投影还有另一类危险:当不同来源互相矛盾时,页面为了“整洁”悄悄选一个最顺眼的答案。

我们更倾向于相反的做法:来源冲突本身就是一个需要保留的事实。

例如,在已审计路径中:

  • 权威工作流缺失或来源互相冲突时,可以得到 projection_conflict,而不是从运行时、REPORT 或验收字段猜一个生命周期;
  • 网关是否在线,需要运行时、磁盘配置和上下文身份相互对齐,实例身份不一致时不能默认发布绿色;
  • 工作流已经 done 时,一条证据冲突仍可以单独保留,不能因为任务生命周期已终态就吞掉审计冲突。

这背后是一条很简单的原则:

一个事实轴的确定性,不能替另一个事实轴消除不确定性。

done 回答任务位置;证据冲突回答关联关系是否可靠。把两者压成一个状态,无论最后显示绿还是红,都会损失信息。

6. 每一盏灯至少应该声明五件事

如果状态只是一个颜色加一行文案,开发者很容易在组件里继续拼布尔值。更稳的做法是把每个状态当成一份小型投影合同,至少声明:

声明例子
来源“网关在线”来自运行时、磁盘配置和上下文身份的一致性,而不是 REPORT
对象它描述的是网关、执行会话、任务还是 REPORT
时效这个判断针对哪个时间窗口或版本成立
能证明 / 不能证明能证明连接可用;不能证明执行会话仍有活性或任务已验收
冲突策略来源冲突时显示冲突或未知,而不是回退成绿色

这五项一旦明确,很多界面缺陷会从“颜色不对”变成更容易测试的问题:

  • 当前用户不是任务所有者,但有查看权限且存在新鲜的本地执行会话,进度会不会被错误隐藏?
  • 网关在线、作业心跳已经过期,页面能否同时展示“连接可用”和“执行失活”?
  • 执行会话已经结束、REPORT 尚未到达,是否停在“等待正式报告”,而不是直接显示“交付完成”?
  • 工作流为 done、证据关联仍有冲突,两个事实能否同时存在?
  • 运行时与磁盘中的实例身份不一致,远程页面会不会继续把旧实例标成当前?

这些测试不需要先发明一个更大的全局状态机。它们只要求:每个条件只回答自己拥有证据的问题。

7. 绿色不是结论,只是一个有范围的投影

真正好的 Agent 面板当然需要简单。用户不应该读十几行内部状态才能知道系统现在大概怎样。

但简单不等于把六种事实压成一个万能绿灯。Sutando 的协作者进度缺失很有代表性:一个原本正确的理由,只要被应用到错误对象上,就足以把真实执行隐藏掉。

我们的本地审计也只支持一个有限结论:会话活性、执行进度、REPORT 等待和 technical_error 可以先拆开;冲突可以保留为独立事实轴;这些规则可以被定向测试和公开复现。它不支持“所有界面、PWA 和权限组合都已经正确”的更强主张。

所以,下次看到一个 Agent 状态写着“在线”或“执行中”,更有价值的问题不是“它是不是绿色”,而是:

这条状态来自哪一个事实源?描述哪个对象?对哪个时间窗口有效?它证明了什么,又明确不能证明什么?

如果页面答不出这些问题,这盏灯就承担了超过自己证据范围的权力。


公开证据

来源与证据边界

  • Sutando PR #3432 在本文复核时仍为开放 PR。本文只使用它作为“访问级别或角色身份不能替代执行位置与实时进度”的公开反例。PR 的四个回归用例是作者报告;作者同时明确说明尚未完成桥接服务重启后的真实端到端见证,因此本文不把该修复描述为已经完整生产验证。
  • 第一方 R3 证据支持五类会话观察语义、对应定向源测试和公开脱敏复现器。公开读取器复现的是披露合同,不是私有产品源码;它不证明全部网页面板、桌面端、PWA、查看权限或权限过滤路径都已经通过完整正交性审计。
  • 本文的核心结论是关于投影边界:查看权限、网关连通性、会话活性、执行进度、正式 REPORT 到达、任务生命周期与证据冲突应分别保留来源和语义。本文不据此评价 Sutando 或 CodeFlowMu 的整体可靠性。

Last updated: