feat(dashboard): polish frontstage goal-channel state legibility (GH-C49) - #3663
Conversation
|
Paused; only #3662 remains active. |
Clarify the local goal-channel demo fixture and ops board so outcome, lease, capability-wait, and workspace-repair stay scannable while browser data remains read-only. Signed-off-by: Shize Li <lose.nature@gmail.com> Co-authored-by: Cursor <cursoragent@cursor.com>
4da2a17 to
0e3f382
Compare
|
Reopened after capacity pause. Pre-open audit vs current main: no file conflicts, no GH-C49 collision. Rebased clean onto upstream/main. |
huangruiteng
left a comment
There was a problem hiding this comment.
详细中文评审
评审对象:0e3f3827cb8164fddf6a1090bd81d38a08b1d377
1. 动机
这个 PR 想完成 GH-C49:在不增加浏览器写权限的前提下,让 /frontstage?mode=ops 更容易扫描 delivery outcome、lease、capability-wait 与 workspace-repair。这个问题是真实的 operator 可读性问题;改动也明确保持 showcase 首页首屏和 README 不变,并继续把 event ledger 作为 source of truth。
2. 改动思路
实现分为三层:
goal-channel-frontstage.ts扩充 synthetic read-only fixture,加入latest_delivery_outcome、capability/workspace todos、capability gate,以及带lease_until/write_scope的 lease。frontstage-page.tsx增加状态 tone helpers、deriveOperatorStateSignals()和新的 Operator State Legibility panel;Todo action kind、timeline classification 与 active claims 也获得更强的 badge 呈现。- route/browser smokes 与两份产品文档补上新的 fixture/anchor;browser smoke 另外把 showcase 首项断言改为从 catalog 派生,避免固定标题。
正向路径是清楚的:sample projection 的 outcome_progress、hard lease、capability wait 和 workspace repair 会出现在只读 ops board;用户仍只能通过 relative/loopback status source 读取,浏览器没有新增 write authority。视觉上我独立运行并查看了 desktop ops screenshot,新 panel 与现有紧凑 operator layout 一致,showcase 首屏未被这组改动改变。
3. 具体改动
goalChannelLeaseSchema/GoalChannelLease新增lease_until和write_scope,live payload 可保留并渲染这两个字段。- sample fixture 新增 outcome、capability-wait、workspace-repair、hard/soft lease 与对应 timeline events。
statusTone()改为大小写归一化;TodoRow()把 action kind 提升为独立 badge;timeline 和 claims 使用新的 tone helper。deriveOperatorStateSignals()从 source refs、events、todos、gates、leases 推导四个 operator signals,并由新 panel 展示。- route smoke 断言新增 helper/fixture/anchor 的源码存在;browser smoke 保持全路由视觉与 public/private boundary 覆盖。
- roadmap 与 interaction baseline 登记
frontstage-operator-state-legibility作为当前 acceptance anchor。
4. 对主干的风险
这里有一个阻塞问题:新的 operator state 分类依赖 substring 和自然语言 title,而不是 typed state semantics。具体位置是 apps/presentation/dashboard/src/views/frontstage-page.tsx:393-508。
actionKindTone()只要 action kind 包含delivery或outcome就显示 success,因此delivery_failed、delivery_blocked一类合法扩展 token 会被染成绿色。eventClassificationTone()对任何包含outcome的 classification 都显示 success;deriveOperatorStateSignals()又让任何非空latest_delivery_outcome都显示 success,所以控制面已有的outcome_gap与surface_only会和primary_goal_outcome一样被呈现为成功。- capability/workspace signal 还回退到
todo.title.includes(...)。普通的“document workspace behavior”或“review capability catalog”任务会被误判成 repair/wait;相反,新的同义 action kind 也可能漏判。
这不是纯视觉偏好:该 panel 面向 operator,错误的绿色 outcome 或虚假的 wait/repair 会改变人对当前控制面状态的判断。仓库规则也明确要求 state-classification/delivery-semantics 通过 typed enum、schema 或 transition/read-model helper 表达,不能由 prose/substring 猜测。
最小修复是把分类移到 typed projection/read-model 边界:对已知 delivery_outcome、todo status/action kind、gate kind 和 lease status 做 exact mapping,未知值保持 neutral;删除 title substring fallback。请加语义测试覆盖至少 outcome_progress、outcome_gap、失败/阻塞 delivery token、普通包含 workspace/capability 文案的 todo,以及未知 token。当前 route smoke 只是 source.includes(...),browser smoke 也没有断言新 panel 的 value/tone,因此全绿检查无法捕获这些 false positives。
代码体量为 +301/-13,其中 +216/-6 落在已经约 4k 行的 frontstage-page.tsx。问题本身值得修,但 state interpretation 继续堆在 view hotspot 中会扩大维护成本;最高价值的 bounded simplification 是把 operator signal derivation 放到已有 data/read-model owner 并用 table-driven semantic tests 约束,view 只渲染结果。以当前 exact head 看,change proportionality 仍是 not_yet_proven:UI 规模不算过大,但新增机制在核心状态判断上会产生错误结论。
独立验证结果:
npm run smoke:frontstage-route:通过npm run build:通过(仅已有的 >500 kB chunk warning)npm run smoke:frontstage-browser:通过,并检查 desktop ops/showcase 与 mobile screenshotsloopx check --scan-path apps/presentation/dashboard --scan-path docs/product/roadmaps/dashboard-frontend-selection.md:public boundary clean;3 个 registry warnings 与本 PR 无关git diff --check与 base/head merge-tree:通过- 远端 DCO、dependency review、Python、Windows/macOS desktop、SonarCloud 与 frontstage build 均通过;deploy/upload-release 按设计 skipped
- 未验证真实远端 status producer;本 PR 也没有引入该写入或 provider 边界
5. 我的整体评价
只读 authority、fixture 覆盖、UI 层级和文档方向都合理,视觉实现也与 LoopX 的 dense/calm operator 标准一致。但这个 PR 的核心目标正是“状态可读性”,而当前 substring/prose 推导会把 gap/failed/普通文案显示成错误状态,且现有 smokes 只证明元素存在,不证明语义正确。因此我对 exact head 0e3f3827cb8164fddf6a1090bd81d38a08b1d377 的正式结论是 REQUEST_CHANGES。请先改为 typed/exact state mapping 并补充 negative semantic coverage;修复后可以重新复审。
English verdict: REQUEST_CHANGES on exact head 0e3f3827cb8164fddf6a1090bd81d38a08b1d377. The read-only ops UI, fixture, docs, build, browser smoke, boundary scan, and remote checks are otherwise sound, but the new operator-state model classifies outcomes/action kinds with substrings and todo-title prose. That can render outcome_gap, failed delivery tokens, or ordinary workspace/capability wording as success/wait/repair. Replace it with exact typed mappings, keep unknowns neutral, move the derivation to the data/read-model owner, and add positive plus negative semantic tests.
Move operator-state tone helpers and signal derivation from the frontstage view into the goal-channel-frontstage read model, and replace substring/prose classification with exact token tables from the shipped control-plane vocabularies: outcome_progress/primary_goal_outcome stay success, outcome_gap/delivery_failed/delivery_blocked render danger, surface_only and unknown tokens stay neutral, and todo titles are display copy only so ordinary workspace/capability wording can no longer flag repair/wait. Cover the semantics with a table-driven frontstage-operator-state smoke (positive, negative, prose, and unknown-token cases) and assert the ops panel value and tone classes in the browser smoke. Signed-off-by: Shize Li <lose.nature@gmail.com>
已改为 typed/exact 状态分类并补正负语义测试新 head: 1. 分类移入 read-model,substring 全部移除(P1 修复)
2. 语义测试(正负 cases,table-driven)新增
Browser smoke 补充 panel value/tone 断言: 校验(无跳过项、无手工 hold)
English verdict: head |
huangruiteng
left a comment
There was a problem hiding this comment.
详细中文评审
评审对象:039c80bb778a9dbb9e16d6255aa879f5a2dc3a35
动机
这个 PR 继续完成 GH-C49:把只读 /frontstage?mode=ops 的本地 goal-channel fixture 中 delivery outcome、lease、capability-wait 与 workspace-repair 做成可扫描的 operator state,同时不改浏览器写权限,也不改 showcase 首页首屏。问题和边界都清楚:原先这些信息分散在 source refs、todos、gates、leases 与 timeline 中,operator 很难快速判断当前结果、占用和等待类型。
改动思路
实现现在分成了正确的三层。goal-channel-frontstage.ts 承担 fixture、schema/read model 和 exact-token tone 映射;frontstage-page.tsx 只消费 deriveOperatorStateSignals() 并渲染 panel/badges;route、semantic、browser smokes 再覆盖源码锚点、分类语义和实际 DOM/tone。相较上一版,把 substring/title-prose 分类移出约 4k 行 view hotspot 是有价值的 bounded refactor,未知 outcome 保持 neutral,普通包含 workspace/capability 文案的标题也不再参与分类。
正向路径已验证:latest_delivery_outcome=outcome_progress 经过 deliveryOutcomeTone() 显示 success;hard/soft lease 经过 leaseStatusTone() 显示相应状态并保留 expiry/scope;typed capability gate/todo 与 workspace repair event/todo 进入四格 operator panel。浏览器仍只读取 demo 或显式的 relative/loopback status source,truth_contract.write_authority 保持 none。
具体改动
apps/presentation/dashboard/src/data/goal-channel-frontstage.ts扩充 demo fixture、lease schema/type,并新增BadgeTone、四组 exact token tables 与deriveOperatorStateSignals();未知 token neutral,todo title 仅作展示。apps/presentation/dashboard/src/views/frontstage-page.tsx增加 Operator State Legibility panel,Todo action-kind、timeline classification 与 active lease 使用语义 badge;Developer onboarding 补 capability-wait 提示。frontstage-operator-state-smoke.ts用 214 行 table-driven cases 覆盖 outcome/action/event/lease tone、gap/failure、普通 prose 与未知 token;route smoke 保留结构锚点。- browser smoke 断言 outcome/lease/capability panel 的 value/tone,并把 showcase 默认项从硬编码标题改为 catalog 首项,降低 fixture 漂移。
- 两份产品文档登记新的 acceptance anchor;
package.json暴露独立 semantic smoke。
关键代码讲解
deliveryOutcomeTone()/eventClassificationTone():用 exact lookup 取代 substring,outcome_progress/primary_goal_outcome为 success,outcome_gap与失败/阻塞 disposition 为 danger,未知值 neutral。deriveOperatorStateSignals():把 source refs、event ledger、todos、gates 与 leases 汇成 outcome/lease/capability-wait/workspace-repair 四个 read-model signals,view 不再自行解释状态。TodoRow()与 Operator State Legibility panel:只负责把 read-model tone/value 渲染为 badge/card,没有增加 mutation 或 authority。runDerivedSignals():已覆盖上一轮指出的 outcome gap、surface-only、title prose 和 unknown-token negative cases。
对主干的风险
仍有一个语义阻塞点:deriveOperatorStateSignals() 把任意 agent todo 的 exact status === "waiting" 都当成 capability wait,即使 action kind 与等待原因明确不是 capability。触发链是:capabilityTodo 的第三个 OR 分支仅检查 status;随后 signal 直接取该 todo 的 waiting 和 title,并染成 warning。独立 negative walkthrough 使用 waiting_on=external_evidence、action_kind=external_review_wait、title=Wait for an independent reviewer.,实际结果仍是:
{"label":"capability-wait","value":"waiting","helper":"Wait for an independent reviewer.","tone":"warning"}
这会把 reviewer、CI、定时窗口或其他 external-evidence wait 错标成缺 capability。它不再是 prose/substring heuristic,但仍把通用 lifecycle status 当成 capability-domain discriminator,违反这个 panel 自己声明的 exact typed semantics。当前 semantic smoke 只覆盖 positive status=waiting + action_kind=capability_wait,没有覆盖“waiting 但非 capability”的 negative case,因此全绿无法发现该 false positive。
最小修复:删除通用 status === "waiting" fallback,或仅在 capability-specific typed action/gate/waiting_on=capability 已成立时把 status 用作显示值;补一例 external_review_wait/external_evidence(或等价非 capability wait)应保持 capability signal clear/neutral 的 semantic case。除此之外,上一轮 blocker 已修复。
验证矩阵:
npm run smoke:frontstage-operator-state:通过npm run smoke:frontstage-route:通过npm run build:通过,仅有既有的 >500 kB chunk warningnpm run smoke:frontstage-browser:通过;独立查看 ops screenshot,panel 的层级、hairline、badge 与 dense/calm operator 标准一致loopx check --scan-path apps/presentation/dashboard --scan-path docs/product/roadmaps/dashboard-frontend-selection.md:public boundary clean;4 个 registry/runtime warnings 与本 PR 文件无关git diff --check:通过;远端 11 个当前 checks 中 9 个 success、2 个按设计 skipped- 未验证真实远端 status producer;本 PR 的已声明主范围是本地 demo fixture/read-only board
体量为 +568/-14:主要是 +250/-3 的 read model/fixture 与 +214 的 semantic smoke,view 仅 +61/-7。对 GH-C49 的 fixture、read-model、UI、validation、docs 五个同域 surface 来说整体可解释,且已把状态 authority 从 view 收回 data boundary;当前不需要再引入新 abstraction。不过在 capability-wait 仍有可复现误分类时,change proportionality 还不能视为完整通过。
我的整体评价
exact head 的方向明显改善:上一轮的 outcome substring、todo-title prose 和 view-hotspot 问题已被正确处理;只读 authority、视觉实现、文档和大部分 negative coverage 都可靠。但 PR 的核心目标就是 operator state legibility,而任意非 capability 的 waiting todo 仍会被显示为 capability wait。这个 false positive 会直接改变 operator 对阻塞原因的判断,因此结论仍是 REQUEST_CHANGES。修掉通用 waiting fallback并补对应 negative case 后,可以快速复审;其余部分没有新的 blocker。
English verdict: REQUEST_CHANGES on exact head 039c80bb778a9dbb9e16d6255aa879f5a2dc3a35. The prior substring/title-prose blocker is substantially fixed, the read-only UI and exact outcome mappings are sound, and local semantic/route/build/browser/boundary validation passes. One typed-state false positive remains: any agent todo with status="waiting" is labeled as a capability wait even when waiting_on=external_evidence and action_kind=external_review_wait. Remove that generic-status discriminator (or require an explicit capability action/gate/waiting_on token) and add the missing negative semantic case.
Signed-off-by: Shize Li <lose.nature@gmail.com>
|
@huangruiteng thank you for the focused follow-up. Updated in ef1095b: capability-wait now requires an exact typed discriminator—action_kind capability_wait/capability_repair, a capability_wait gate, or waiting_on=capability. Generic status=waiting is display-only after classification and no longer establishes the capability domain. Added the semantic negative case “external review waiting todo” for external_review_wait + external_evidence + status=waiting, asserting the capability signal stays clear/success. The existing positive capability_wait case remains warning, and the Round 1 exact outcome-token mapping plus title-as-display-only protections remain intact. The operator-state smoke, route smoke, dashboard build, browser smoke, and LoopX public-boundary check all pass. |
huangruiteng
left a comment
There was a problem hiding this comment.
详细中文评审
评审对象:ef1095bbf5d71636e1936341861ace9efdde1a77
动机
这个 PR 继续完成 GH-C49:让只读 /frontstage?mode=ops 把 delivery outcome、lease、capability-wait 与 workspace-repair 以紧凑、可扫描的 operator state 呈现,同时保持浏览器无写权限、showcase 首页首屏与 README 不变。问题边界清楚,operator 需要从分散的 source refs、todos、gates、leases 和 timeline 中快速辨认结果、占用与等待原因。
改动思路
实现保持了合理的 read-model 分层:goal-channel-frontstage.ts 负责 fixture、schema 和 exact-token 状态解释,frontstage-page.tsx 只消费 deriveOperatorStateSignals() 并渲染 badge/panel,semantic、route 与 browser smokes 分别验证状态语义、结构锚点和真实 DOM/视觉结果。相较最初版本,状态 authority 已从约 4k 行的 view hotspot 收回 data/read-model 边界,未知 token 保持 neutral,todo title 只用于展示。
这次增量 commit 正确修复了上一轮唯一 blocker:deriveOperatorStateSignals() 不再把任意 status="waiting" 的 agent todo 当作 capability wait,而只接受 capability_wait / capability_repair action kind、capability gate 或 waiting_on=capability。新增 negative semantic case 复现了 waiting_on=external_evidence + action_kind=external_review_wait,并验证 capability signal 为 clear / success。
具体改动
deliveryOutcomeTone()、eventClassificationTone()、actionKindTone()与leaseStatusTone()使用 exact lookup;outcome_gap、failed/blocked outcome 为 danger,surface_only和未知值为 neutral。deriveOperatorStateSignals()将 outcome、lease、capability-wait 与 workspace-repair 汇总为四个只读 signal;view 不再通过 substring 或自然语言 title 推断控制面状态。- 最新修复删除通用 waiting-status discriminator,并增加 external-review/external-evidence 的负例,避免把 reviewer、CI 或其他外部证据等待错标为 capability 缺口。
- browser 仍只读取 demo 或显式 relative/loopback status source,
truth_contract.write_authority保持none;ops screenshot 中新 panel 沿用 hairline、compact badge 和 dense/calm operator 布局。 - 两份产品文档登记 acceptance anchor,semantic smoke 成为独立 npm script;没有增加新的浏览器 mutation、provider、permission 或生产写入路径。
对主干的风险
未发现新的阻塞问题。上一轮可复现的 capability-wait false positive 已在 exact head 修复,正向 capability_wait 与负向 external_review_wait 都有语义覆盖。typed-state lens 现在通过 exact helper/table 表达,未使用 substring denylist 或 prose classifier;domain-neutrality、behavior-disclosure 与 guidance-vs-obligation lens 没有发现对通用控制面契约的静默修改。
完整 exact-head 体量为 +590/-14:主要成本是 +249 的 fixture/read model、+240 的 table-driven semantic smoke,以及 +68 的 view 呈现。对同一个 GH-C49 read-only operator legibility vertical slice 来说是 proportionate 的;最高价值的 bounded future-facing refactor已经应用——状态解释集中到 data owner,view 只渲染。当前没有理由再拆出新的 abstraction。
独立验证结果:
npm run smoke:frontstage-operator-state:通过,包含上一轮 blocker 的 external-evidence negative casenpm run smoke:frontstage-route:通过npm run build:通过,仅有既有的 >500 kB chunk warningnpm run smoke:frontstage-browser:通过;独立查看 desktop screenshot,状态 panel 与现有 operator 视觉语言一致loopx check --scan-path apps/presentation/dashboard --scan-path docs/product/roadmaps/dashboard-frontend-selection.md:public boundary clean;3 个 registry/state warnings 与本 PR 文件无关git diff --check与最新origin/main的 merge-tree:通过- 远端 required checks 均通过;deploy/upload-release 按设计 skipped
残余风险是没有用真实远端 status producer 做端到端读取,但本 PR 没有改 producer 或写入边界;schema、synthetic live payload、semantic smoke、browser smoke 和现有 status-source boundary 对这个只读展示改动提供了足够覆盖。
我的整体评价
这个 exact head 已经修复两轮评审中发现的状态误分类:substring/title-prose 推断已被 exact read-model helper 替代,通用 waiting status 也不再冒充 capability wait。只读 authority、视觉层级、语义负例、文档和主干兼容性均符合仓库要求。我没有发现阻塞或需要延后合并的问题,结论为 APPROVE。本次评审只批准,不执行 merge。
English verdict: APPROVE exact head ef1095bbf5d71636e1936341861ace9efdde1a77. The previous capability-wait false positive is fixed by requiring an explicit capability discriminator, and the new external-evidence/external-review negative case proves that generic waiting todos remain clear. Exact typed mappings, read-only authority, semantic/route/build/browser validation, public-boundary checks, visual inspection, and merge-tree compatibility all pass; the remaining live-producer risk is non-blocking for this read-only fixture and view change.
Summary
/frontstagegoal-channel demo fixture so outcome, lease (lease_until/write_scope), capability-wait, and workspace-repair are explicit.Closes #3644
Test plan
npm run smoke:frontstage-route(inapps/presentation/dashboard)npm run smoke:frontstage-browserloopx check --scan-path apps/presentation/dashboard --scan-path docs/product/roadmaps/dashboard-frontend-selection.md/frontstage?mode=opsdemo fixture for outcome / lease / capability-wait / workspace-repair scanabilityMade with Cursor