Skip to content

feat(workhub): add work identity, prompt status, and keyboard selection - #5198

Open
ARE404 wants to merge 27 commits into
apache:mainfrom
ARE404:feat/workhub-conversation-colors
Open

feat(workhub): add work identity, prompt status, and keyboard selection#5198
ARE404 wants to merge 27 commits into
apache:mainfrom
ARE404:feat/workhub-conversation-colors

Conversation

@ARE404

@ARE404 ARE404 commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

WorkHub identifies each delegated Work with separate message accents (prompt right, answer left), compact colored Workspace / Session labels, and status before the prompt timestamp. Status replaces the standalone delegation result card.

Rail activation first locates the latest loaded conversation for a Work, then filters, then restores all conversations. Mouse and keyboard use the same sequence without a timer. Message stripes directly toggle filtering; identity links open the target Session. Filtering preserves the ChatView instance and applies to historical content, the multi-Turn live buffer and active execution.

The PR implements a pre-admission target selector behind the optional Host routing hook; current production startup does not wire that hook (see real-provider acceptance below). No option is preselected: digits and arrows select, Enter confirms, Esc returns to the preserved draft. WorkHub also supports AskUserQuestion, hydration, answer retry and Stop.

Ownership and UI orchestration

Entry / responsibility Owner and behavior
Send and rejected Retry Existing useWorkHubController submission boundary invokes one presentation callback before submission; WorkHubRoot clears the Work filter. Retry retains the rejected attempt identity.
Unknown-admission recovery Existing controller queries/replays the same attempt idempotently; it does not cross the fresh-submission callback.
Read recovery Reloads the projection without clearing the filter or resubmitting.
Target selection and question hydration WorkHubRoot reveals the interaction locally; a docked conversation stays docked.
Progress expansion The preload contract requires a progress request. Main validates it both before enqueueing and before native mutation. Missing/malformed requests are rejected and stale requests are ignored.
Explicit detach / dock Existing main presentation owner reparents the same WebContentsView. Progress expansion has no fallback detach.
Pending selection and focus The existing mounted choice panel retains answers/selection. Native focus requests prefer that panel and preserve focus already inside it; otherwise they focus the composer.

This removes duplicate filter clearing from Send/Retry handlers and removes the overloaded no-argument show-conversation behavior. It adds no lifecycle state machine or general-purpose controller.

The Host still owns bounded opaque selector offers, fresh candidate binding and durable admitted routing decisions. Action Gate remains the execution authorization boundary. Intent-only clarification stays a normal admitted assistant follow-up. Selection itself neither admits a Turn nor drains the coordinator. The protocol compatibility epoch is 148 against the integrated main epoch 147.

Current verification

Rebased onto main 5049ffc1a. The conflict resolution retains main's transcript commit-scheduler / live-handoff regression and this PR's failed-prompt status and retry identity.

The early-progress-expansion P2 was reproduced through the real main-handler harness: prepareControl → ready → expand(request) left the native window hidden before progress-ready. The existing presentation owner now completes the passive reveal with showWindowInactive, respecting hidden reveal mode. Request freshness checks, explicit placement commands and no-focus-stealing behavior remain unchanged. The regression fails before the fix and passes after it, and also checks late paint / stale expansion after dismissal.

  • Full repository build and workspace typecheck passed.
  • Desktop tests: 2532/2532; focused presentation/controller tests: 48/48.
  • Renderer architecture: 112/112; lint, format, ASF headers, Astryx inventory and Electron budget checks passed.
  • Native Electron: 5/5 across Host history paging / reader preservation, WorkHub reconstruction, return/rail navigation and a real Host pending question surviving reload and explicit detach/dock with retained selection and focus. The question backend is deterministic; this does not close the real-model or automatic-progress acceptance below.
  • Previous head 21b30caf9 CI 34693581161 passed. The first rebased run 34700789283 stopped at the Windows inventory preflight: generated totals were 91 declarations while the document recorded 90. The follow-up regenerates only the two summary counts; no skip rules changed. npm run windows:inventory now passes. The follow-up requires its own CI result.
Prior verification and failed aggregate history
  • Desktop build and typecheck passed; Desktop tests: 2526/2526. The sandboxed aggregate first failed with loopback-listen EPERM; the unsandboxed full rerun passed.
  • Focused real main-handler and controller tests: 46 passed, covering current/stale progress requests, docked presentation, submission, rejected Retry, unknown admission and read recovery.
  • Native WorkHub navigation / window reconstruction / pending-question suite: 4/4 passed. The real Host pending-question test covers: docked delivery, reload hydration, explicit detach/dock, retained radio selection and focus inside the pending panel after detach. The model backend is deterministic.
  • Native transcript-scroll-cost suite: 4/4 passed. CI run 34689750231 previously reported 33/34, failing when the last Turn detached during scrollIntoViewIfNeeded. Tail setup now scrolls the stable transcript container instead of a replaceable Turn; the mounted-window and reader-displacement assertions are unchanged. This identifies the observed test setup race, not proof of a production regression or a blanket flake classification.
  • Renderer architecture: 103 passed; lint, format, ASF headers, Astryx inventory and Electron test-budget checks passed.
  • Light/dark Electron Storybook checks cover identity colors, filtered Send/Retry, rail/stripe toggling, target selection and question lifecycle. These use scripted services and accessibility checks, not a real model or native presentation handler.

Prior Host aggregate evidence remains mixed: one owned-candidate connection-election failure (1905 passed, 12 skipped), then 11/11 in the isolated file. A separate earlier tool-composition aggregate was 39/40, then the timed-out child-patch test passed alone. Those aggregate failures are not relabeled green. The latest main-integration focused Host admission / coordination / tool-composition run was 115/115; this UI consolidation does not change those Host mechanisms.

Latest consolidation CI 34692537994 passed build, workspace tests, Runtime Host tests and Desktop E2E, then failed Storybook smoke in two stories. The follow-up supplies the question fixture with Host-owned waiting_for_user execution and clears its queried interaction after Stop/answer; the model-picker story now waits for React to commit announcement changes. All 16 targeted light/dark story scenarios pass locally after these fixes. The failed aggregate remains recorded; the follow-up CI must be assessed separately.

Current CI at the tested head failed in product-workhub--colored-work-history: it expected 已完成 but observed 已接收. This manual acceptance does not override that failed check; see run 34700891842.

Real Electron / real-provider acceptance

Tested the actual production build at 59565b1aa on macOS with a new isolated profile and real deepseek-v4-flash; no fake backend, injected candidates or presentation stub.

  • Passed: real control-observe creates a native progress window; a real AskUserQuestion automatically expands it; the main window keeps focus, then explicit user activation + 2, Enter selects blue. The model replies “你选择了蓝色。” and completes.
  • Passed, generic question path: two real same-named Sessions cause the model to query candidates and ask beta/alpha through AskUserQuestion. Selecting beta leads to actual delegated execution there. beta/acceptance.txt contains exactly WORKHUB_ACCEPTANCE_BETA_59565b1a (32 bytes), while alpha has no file. The target Session shows completion. Model tool errors and retries are retained in the report.
  • Failed / integration gap: the dedicated pre-admission target selector never appeared. Production composition only installs its routing hook when dependencies.workHubRoutingModel is provided; the current tree supplies that dependency only in tests. The routing-model factory also has no production caller. These composition lines originate in feat(workhub): add model routing foundation #5152 (fa0ff028e1), predating this PR. Therefore the generic AskUserQuestion flow is not evidence that the dedicated target selector works in production.

Reproducible Chinese steps, exact prompts, state transition timestamps, selected Session identities, byte-level results and screenshots: acceptance report.

  • Actual progress-window question delivery, passive expansion and answer completion.
  • Real model ambiguity → generic question → selected-target execution.
  • Dedicated target selector production wiring and real-provider end-to-end acceptance, including its native delivery. This remains open; no production routing behavior was changed during acceptance.

Visual references

Screenshots captured earlier in this branch; these illustrate the design, not the latest acceptance run:

Conversation identity and status

Target selection

AI use

  • No generative tool made a substantive contribution
  • Generative tooling made a substantive contribution

Codex implemented changes, tests and this description. Retain Generated-by: Codex when squashing.

Checklist

  • Tests cover the changed boundaries
  • Local lint, format, typecheck and affected suites pass
  • Behavior changes are described above
  • Remaining native / real-model acceptance is complete

@github-actions github-actions Bot added the effort/XL Under 2500 readable lines label Sep 11, 2026
@ARE404
ARE404 marked this pull request as ready for review September 11, 2026 14:26

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Design verdict. Target selection is decided at the right authority: the Host keeps the pending offer (per-Turn, 64 entries, 10 min TTL), re-validates the opaque candidateRef against a fresh candidate set, binds the durable routingDecision before admission, and the renderer only echoes requestId + candidateRef. Loss of the offer (Host restart, expiry, removed target, second prompt) degrades to "ask again", which is fine for unadmitted draft state. But the pause is signalled by throwing TargetSelectionRequired out of prepareWorkHubRoutingDecision / prepareFreshContent, through RootTurnCoordinator.startRootMessage, and catching it back in the coordinator. startRootMessage runs under runCommand, which treats any non-whitelisted error as an authority failure and drains the Host. The selector therefore takes the Runtime Host down on its first use. Not merge-ready; the fix is local in shape (return a value instead of throwing) but must go through the root authority's outcome type.

P0 — Every ambiguous prompt drains the Runtime Host

Reachability ①: user sends a prompt the routing model classifies clarify.

  • packages/runtime-host/src/server/workhub-coordination-coordinator.ts:808,898 throw TargetSelectionRequired; :919,923,927 throw plain Error from #selectedRoutingDecision, which runs inside prepareFreshContent.
  • Both run inside startRootMessage's admission task (packages/runtime-host/src/server/root-turn-coordinator.ts:2032-2155), which is wrapped by runCommand (:3347-3360): anything that is not RuntimeHostedRootConflictError / RuntimeHostedRootUnavailableError / HostedRootAdmissionGateError / shutdown-cancel calls this.requestHostDrain() before rethrowing.
  • packages/runtime-host/src/server/host-kernel.ts:356-364 then sets #shutdownRequested, arms the shutdown deadline and begins the composition drain; every later operation, including the selection answer, is refused with host_draining (:622).

Repro (ran locally through the real RootTurnCoordinator, then removed): append to root-turn-coordinator.test.ts a createFailureFixture({ prepareWorkHubRoutingDecision: async () => { throw new Error('WorkHub target selection required'); } }), create the coordination stable session, call startWorkHubCoordinationMessage(...). It rejects and fixture.drainRequested() === true; no admission is written. The PR's coordinator test cannot see this because its startWorkHubCoordinationMessage fixture bypasses RootTurnCoordinator.

Fix: make the pause a value, not an exception. prepareWorkHubRoutingDecision returns { kind: 'decision', decision } | { kind: 'target_selection', request }; prepareFreshWorkHubExecution propagates it and startRootMessage returns completedStart(...) with a dedicated outcome (e.g. ok: false, code: 'target_selection_required', request) that #answer maps to targetSelection. #selectedRoutingDecision returns { kind: 'rejected', outcome: turnFailure('operation_conflict', …) } through prepareFreshContent instead of throwing (today a mismatched candidateRef also surfaces as internal_failure + console.error, operation-dispatcher.ts:369-377). Add the real-authority test above with drainRequested() === false.

P1 — Intent-unclear prompts can no longer reach the assistant

Reachability ①: any prompt whose intent the model cannot classify ("hi", "帮我看看这个").

applyWorkHubRoutingPolicy maps intent.kind === 'unclear' to clarify (packages/core/src/workhub-routing.ts:127). The coordinator turns every model clarify into a selector when allowTargetSelection (workhub-coordination-coordinator.ts:866-878), and startRootMessage always passes true (root-turn-coordinator.ts:2096). The selector offers only existing candidates, create_new, or "continue explaining", which returns the draft unsent (apps/desktop/src/renderer/features/workhub/ui/workhub-target-selector.tsx:44-54, use-workhub-controller.ts:186-198). On main a clarify Turn is admitted and the assistant asks in conversation; now "Which work do you want to continue?" is shown for prompts that are not about continuing work, and there is no way to deliver them. The test asserts this ('intent clarification also waits before admission').

Fix (smallest): add a third selection { kind: 'answer_here' } that admits with { disposition: 'answer_here' }, and make the "none of these" button send it instead of dismissing. Alternative: let the policy distinguish target ambiguity from intent ambiguity and only pause on the former.

P2 — New text and keycaps are hand-rolled instead of Astryx roles

Reachability ① (every rendered label). RadioList, Button and TextInput are used correctly; the surrounding text is not. packages/ui/src/choice-panel.tsx:83 renders a raw <kbd className="maka-choice-shortcut"> where Astryx exports Kbd; the hint at :85, workhub-selection-hint and workhub-delegation-status are <p>/<span> with font-size: 11px/12px literals (workhub.css:281,307, packages/ui/src/styles.css:1147,1149), giving 15.7px/17.1px line boxes off the 4px grid. The Workspace / Session label is a Button variant="ghost" restyled by CSS to height: auto; padding: 0; font-size: 11px (workhub.css:275-281) — fighting the primitive to get a text-sized navigation control. DESIGN.md §7 "Role, Not Axes" and §9 "Use Astryx primitives as the default seam"; the settings pages already use <Text type="supporting" color="secondary"> 68 times. Fix: Kbd keys="1" for shortcuts; Text type="supporting" color="secondary" for hint and status; Link (no href renders a <button>) with type="supporting" for the identity label, keeping only the --workhub-work-hue override since Astryx has no per-hue variant. That removes the three CSS literals and the ghost-button override.

Notes (not blocking)

  • AskUserQuestion vs. selector. Two composer-area choice surfaces now exist with different plumbing (Host-transient offer vs. interaction authority). Keeping target selection before admission is justified because the routing decision must be durable before the model runs; say so in the PR body so the split does not look accidental.
  • Epoch. 143 is correct against current main (142). #5164 also bumps 142→144; whichever merges second must re-bump.
  • Prompt status noise (P3). workhub-root.tsx:85 gives every historical turn_state a status, so every completed prompt reads "Completed · time" (verified in DOM for product-workhub--question-lifecycle and --colored-work-history). Only non-terminal, failed or aborted states change what the user does next; consider dropping completed for plain coordination turns.
  • PNGs under docs/images/pr/ (P3). No tracked rule forbids them, but CONTRIBUTING.md:87 asks for screenshots in the PR, and the raw.githubusercontent.com/ARE404/... links die with the branch. Attach to the PR and drop the files.
  • Scope. The unchecked real-model flow matters for merge only for AskUserQuestion under the bypass coordination session; the selector itself is fully exercised without a model once the P0 path is fixed.

Verified: @maka/runtime-host coordinator/protocol/tool-profile tests (41 pass); @maka/desktop workhub-send-visibility + workhub-anchor-rail (26 pass); both new tests go red with the fix reverted; storybook-static computed styles for product-workhub--colored-work-history, --target-selection, --question-lifecycle, product-ask-user-question--keyboard-choices in light and dark (accent bars 3px on the sender edge, labels oklch(0.42 0.075 h) / oklch(0.8 0.09 h), status before timestamp); real key presses select radios in both stories.

中文

设计结论。 目标选择的决定权放在了正确的权威上:Host 持有待选 offer(按 Turn,64 条,10 分钟 TTL),用最新候选集重新校验不透明的 candidateRef,在 admission 前绑定持久的 routingDecision,renderer 只回传 requestId + candidateRef。offer 丢失(Host 重启、过期、目标被删、第二条 prompt)都退化为"再问一次",对未 admit 的草稿态是合理的。但暂停是通过从 prepareWorkHubRoutingDecision / prepareFreshContent 抛出 TargetSelectionRequired、穿过 RootTurnCoordinator.startRootMessage、再在 coordinator 里 catch 回来实现的。startRootMessage 跑在 runCommand 里,任何不在白名单的异常都会被当作权威故障并触发 Host drain。所以选择器第一次使用就会把 Runtime Host 拉下线。不可合并;修法形态上是局部的(返回值而不是抛异常),但必须经由根权威的 outcome 类型。

P0 — 每条歧义 prompt 都会 drain Runtime Host

可达性 ①:用户发送一条被路由模型判为 clarify 的 prompt。

  • workhub-coordination-coordinator.ts:808,898 抛出 TargetSelectionRequired:919,923,927#selectedRoutingDecision 里抛普通 Error,而它在 prepareFreshContent 内执行。
  • 两者都在 startRootMessage 的 admission task 内(root-turn-coordinator.ts:2032-2155),外层是 runCommand:3347-3360):不是 RuntimeHostedRootConflictError / RuntimeHostedRootUnavailableError / HostedRootAdmissionGateError / shutdown-cancel 的异常都会先 this.requestHostDrain() 再重抛。
  • host-kernel.ts:356-364 随即置位 #shutdownRequested、启动关机 deadline、开始 composition drain;之后所有操作(包括选择后的 answer)都被拒为 host_draining:622)。

复现(已在本地经真实 RootTurnCoordinator 跑过,随后删除):在 root-turn-coordinator.test.ts 末尾追加 createFailureFixture({ prepareWorkHubRoutingDecision: async () => { throw new Error('WorkHub target selection required'); } }),创建 coordination stable session,调用 startWorkHubCoordinationMessage(...)。结果 reject,且 fixture.drainRequested() === true,没有写入 admission。PR 里的 coordinator 测试看不到这一点,因为其 startWorkHubCoordinationMessage 夹具绕过了 RootTurnCoordinator

修法:把暂停做成返回值而非异常。prepareWorkHubRoutingDecision 返回 { kind: 'decision', decision } | { kind: 'target_selection', request }prepareFreshWorkHubExecution 透传,startRootMessage 用专门的 outcome(如 ok: false, code: 'target_selection_required', requestcompletedStart(...),由 #answer 映射为 targetSelection#selectedRoutingDecision 通过 prepareFreshContent 返回 { kind: 'rejected', outcome: turnFailure('operation_conflict', …) } 而不是抛(现在 candidateRef 不匹配也会变成 internal_failure + console.erroroperation-dispatcher.ts:369-377)。补上面这个真实权威的测试并断言 drainRequested() === false

P1 — 意图不明的 prompt 再也到不了助手

可达性 ①:任何模型无法归类意图的 prompt("hi"、"帮我看看这个")。

applyWorkHubRoutingPolicyintent.kind === 'unclear' 映射为 clarifyworkhub-routing.ts:127)。coordinator 在 allowTargetSelection 时把所有模型 clarify 都变成选择器(workhub-coordination-coordinator.ts:866-878),而 startRootMessage 总是传 trueroot-turn-coordinator.ts:2096)。选择器只提供现有候选、create_new 或"继续说明"——后者只是把草稿退回不发送(workhub-target-selector.tsx:46-58use-workhub-controller.ts:192-201)。mainclarify 会 admit Turn,由助手在对话里追问;现在对与"继续哪个工作"无关的 prompt 也弹出该问题,且没有任何投递路径。测试还专门断言了这一行为('intent clarification also waits before admission')。

修法(最小):增加第三种 selection { kind: 'answer_here' },以 { disposition: 'answer_here' } admit,并让"都不是"按钮发送它而不是 dismiss。替代方案:让 policy 区分目标歧义和意图歧义,只在前者暂停。

P2 — 新增文字和快捷键帽是手写的,不是 Astryx 角色

可达 ①(每个渲染的标签)。RadioListButtonTextInput 用得对,周围的文字没有。packages/ui/src/choice-panel.tsx:83 手写 <kbd className="maka-choice-shortcut">,而 Astryx 有 Kbd:85 的提示、workhub-selection-hintworkhub-delegation-status 都是带 font-size: 11px/12px 字面量的 <p>/<span>workhub.css:281,307packages/ui/src/styles.css:1147,1149),行框 15.7px/17.1px,不在 4px 网格上。Workspace / Session 标签是被 CSS 改成 height: auto; padding: 0; font-size: 11pxButton variant="ghost"workhub.css:275-281),为得到文字尺寸的导航控件而对抗原语。DESIGN.md §7 "Role, Not Axes"、§9 "Use Astryx primitives as the default seam";settings 页已用 <Text type="supporting" color="secondary"> 68 次。修法:快捷键用 Kbd keys="1";提示和状态用 Text type="supporting" color="secondary";身份标签用 Link(无 href 时渲染 <button>)加 type="supporting",只保留 --workhub-work-hue 覆盖(Astryx 没有按色相的变体)。这样三处 CSS 字面量和 ghost 按钮覆盖都可删。

备注(不阻塞)

  • AskUserQuestion 与选择器。 composer 区域现在有两套选择界面、两套管线(Host 临时 offer vs. interaction authority)。把目标选择放在 admission 前是有理由的(路由决定必须在模型运行前持久化),请在 PR 正文写明,避免看起来像是偶然分裂。
  • Epoch。 相对当前 main(142),143 正确。#5164 也从 142 升到 144;后合并者需要再升。
  • Prompt 状态噪音(P3)。 workhub-root.tsx:85 给每条历史 turn_state 都赋状态,于是每条已完成的 prompt 都显示"已完成 · 时间"(在 product-workhub--question-lifecycle--colored-work-history 的 DOM 中确认)。只有非终态、失败或中止会改变用户的下一步;建议普通 coordination turn 不显示 completed
  • docs/images/pr/ 下的 PNG(P3)。 没有仓库规则禁止,但 CONTRIBUTING.md:87 要求截图放在 PR 里,且 raw.githubusercontent.com/ARE404/... 链接会随分支删除失效。改为 PR 附件并删掉文件。
  • 范围。 未勾选的真实模型流程只对 bypass 模式 coordination session 下的 AskUserQuestion 有合并意义;选择器本身在 P0 修复后无需模型即可完整验证。

已验证:@maka/runtime-host coordinator/protocol/tool-profile 测试(41 通过);@maka/desktop workhub-send-visibility + workhub-anchor-rail(26 通过);两个新测试在还原修复后均变红;storybook-static 在 light/dark 下对 product-workhub--colored-work-history--target-selection--question-lifecycleproduct-ask-user-question--keyboard-choices 的计算样式(发送方边缘 3px 色条、标签 oklch(0.42 0.075 h) / oklch(0.8 0.09 h)、状态在时间戳之前);真实按键在两个 story 中都能选中单选项。

Comment thread apps/desktop/src/renderer/styles/workhub.css
Comment thread packages/ui/src/choice-panel.tsx
Comment thread packages/runtime-host/src/server/workhub-coordination-coordinator.ts Outdated
Comment thread packages/runtime-host/src/server/workhub-coordination-coordinator.ts Outdated
Comment thread packages/runtime-host/src/server/root-turn-coordinator.ts
Comment thread apps/desktop/src/renderer/features/workhub/ui/workhub-root.tsx
Comment thread apps/desktop/stories/ask-user-question.stories.tsx Outdated
Comment thread apps/desktop/src/renderer/features/workhub/ui/workhub-target-selector.tsx Outdated

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Status check on 9f31d58fa. Three commits landed since the last round; none touches packages/runtime-host or packages/core, so the P0 and P1 stand unchanged. 76639a86a resolves one inline item. bb8bf7ad0 is a new alignment tweak. 9f31d58fa adds a conversation filter that is not in the PR title, body, or any issue; as fresh code it has a P1 of its own. Still not merge-ready.

Item Status on 9f31d58fa
P0 — ambiguous prompt drains the Host Open. Re-ran the probe through the real RootTurnCoordinator (createFailureFixture({ clientCapabilities, prepareWorkHubRoutingDecision: async () => { throw new Error('WorkHub target selection required') } }), v2 coordination Session, startWorkHubCoordinationMessage): routing called once, rejects with that error, drainRequested() === true, no admission written. workhub-coordination-coordinator.ts:82,808,896 and root-turn-coordinator.ts:3347-3360 are byte-identical to the reviewed head.
P1 — intent-unclear prompts cannot reach the assistant Open. workhub-coordination-coordinator.ts:866-878 still maps every model clarify to a selector when allowTargetSelection; root-turn-coordinator.ts:2096 still passes true; the selector still has no "answer here" delivery.
P2 — hand-rolled text/keycaps Open, and grown. choice-panel.tsx:72 still renders <kbd className="maka-choice-shortcut">; workhub.css:306 (.workhub-selection-hint, 12px) and :279-283 (ghost Button forced to text size) unchanged. 9f31d58fa adds .workhub-conversation-filter { font-size: 12px } (workhub.css:325, computed line box 17.1px) in the same style.
Inline 04 — --workhub-selection-label duplicates --workhub-work-label Open (workhub.css:317-318).
Inline 05 — hint strings inline in ChoicePanel Addressed by 76639a86a: questions.keyboardHint in conversation-copy.ts, read via getConversationCopy(locale).
Inline 06 — inline import() types in the coordinator Open (:81,810,884).
Inline 07 — throw new Error for client mismatch in #selectedRoutingDecision Open (:919,923,927); folds into the P0 fix.
Inline 08 — allowTargetSelection always true Open (root-turn-coordinator.ts:1569,2096).
Inline 09 — every completed prompt shows "Completed · time" Open (workhub-root.tsx:85).
Inline 10 — toBeChecked() without waitFor Open at the same lines; note the four stories passed in this static build (light), so the flake is timing-dependent, which is the reason to wrap them.
Inline 11 — duplicated hostCwd basename expression Open (workhub-target-selector.tsx:49, linked-work.ts:64).
Notes (PNGs in docs/images/pr/, epoch, status noise) PNGs still in the tree. Epoch 143 vs origin/main 142 is still correct.

bb8bf7ad0 gives every WorkHub prompt a transparent 3px end border so unlinked and delegated prompts share a metadata edge, with a story assertion; no concerns.

9f31d58 — conversation filter: does not belong in this PR

Design. The commit adds a second interaction model on top of the identity rails: double-click / shift-click on a navigation item filters the conversation, a single click now opens the Session only after a 500 ms timer, and every linked prompt and answer grows an invisible 12 px <button> on its accent edge. None of this is in the PR summary, the verification list, or an issue. It lands mid-review on a PR that already carries an open P0, and it changes the primary rail gesture for everyone. Split it out and open it against a short design note (which gesture, why a hidden edge button when the visible label already opens the Work), after P0/P1 are fixed here.

P1 — Sending while filtered makes the user's own prompt disappear

Reachability ①: filter by any Work (edge button or rail double-click), type a follow-up, press Enter.

workhub-conversation.tsx:120-121,133 keep only messages, liveTurn, and transient messages whose turnId is in matchingTurns, and matchingTurns comes from workLinks, which linked-work.ts:64-96 derives only from durable delegation_assigned / tasks tool results. A new Turn has no link until delegation lands, so the optimistic bubble, the admitted prompt, the streaming answer, and the running status are all hidden; runningStatus is forced false (:134). Reproduced on product-workhub--colored-work-history in the static build: filter to 支付回调幂等性, send FILTERED_SEND_PROBE: transcript stays at 2 turns, no transient row, no running status, filter bar still shown; clearing the filter reveals 5 turns including the new prompt and answer. For a clarify/answer_here Turn the message never appears until the user clears the filter by hand.

Fix (smallest): clear selectedWork on send (highlight.selectWork(undefined) in the send path, or in the controller's send), so the transcript returns to the full view exactly when new content is about to arrive. If the filter is meant to survive a send, the pending Turn and the live Turn must be exempt from the filter until their link exists.

P2 — Single click on the navigation rail now waits 500 ms

Reachability ①: every click on a rail item. workhub-navigation-rail.tsx:141 defers onOpenSession behind setTimeout(..., 500) so a double-click can be distinguished; on main the same click opens immediately. Measured in the static build: a single click resolves nothing for 500 ms. The primary action of the rail should not pay for a secondary gesture; keyboard-only users already get the immediate path (event.detail === 0). If the filter stays, put it on a modifier or a distinct control and keep single click immediate.

P2 — Hidden 12 px edge buttons in the tab order

Reachability ①. Each linked prompt and answer renders .workhub-message-rail (chat-turn.tsx:575,645,675; workhub.css:321-323): 12 px wide, transparent, no text, tabIndex 0, positioned over the accent border. In product-workhub--colored-work-history that is six extra focus stops between the rail and the composer, each right before a visible identity button that already opens the same Work. Nothing on screen tells a pointer user the edge is clickable except the title. DESIGN.md's rule that an element must change the user's next action is not met; if a per-message filter entry is wanted, add it as a visible action on the existing label (MoreMenu or a second Button), not as an invisible hit area.

中文

针对 9f31d58fa 的状态核对。上一轮之后新增三个 commit,均未触及 packages/runtime-hostpackages/core,因此 P0 与 P1 原样保留。76639a86a 解决了一条 inline 意见;bb8bf7ad0 是新的对齐微调;9f31d58fa 新增了对话筛选,PR 标题、正文和任何 issue 都没有提到,作为新代码它自身带来一个 P1。仍不可合并。

项目 9f31d58fa 上的状态
P0 — 歧义 prompt 会 drain Host 未修。 经真实 RootTurnCoordinator 重跑探针(createFailureFixture({ clientCapabilities, prepareWorkHubRoutingDecision: async () => { throw new Error('WorkHub target selection required') } }),v2 coordination Session,startWorkHubCoordinationMessage):routing 被调用一次,以该错误 reject,drainRequested() === true,未写入 admission。workhub-coordination-coordinator.ts:82,808,896root-turn-coordinator.ts:3347-3360 与上次评审的 head 逐字节相同。
P1 — 意图不明的 prompt 到不了助手 未修。 workhub-coordination-coordinator.ts:866-878 仍在 allowTargetSelection 时把所有模型 clarify 变成选择器;root-turn-coordinator.ts:2096 仍传 true;选择器仍没有"就在这里回答"的投递路径。
P2 — 手写文字/快捷键帽 未修,且扩大。 choice-panel.tsx:72 仍是 <kbd className="maka-choice-shortcut">workhub.css:306.workhub-selection-hint,12px)与 :279-283(ghost Button 被压成文字尺寸)未变。9f31d58fa 又以同样方式加了 .workhub-conversation-filter { font-size: 12px }workhub.css:325,计算行框 17.1px)。
Inline 04 — --workhub-selection-label--workhub-work-label 重复 未修(workhub.css:317-318)。
Inline 05 — ChoicePanel 内联文案 已修76639a86a):conversation-copy.ts 增加 questions.keyboardHint,经 getConversationCopy(locale) 读取。
Inline 06 — coordinator 内联 import() 类型 未修(:81,810,884)。
Inline 07 — #selectedRoutingDecision 对客户端不匹配 throw new Error 未修(:919,923,927);随 P0 修法一起消失。
Inline 08 — allowTargetSelection 恒为 true 未修(root-turn-coordinator.ts:1569,2096)。
Inline 09 — 每条已完成 prompt 显示"已完成 · 时间" 未修(workhub-root.tsx:85)。
Inline 10 — toBeChecked() 没包 waitFor 未修,行号不变;本次静态构建(light)四个 story 都通过,说明是时序相关的 flake,这正是要包 waitFor 的原因。
Inline 11 — hostCwd 取名表达式重复 未修(workhub-target-selector.tsx:49linked-work.ts:64)。
备注(docs/images/pr/ 的 PNG、epoch、状态噪音) PNG 仍在仓库里。epoch 143 相对 origin/main 的 142 仍正确。

bb8bf7ad0 给每条 WorkHub prompt 加 3px 透明尾边框,让未链接和已委派的 prompt 共用一条元数据边缘,并加了 story 断言;没有问题。

9f31d58 — 对话筛选:不属于本 PR

设计。该 commit 在身份色条之上叠加了第二套交互模型:导航项双击/shift 点击筛选对话,单击改为 500 ms 定时后才打开 Session,每条已链接的 prompt 和回答在色条边缘多出一个不可见的 12px <button>。这些都不在 PR 摘要、验证清单或任何 issue 里。它在评审进行中落到一个仍有 P0 未修的 PR 上,还改变了所有人的主手势。建议拆出去,先修好这里的 P0/P1,再附一段简短设计说明(选哪种手势、可见标签已能打开 Work 为何还要隐藏边缘按钮)单独开 PR。

P1 — 筛选状态下发送,用户自己的 prompt 会消失

可达性 ①:按任一 Work 筛选(边缘按钮或导航栏双击),输入后续内容,回车。

workhub-conversation.tsx:120-121,133 只保留 turnIdmatchingTurns 中的消息、liveTurn 和 transient 消息,而 matchingTurns 来自 workLinks,后者由 linked-work.ts:64-96 仅从持久化的 delegation_assigned / tasks 工具结果推导。新 Turn 在委派落地前没有链接,于是乐观气泡、已 admit 的 prompt、流式回答、运行状态全部被隐藏;runningStatus 被强制为 false:134)。已在静态构建的 product-workhub--colored-work-history 上复现:筛选到 支付回调幂等性,发送 FILTERED_SEND_PROBE:transcript 仍是 2 个 turn,没有 transient 行,没有运行状态,筛选条仍在;清除筛选后出现 5 个 turn,包含新 prompt 和回答。对 clarify/answer_here 的 Turn,消息在用户手动清除筛选前永远不出现。

修法(最小):发送时清除 selectedWork(在发送路径或 controller 的 send 里调 highlight.selectWork(undefined)),让 transcript 恰在新内容到来时回到完整视图。如果筛选必须跨发送保留,则 pending Turn 和 live Turn 在链接存在前必须豁免筛选。

P2 — 导航栏单击要等 500 ms

可达性 ①:每次点击导航项。workhub-navigation-rail.tsx:141onOpenSession 推迟到 setTimeout(..., 500) 之后以区分双击;main 上同一次点击立即打开。静态构建实测:单击 500 ms 内没有任何反应。主动作不该为次要手势买单;键盘用户已经走即时路径(event.detail === 0)。若保留筛选,请放到修饰键或独立控件上,单击保持即时。

P2 — tab 顺序里的隐藏 12px 边缘按钮

可达性 ①。每条已链接的 prompt 和回答渲染 .workhub-message-railchat-turn.tsx:575,645,675workhub.css:321-323):12px 宽、透明、无文字、tabIndex 0,覆盖在色条上。在 product-workhub--colored-work-history 里,这在导航栏与 composer 之间多出六个焦点停靠点,每个都紧挨着一个已经能打开同一 Work 的可见身份按钮。除了 title,屏幕上没有任何提示告诉指针用户边缘可点。不满足 DESIGN.md"元素须改变用户下一步动作"的规则;若需要按消息的筛选入口,应作为现有标签上的可见动作(MoreMenu 或第二个 Button),而不是不可见热区。

Comment thread apps/desktop/stories/workhub.stories.tsx Outdated
Comment thread apps/desktop/stories/workhub.stories.tsx Outdated
Comment thread apps/desktop/src/renderer/features/workhub/ui/workhub-conversation.tsx Outdated

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for addressing the previous review and documenting the remaining acceptance work. I re-reviewed d75735f6d3e63a2493344e44d6ba2b27e46a002d across architecture, implementation, and simplification. Two local P2 issues remain, both noted inline; no new P0/P1 was identified.

The authority boundary now looks sound. Target selection returns a typed outcome before admission, the Host validates the offered identity and refreshes the same target against current candidates, and execution still passes through the existing Action Gate. The transient offer, fresh candidate binding, durable routing decision, and final authorization check protect distinct obligations; I do not see a justified architecture rewrite or a redundant authority to remove.

The earlier Host-drain, intent-only clarification, and ordinary filtered-send findings are addressed. The ChatView remount, Astryx primitives, shared copy/color/path handling, type imports, and Storybook assertion/viewport concerns are also addressed. I am withdrawing the earlier claim that allowTargetSelection is always true: recovery and follow-up use the false default, while direct starts opt in. The 500 ms rail delay is gone. I am not carrying forward the completed-status or rail-interaction preferences as correctness findings under the currently documented behavior.

The useful remaining simplification is to make clearing the presentation filter part of a shared send/retry entry point. The ordinary send fix currently leaves Retry uncovered. The shared identity color cleanup also introduced a missing dark-theme selector, detailed inline.

Validation in this review: an Electron computed-style probe reproduced the light-theme issue; an exact-head WorkHubRoot/controller DOM probe reproduced failed send → filter → successful Retry with the new messages hidden until clearing the filter. Host code and its regression tests were inspected, but the full suite was not rerun. Current CI is passing. The real-model routing → selection → execution flow and actual floating-window expansion/focus/dock transitions remain unverified, as listed in the PR; fixture checks do not replace those acceptance items.

AI assistance: Codex coordinated three deep reviewers; findings were cross-checked against the current production paths and the focused probes.

Comment thread apps/desktop/src/renderer/styles/workhub.css Outdated
Comment thread apps/desktop/src/renderer/features/workhub/ui/workhub-root.tsx Outdated
@ARE404
ARE404 force-pushed the feat/workhub-conversation-colors branch 2 times, most recently from 7a92599 to 1de55db Compare September 12, 2026 10:56
Astro-Han

This comment was marked as duplicate.

@Astro-Han

Copy link
Copy Markdown
Contributor

Thanks for working through the review feedback. I think this now needs a bounded architecture consolidation before another rereview, rather than only a guard around the latest P2. This assessment is based on 1de55db5d7601d8875c13a563d8bc346e2add8d4.

The Host admission and execution boundary looks sound. The remaining pattern is in UI orchestration: submission visibility is enforced separately by Send and Retry, while showConversation mixes expanding content with changing window placement. Fixing individual callers leaves the next caller exposed to the same assumptions. The Storybook presentation stub also hides the actual window-command behavior. I should have distinguished these UI contracts from the already-correct Host architecture more clearly in the earlier review.

Please give your implementation agent the following prompt. The goal is to remove those recurring coordination obligations within this PR, not to add another controller or redesign all of WorkHub.


Implementation agent prompt

Review and consolidate the UI orchestration in this PR before fixing the latest inline P2. Start by reading the current production paths and the review history; do not assume every previous suggestion is correct. Pin your work to the latest PR head and account for changes from main.

1. Define the contracts and their owners before editing.

Trace ordinary Send, rejected-send Retry, unknown-admission recovery, transcript-read recovery, target selection, AskUserQuestion hydration, and progress/floating/docked presentation through the renderer, preload, and main process. State which existing owner decides each fact and which side effects each entry is allowed to cause. In particular:

  • Runtime Host remains the sole authority for admission, execution, interactions, and terminal state. Renderer state is presentation or pending-request coordination.
  • A newly submitted or resubmitted prompt and its answer must be visible without manually clearing a Work filter. Read recovery and unknown-admission reconciliation are not new submissions and must not accidentally resend work.
  • Presenting a question or target selector must preserve the current docked/floating placement. Expanding an existing progress card is a distinct operation from explicitly detaching or docking the window.
  • Pending interactions must retain their answers/selection and usable keyboard focus through supported presentation transitions; focusing an ordinary composer must not override an active interaction.

2. Consolidate at the existing boundaries.

  • Remove the need for individual Send/Retry buttons to remember the same submission-visibility rule. Put that rule at an existing shared submission boundary, while preserving the distinct retry/recovery semantics above. Do not move presentation filtering into Runtime Host.
  • Inspect every production caller of showConversation. Today an absent progressRequest can reach detach(true), although the caller only intends to reveal an interaction. Narrow this contract so expanding a progress card cannot silently mean changing placement. Check whether requiring the current progress request lets the optional/no-request branch disappear; keep explicit placement changes on the existing detach/dock path. Validate stale requests at the existing presentation owner.
  • Keep local content expansion, native placement, and focus responsibilities explicit. Do not introduce a second presentation state machine, mirrored lifecycle flags, or another event loop to synchronize them. If additional state is truly necessary, identify the concrete obligation that cannot be met by an existing owner.
  • Preserve the multi-Turn buffer and stable rejected-prompt identity from the latest main integration.

3. Perform an ablation pass.

After the consolidation, try removing the superseded branches, duplicated caller-side side effects, and tests that only assert those old mechanisms. Retain the smallest tests protecting distinct observable contracts. Do not delete the Host offer cache, fresh candidate rebinding, durable routing decision, or Action Gate merely to reduce code: those currently protect separate expiry/recovery, freshness, replay, and authorization obligations. Do not change the documented navigation/filter product behavior as an incidental cleanup.

4. Verify through the real boundaries.

Use the existing test seams and native E2E infrastructure. Cover ordinary submission and rejected Retry while filtered; ensure read/unknown-admission recovery does not create a duplicate submission. Exercise a docked selector and a hydrated question through the real presentation command handling and assert that placement stays docked. Check progress-card expansion, pending-interaction focus, and floating/docked transitions with the actual window implementation. A no-op Storybook showConversation stub cannot establish these contracts.

Complete the PR's already-listed real-model ambiguous-routing → selection → target-execution acceptance, or state precisely why it remains unverified. Investigate the failing exact-head CI transcript-scroll-cost E2E without assuming either a PR regression or a flake; preserve any failed aggregate result in the validation report. Run the affected checks rather than adding a broad new test matrix.

5. Report the final architecture, not just the patch.

Update the PR description with the problem, the final responsibility boundaries, which old paths or obligations were removed, and the evidence for each acceptance item. Explain any complexity that survived ablation. If a real product decision is needed, surface that specific decision before inventing behavior.

Do not stop after adding if (progress) to the current effect. Completion means the contract prevents equivalent mistakes at other callers, the superseded behavior is removed, and the observable interaction/presentation paths have been verified.


I will rereview the consolidated architecture first, then the implementation and simplification. AI assistance: Codex helped trace the current call paths and draft this review guidance.

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for making the consolidation explicit. At 21b30caf9, Send and rejected Retry now share the submission callback, while unknown-admission and read recovery keep their separate meanings. Progress expansion requires a current request and no longer falls back to detach. These are the right ownership boundaries, and the old docked-placement P2 is fixed.

One P2 remains in the progress-to-conversation transition, detailed inline: expanding before the first progress paint leaves the native window hidden. Please complete that transition in the existing presentation owner, preserving stale-request rejection, explicit placement changes and no-focus-stealing behavior. This needs a local correction and a regression through the existing main handler, not another controller.

Verification: rebuilt this exact head; 46 presentation/controller tests passed. The real Electron pending-question test also passed: docked delivery, reload hydration, explicit detach/dock, retained selection and focus in the question panel. An additional probe through the existing main-handler harness reproduced the early-expansion failure. I have not run a real provider routing session. The two remaining acceptance items already disclosed in the PR body—real-model target routing and complete native progress/selector delivery—remain open, so I am not approving yet.

AI-assisted rereview with Reviewer Sol and the coordinating Codex agent; the latter independently checked the changed boundaries and ran the validations above.

Comment thread apps/desktop/src/main/workhub-presentation.ts
ARE404 and others added 20 commits September 12, 2026 22:53
Move the keyboard hint translations into ConversationCopy to satisfy the locale hygiene CI gate without changing displayed copy.

Generated-by: Codex
Reserve the same right-side accent gutter for every WorkHub prompt so unlinked and delegated messages share a metadata edge. Verify the shared edge in the mixed-work story.

Generated-by: Codex
Return target selection as an admission outcome instead of a Host-draining exception. Admit intent-only clarification and clear conversation filters before submission. Reproduce all three defects with root-authority and interaction regressions.

Generated-by: Codex
Preserve the chat view across filtering, require history navigation in the paged story, configure its narrow counterpart, and await keyboard state. Reuse Astryx text/link/keycap primitives and shared identity/path values while retaining the approved compact labels and filter gestures.

Generated-by: Codex
Replace the raw stripe control with the design-system Button and regenerate the surface inventory required by CI.

Generated-by: Codex
Read computed border colors instead of CSS token declarations to comply with the ink-ladder contract and validate rendered identity colors.

Generated-by: Codex
Verify rail activations stay in WorkHub, then open the Session from its sidebar title to retain return-button and draft-persistence coverage.

Generated-by: Codex
`product-ask-user-question--keyboard-choices` failed on every CI run for
this branch. The story sent its first key as its very first action, but
the panel takes focus when it mounts and handles these shortcuts on
itself rather than on the document, so a key sent before that focus lands
is delivered to <body> and dropped.

Nothing is wrong with the shortcut. Pressing `2` against the built story
selects the second option exactly as the story expects, once the panel
holds focus. Locally the race resolved either way; on CI's slower runner
it lost every time, which is why six consecutive runs failed identically.

Wait for the panel to actually hold focus first. Verified against the
built Storybook through the smoke runner's own `smokeStory`: three of
three runs failed before this change, five of five pass after, and the
full catalogue is green at 345 stories and 372 theme renders.

Generated-by: Claude Opus
Preserve the multi-Turn buffer, filter active execution with conversation turns, and retain failed prompts for retry.

Generated-by: Codex
Await model switch announcement commits in story assertions.

Generated-by: Codex
@ARE404
ARE404 force-pushed the feat/workhub-conversation-colors branch from 21b30ca to 154f4a3 Compare September 12, 2026 14:57

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the focused fix and the clear acceptance notes. I rereviewed 59565b1aa. The previous early-expansion P2 is closed: the existing Main presentation owner now completes passive reveal when expansion consumes the progress request before paint, while preserving hidden mode, request freshness and no-focus-stealing behavior. No new controller or lifecycle authority is needed.

I rebuilt this head and ran the 48 presentation/submission tests successfully. Reverting only the presentation fix made the new before-first-paint regression fail with the window still hidden; restoring it passed. The real Electron pending-question test also passed, covering reload hydration, explicit detach/dock, retained selection and focus. No new P0–P3 code finding emerged from this rereview.

I am keeping this as a comment until the two remaining acceptance items are demonstrated:

  • Actual progress-window delivery and automatic expansion into a pending question/target selector through the real native presentation handler, including selection/answer completion and no focus stealing.
  • Real-model ambiguous routing, user selection, and execution against the selected target.

The docked deterministic-backend E2E and the native-handler harness establish useful boundaries, but not those complete paths. Please attach reproducible steps and observed results to this PR; there is no evidence here calling for another architectural rewrite. Current CI is still running and the PR is mergeable.

AI-assisted rereview and local verification with Codex.

中文

上次进度窗过早展开后仍隐藏的 P2 已闭环,修复沿现有 Main 展示权威完成,没有增加控制器。48 项测试、回退失败/恢复通过的负对照,以及真实 Electron 的问题面板重载和显式窗口切换验收均通过。本次没有新的 P0–P3 代码问题。

暂保留 COMMENT,待完成正文两项验收:真实进度窗自动展开并交付问题/目标选择,以及真实模型歧义路由→选择→目标执行。现有分层测试不替代这两条完整路径;也没有证据要求再做一次架构重写。CI 尚在运行。

@Astro-Han

Copy link
Copy Markdown
Contributor

Thanks for working through all the follow-ups! It would be helpful to add a couple of short demo videos to the PR body, both to show how the feature feels and to make the remaining acceptance easier to verify:

  • The actual progress window automatically expanding into a question or target selector, then completing the interaction without stealing focus.
  • A real-model ambiguous request going through target selection and executing against the selected target.

A brief note with the tested commit, OS, steps, and whether the backend is real or simulated would be enough. No polished walkthrough needed—a simple screen recording of each flow would help me review the behavior and give future readers a useful feature demo. Thanks!

Record the production routing hook integration gap separately from generic question delegation.

Generated-by: Codex
@ARE404

ARE404 commented Sep 12, 2026

Copy link
Copy Markdown
Contributor Author

Ran the production Electron build at 59565b1 with real deepseek-v4-flash, isolated data, and no injected model/presentation responses.

The native progress → automatic question expansion → keyboard answer → completion path passed. The progress window became visible without taking focus from the main window; after explicit activation, 2 + Enter selected blue and the real model completed with “你选择了蓝色。”

The real model also resolved two same-named works through a generic AskUserQuestion, then delegated to the chosen beta Session. beta/acceptance.txt exists with exactly the requested 32 bytes; alpha has no file. I verified the target Session's execution and completion, not merely admission.

However, the dedicated target selector did not appear. Source tracing explains why: execution-composition only installs prepareRoutingDecision when dependencies.workHubRoutingModel is provided (lines 1525–1527), and passes that same optional dependency to the coordinator (line 1942). The current production entry points do not supply it; the factory and injection are used only by tests. These lines came from #5152, before this PR. The generic question flow therefore cannot close the dedicated-selector acceptance. This is now recorded as a production integration gap rather than unexecuted testing.

Reproducible prompts, actual transition timestamps, focus observations, Session identities, file evidence and screenshots: https://github.com/ARE404/maka-agent/blob/6aa526a8d6c7e45b2ec656152ee02120339322ca/docs/workhub-native-acceptance-2026-09-12.zh-CN.md

The tested head's CI also failed separately in colored-work-history (expected 已完成, observed 已接收); that failure remains recorded. This evidence-only commit does not change production routing or fix that story.

@Astro-Han Astro-Han left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for doing the real-provider acceptance and distinguishing the generic question flow from the dedicated target selector. The report provides useful evidence for native passive expansion, answering a question, and execution in the selected Session. The evidence-only update from 59565b1aa to 6aa526a8d does not change the implementation I previously tested.

I checked the routing composition and the upstream decision. There is an important qualification: the missing production default is intentional. #5152 explicitly keeps the current production routing default until the comparative production-path evidence required by #3492 exists. #3492 still leaves real-model comparison, strategy selection and rollout open. Please do not close this by simply injecting createHostWorkHubRoutingModel in production.

The design/acceptance question for this PR is now concrete: its dedicated pre-admission selector depends on a routing path that is not enabled for normal users. A generic AskUserQuestion followed by delegation is a useful supported workflow, but does not demonstrate that selector or its admission contract.

Please reconcile the deliverable with that existing gate before merging:

  • If the dedicated selector is part of this release, complete the required comparison/strategy decision through the existing maka eval and Host admission path, then integrate and verify the selected production route. Reuse the existing Host composition and Action Gate; do not add a UI routing authority or another evaluation framework.
  • If that routing rollout remains deferred, propose a coherent scope for the currently usable identity/status/question improvements and identify which inactive selector-specific machinery should be deferred or removed. Merely relabeling unreachable UI as delivered would not resolve the issue.

This is a scope and integration decision, not evidence that the default was accidentally omitted or that the already-reviewed Host safeguards need another rewrite. I am keeping COMMENT pending that decision.

The current head also fails CI in product-workhub--colored-work-history: expected 已完成, received 已接收. Please establish whether this is a fixture scheduling issue or incorrect status projection before changing the test; do not weaken the assertion or assume a flake. GitHub currently also reports a conflict with main.

A short video of the successful native flow would still be useful for the PR presentation; it is separate from the routing decision above.

AI-assisted follow-up: Codex checked the current source, acceptance report, upstream rollout constraints and CI logs.

中文

真实模型验收确实推进了:原生进度窗被动展开、问题回答以及选定 Session 执行已有证据。但专用选择器依赖的路由没有默认启用,这是 #5152#3492 评估门槛作出的有意决定,不能作为漏接依赖直接注入。

请先收敛本 PR 的交付范围:若本次要交付专用选择器,需完成已有比较评估/策略决策,再接入并验收真实生产路径;若路由上线继续延后,请提出当前可用功能的完整范围,并说明哪些未启用的选择器机制应延后或删除。不要新建路由权威或评估框架,也不要把通用提问当成专用选择器验收。

当前 CI 仍在 colored-work-history 上出现“已完成/已接收”不一致,另有 main 冲突,需查明并解决。保持 COMMENT;不要求再推翻已经验证过的 Host 边界。

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

Labels

effort/XL Under 2500 readable lines

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants