Skip to content

fix(dashboard): resolve the steward chat runtime from the channel - #4557

Merged
huangruiteng merged 2 commits into
mainfrom
codex/steward-runtime-resolution
Sep 16, 2026
Merged

huangruiteng merged 2 commits into
mainfrom
codex/steward-runtime-resolution

Conversation

@huangruiteng

Copy link
Copy Markdown
Collaborator

动机

业主报告:前端在管家回答处显示 Codex,应当表示 LoopX 管家。上一刀(#4555 / #4556)修掉了回答署名,但同一屏上还有第二个同源问题:聊天 Runtime 选择器在本机发现 Codex 适配器时优先选它,于是页头 chip 解析出 dsh,选择器与输入框却写着 Codex。

现场回读(已安装 Dashboard,127.0.0.1:8767/chat/):

header = LoopX 管家 | restricted · read-only | dsh | operator 凭据 | deepseek-v4-flash | 总览 | Chat | Chat | Codex | 实时
picker = Chat / Codex
options = Codex, Claude Code, Kiro CLI · 不可用, Claude API · 不可用, OpenAI API · 不可用, DeepSeek Harness (managed), 仅查状态

同一屏里 dsh 与 Codex 并存,读者无法判断到底谁在回答。

改动思路

loopx/chat_server.py 的建会话契约已经把这件事写清楚了:agent_id 是调用方的显式选择,运维方没选时保持为空,每个通道由自己的属主解析默认值。所以前端在运维方没有选择时,展示的默认值必须等于通道自己解析出来的那个执行器,而不是"本机恰好装了什么"。

  • 管家上下文:优先使用控制面声明的 channel_binding.executor_endpoint(映射到已发现适配器时);
  • 本机什么都没声明:保持出货默认(Codex),即 feature-off 等价;
  • 运维方显式选择:仍然优先,并且仍然只有这条路径会让客户端发送端点;
  • Goal 上下文:不变。

具体改动

  • apps/presentation/dashboard/src/views/dashboard-page.tsx:新增 stewardExecutorAgentId 与 agentDefaultForContext(contextId),管家上下文的选择器默认值来自已声明的管家执行器。
  • examples/personal-workspace-browser/fixture.mjs:新增 runtimeAgents fixture 缝,用于声明本机适配器集合。
  • examples/personal-workspace-browser/execution-chip.mjs:新增两条断言——声明托管宿主时选择器与输入框必须是该宿主且不得出现 Codex;本机未声明时选择器仍是出货默认 Chat Codex。
  • examples/personal-workspace-browser/typed-actions.mjs:把描述"Codex 是默认"的措辞改为它实际成立的条件(本机未声明管家执行器)。
  • RFC(EN + ZH):新增「管家回答身份与 Runtime 选择」小节,记录两条规则与证据。

对主干的风险

低到中。这是默认展示行为变更,在此显式披露:受影响的只有管家上下文的选择器/输入框显示与由它派生的会话缓存键名;Goal 上下文、后端解析、投递语义、权限均不变。已声明的执行器若映射不到任何已发现适配器,则回落到原有链路(旧行为)。显式选择优先的规则没有变化。

我的整体评价

正向且 proportional:一处默认解析 + 一条 fixture 缝 + 两条场景断言 + RFC 记录,覆盖了业主在同一屏上看到的两个 "Codex" 来源,并留下"本机未声明时行为不变"的等价证明。

Validation:

  • tsc --noEmit -p tsconfig.json:通过
  • 完整 personal-workspace-browser-smoke:通过(navigation-sorting, chat-recovery, typed-actions, team-plan, execution-chip)
  • 负向对照:仅回退 dashboard-page.tsx 改动后,新断言精确失败 Chat runtime picker ignored the declared steward executor: Chat Codex
  • 相关 feature smokes:workspace-theme、agent-family、goal-order、team-plan-proposal、chat-route、dashboard-pwa-bundle-smoke 全通过
  • loopx canary premerge --from-git-diff:merge_gate_passed: true,surfaces docs_project_content, public_boundary,docs risk-profile smoke 全过;advisory control-plane-maintainability-ratchet-smoke.py 为 clean origin/main 已知基线
  • 首屏门禁不适用:改动是 channel header 的控件与文案,不涉及首屏 hero/nav

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

English verdict: APPROVE

The chat-runtime picker preferred a discovered Codex adapter over the executor
the machine declares for the steward, so a channel resolving to the managed host
still displayed "Codex" in the header trigger and above the composer while the
capability chip resolved "dsh". The client is expected to send no endpoint until
the operator picks one, so the picker has to show the channel's own resolution
rather than a CLI this machine merely has installed.

The manager context now defaults to the declared steward executor when the
control plane reports one that maps to a discovered adapter, and keeps the
shipped Codex default when the machine declares nothing. Goal contexts are
unchanged, an explicit operator pick still wins, and no endpoint is sent when no
pick was made.

The execution-chip scenario proves the new resolution and the undeclared-machine
parity, with a fixture seam for declaring runtime adapters.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Steward executor selection is a machine decision, so the RFC now states the two
rules that keep the surfaces consistent: the transcript names the speaker while
the capability chip reports the executor and model, and the chat-runtime picker
resolves the manager context the way the channel owner does. The former smoke
wording that described Codex as the default in general now names the condition
it actually holds under.

Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>

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

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

Exact head reviewed: f1f72ac

动机

业主报告前端在管家回答处显示 Codex,应当表示 LoopX 管家。前一刀(#4555 / #4556)修掉回答署名之后,我把已安装 Dashboard 拉起来做了现场回读,发现在同一屏上还有第二个同源展示问题:聊天 Runtime 选择器在本机发现 Codex 适配器时优先选它,于是页头 chip 解析出 dsh,选择器与输入框写着 Codex。两个执行器同屏并存,读者无法判断谁在回答。

改动思路

loopx/chat_server.py 的建会话契约已经写明:agent_id 是调用方的显式选择,运维方没选时保持为空,各通道由自己的属主解析默认值。因此前端在运维方未选择时,展示的默认值必须等于通道自己解析出的执行器,而不是本机恰好装了哪个 CLI。

  • 管家上下文:优先取控制面声明的 channel_binding.executor_endpoint(映射到已发现适配器时)。
  • 本机未声明:保持出货默认 Codex(feature-off 等价)。
  • 运维方显式选择:仍然优先,且仍然只有这条路径会让客户端发送端点。
  • Goal 上下文:不变。

具体改动

  • dashboard-page.tsx:新增 stewardExecutorAgentId 与 agentDefaultForContext(contextId);selectedAgentId 改为按上下文解析。
  • fixture.mjs:新增 runtimeAgents fixture 缝(默认 null,行为不变)。
  • execution-chip.mjs:新增两条断言——声明托管宿主时选择器与输入框必须是该宿主且不得出现 Codex;本机未声明时选择器仍是 Chat Codex。
  • typed-actions.mjs:把"Codex 是默认"的描述改为它实际成立的条件(本机未声明管家执行器)。
  • RFC EN + ZH:新增「管家回答身份与 Runtime 选择」小节,记录两条规则与证据。

对主干的风险

低到中,且是默认展示行为变更,在此显式披露。受影响面仅限管家上下文的选择器/输入框显示与由它派生的会话缓存键名;后端解析、投递语义、权限、Goal 上下文均不变。已声明执行器映射不到任何已发现适配器时回落到原有链路。显式选择优先的规则未变。

我的整体评价

正向且 proportional。它和 #4555 是同一类缺陷的两个面:一个回答署名,一个 runtime 呈现。改动量小、边界清楚,并且明确保留了未声明机器上的旧行为,便于独立回滚。

Evidence:

  • exact head f1f72ac
  • tsc --noEmit -p tsconfig.json: passed
  • 完整 personal-workspace-browser-smoke: passed (navigation-sorting, chat-recovery, typed-actions, team-plan, execution-chip)
  • 负向对照: 仅回退 dashboard-page.tsx 后新断言失败,错误文本为 "Chat runtime picker ignored the declared steward executor: Chat Codex",与现场症状一致
  • feature smokes: workspace-theme, agent-family, goal-order, team-plan-proposal, chat-route, dashboard-pwa-bundle-smoke 全通过
  • loopx canary premerge --from-git-diff: merge_gate_passed true, surfaces docs_project_content + public_boundary, docs risk-profile smokes 全过; advisory control-plane-maintainability-ratchet-smoke.py 为 clean origin/main 已知基线

English verdict: APPROVE

@huangruiteng
huangruiteng merged commit 866a829 into main Sep 16, 2026
5 of 6 checks passed
@huangruiteng
huangruiteng deleted the codex/steward-runtime-resolution branch September 16, 2026 13:25
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.

1 participant