feat(steward): persist guided executor allocation - #4802
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
评审对象:PR #4802,精确 head e9d0103。
动机
这个 PR 解决的是管家执行器“有默认值、没有完整决策边界和可追溯回执”的问题。原有 steward_executor 只能表达首选 endpoint、model 和 reasoning effort;显式调用方可以改选其他 endpoint,但机器配置无法表达“必须锁定”或“只允许在某个集合内自动切换”,Manager Session 也没有保存完整 allocation,因此配置变化和进程重启后,当前会话可能被重新解释。
本次交付是 #4779 路线中的一个完整阶段:显式配置、显式用户选择,以及授权池内基于 availability 的 Agent 选择。它没有提前声称已经实现语义任务匹配。这个边界合理,因为它已经让 Dashboard、Lark 和 CLI 共享同一套选择、持久化和回读语义,同时把后续语义路由留在同一个权限边界内演进。
改动思路
权威关系保持单一:
- steward_executor machine configuration 保存不可推导的 operator intent:preferred、pinned 或 flexible,以及 flexible 的 closed eligible pool。
- chat_manager.manager_executor_allocation 是唯一选择 owner。它综合 machine intent、显式 endpoint、capability availability 和既有 model resolution,产出一份完整 allocation。
- ChatRuntimeController 只执行这个决定:先检查 endpoint availability,再启动 adapter,成功后把 allocation 保存进 Manager Session。
- resume_latest 优先读取 Session allocation,所以 revision A 下启动的会话不会被后来 revision B 的机器配置静默改写。
- manager_channel_binding、Session public projection、Personal Workspace 和 inspect-steward 都只做回读,不重新决定路由。
最强的反对理由是:为了三个 policy 值修改了 runtime、store、CLI、UI、docs 和 packaged assets,范围看起来偏大。但只加 policy field 会留下 restart drift 和“为什么选中它”不可见的问题;只保存 endpoint 又会丢失 model、pool、reason 和 source revision。当前实现复用了既有 machine namespace、Chat owner、Session store 和 shared settings editor,没有建立第二套 selector 或配置库,因此这个 cross-surface 范围与用户可见结果相称。
具体改动
关键代码讲解
- loopx/chat_manager.py:405 的 manager_executor_allocation 负责 policy enforcement。pinned 在 controller.open_session 之前拒绝不同的显式 route;flexible 的自动候选只由 primary 与 eligible_endpoints 构成,capability discovery 不会扩张授权池。
- loopx/capabilities/steward_executor/allocation.py:63 的 normalize_manager_executor_allocation 固化 Session receipt:policy、reason、endpoint、pool、revision、model 和 effort 都是 closed/typed 字段。flexible endpoint 必须属于 pool,非 flexible allocation 不允许携带 pool。
- loopx/chat_manager.py:834 的 open_manager_session 在隐式 resume_latest 时优先复用已有 Session allocation;显式新选择仍会经过当前 policy 重新授权。
- loopx/chat_runtime.py:510 的 ChatRuntimeController.open_session 用 allocation 中的 model/effort 启动真实 adapter,并仅在启动成功后持久化 Manager Session。
- machine-configuration-settings.tsx:42 的 guided editor 把 steward v0 编辑迁移到 v1,并在 preview 前拒绝空 pool、重复 endpoint、primary 不在 pool 等非法 flexible 状态;server normalizer 仍是最终 authority。
其余改动把同一事实投射到 Dashboard runtime details、Zod contract、inspect-steward CLI、RFC 和 operator/reference 文档。旧 v0 machine document 继续接受并映射成 preferred;旧 Manager Session 没有 allocation 时仍走原 resolver。Dashboard 首屏没有改变,新增信息位于现有 machine settings 和折叠 runtime details。
对主干的风险
最大的风险是 selector、Session restore 和 readback 之间出现分叉,导致一边显示 Codex/GPT,另一边实际启动 dsh,或 flexible 在 primary 不可用时越过授权池。当前 exact head 通过以下证据覆盖了这条链路:
- 85 个 focused Python tests 通过,覆盖 policy validation、pinned/out-of-pool rejection、availability fallback、Session persistence/resume、API 和 manager binding。
- base/head 使用相同输入比较,默认 Codex/gpt-6-astra 与 environment-selected dsh/deepseek-v4-flash 的既有字段保持一致。
- source-checkout inspect-steward 回读 codex、gpt-6-astra、preferred、product_default 和空 pool;真实 steward binding smoke 通过。
- Chat build、capability configuration smoke、Personal Workspace contract smoke、packaged execution-chip scenario,以及独立的 steward settings preview/apply browser probe通过;机器配置 apply 保留 exact preview revision。
- git diff --check 通过,构建后 branch 保持干净。
完整 packaged Personal Workspace catalog 在本次复核中停在一个较早、与本改动无关的 Goal lifecycle timing 场景,因此我不把它记为 full pass。受影响的 execution readback 与 steward settings 路径随后独立运行并通过。Live provider request 也没有执行;这里的关键 contract 是 provider 启动之前的授权、model binding 与 Session persistence,真实 filesystem store 和 runtime boundary 已经覆盖。
语义与 CI 对齐
这次是对既有 steward_executor 和 manager_channel_binding vocabulary 的扩展,并新增范围准确的 manager_executor_allocation_v0;没有把 ephemeral selection 说成 peer Agent authority,也没有把 availability 当成授权。错误文本和文档保持 goal/domain neutral,machine policy 明确是 machine-enforced obligation,不是 guidance。评审 packet 的 wait_for_ci 为 false,所以结论基于 exact-head repository-native local validation,没有把 pending remote CI 当作通过证据。
我的整体评价
没有 blocking finding。这个 PR 把“默认选谁”提升成一份可配置、可约束、可持久化、可回读的 Session decision,并且保留 Codex/GPT 的 shipped default、v0 compatibility 和 explicit user intent。代码量主要来自跨入口完整性、tests/fixtures、docs 和 packaged assets;核心 authority 仍集中在现有 owner 中。
Future-facing pass 已检查:把前端 allocation reason 的条件分支整理成 typed localization map 会稍微降低后续维护成本,但当前不影响语义,也不值得扩大本 PR。后续应在此 authority boundary 上补 semantic task-fit evidence 与 packaged first-use/correction qualification。
English verdict: APPROVE - exact head e9d0103; no blocking findings. The closed policy/pool, restart-stable Session allocation, backward-compatible defaults, CLI/Dashboard readback, and affected UI paths were validated locally.
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Exact-head review addendum
Review target: PR #4802 at 3c5860b7dceb2b2bb909b9840dedb18bfd7b75af.
The follow-up commit repairs the only branch-local CI regression found after the prior review. steward_executor.allocation no longer imports the control-plane execution-profile graph, machine_defaults no longer imports chat_manager at runtime, and execution-profile plus orchestration validation now reuse one provider-neutral REASONING_EFFORTS value. This removes the mypy import expansion and two duplicate vocabularies without changing allocation policy, persisted Session fields, defaults, or fallback authority.
Exact-head evidence:
- strict mypy: 22 configured files, 0 errors;
- Ruff: passed for all five files in the repair;
- focused pytest: 85 passed across steward allocation/configuration, Chat API, manager context, and channel binding;
- dashboard acceptance, DCO, dependency review, both optional-Ark contracts, PostgreSQL integration, desktop builds, Node compatibility, Stage 2C, and completed Python shards: passed;
- semantic vocabulary smoke: passed under the source-checkout Python environment with repository Node dependencies;
- change-quality receipt
cqr_0353f91fa205361083d3: valid for the exact current base and diff.
I found no new blocking correctness, authority, configuration, compatibility, privacy, or presentation issue in the final diff. The PR is still not merge-ready because current origin/main has two independent CI regressions: the module-budget debt is repaired by #4793, and the date-expired Lark fixture is repaired by #4798. Those dependencies remain review-required and should land before this branch is refreshed and its final CI/readback is judged.
English verdict: APPROVE THE DIFF - exact head 3c5860b7dceb2b2bb909b9840dedb18bfd7b75af; no blocking finding in this PR, with merge readiness held on #4793, #4798, refreshed-base CI, and maintainer review.
Integration qualification updateReviewed PR #4802 head
This proves that #4793 contains both integration repairs needed by #4802: the module-budget cleanup and a single fixed-clock repair for the dated Lark fixtures. PR #4798 is therefore not an additional integration dependency for #4802. The remaining merge path is explicit: a maintainer must update and land #4793 (its exact-head approval is valid, while merge readiness currently reports only |
The steward's machine setting previously expressed only a preferred executor. A new manager Session could reinterpret that preference after configuration changes or restart, automatic fallback had no closed authorization boundary, and operators could not inspect why a route was selected.
This change delivers the guided allocation slice described by #4779:
steward_executorto a backward-compatible v1 contract withpreferred,pinned, andflexiblepolicies;loopx chat-endpoint inspect-steward;This stage covers explicit configuration, explicit user selection, and availability-based Agent choice inside an authorized pool. Semantic task-fit routing and live first-use/correction qualification remain in the RFC program; this PR does not claim those outcomes.
Validation:
3c5860b7d.semantic-vocabulary-drift-smoke.pypassed under the source-checkout Python 3.13 environment with repository Node dependencies. The premerge host's/usr/bin/python3is 3.9 and fails before scanning atzip(strict=...)on both this branch andorigin/main.origin/mainfailures: module budgets tracked by refactor(chat): remove inherited module-budget regressions #4793 and a date-expired Lark fixture tracked by test(lark): date the manager-context fixtures from the run #4798; this diff adds neither finding.cqr_0353f91fa205361083d3(pass, exact head/diff).The future-facing refactor moved allocation validation and runtime projections into the steward-executor contract.
loopx/chat_runtime.pyremains at its inherited 1,566-line ceiling with zero net growth.No first-viewport presentation changed; the UI work is confined to the existing machine settings and collapsed manager runtime details.