文档:订正 M1A-1 的 retry 复核结论,plan 根 run 保源单列为 M1A-3
Project CI / Repository checks (pull_request) Successful in 1m30s
Project CI / Frontend tests (pull_request) Successful in 2m58s
Project CI / Backend tests (pull_request) Successful in 3m59s
Project CI / Native shell tests (pull_request) Failing after 10m47s

M1A-1 把 resolve_game_creator_agent_runtime_retry_configuration_at 判成
「已被 profile 挡住、本包不改函数」。该结论只对了一半:它确实不会让 plan
误得 autonomous 语义,但复核模板只问了「plan 进 matcher 后会不会误得不该
有的语义」,没问「plan 落到通用兜底后会不会丢掉该有的语义」。这个调用点
既是判据也是 run 构造器,两个方向都要问。

缺陷:plan 根 run 是 standard + 顶层无 parent,两个特例分支都不命中,落
agent-background-task 兜底。run_profile 由 agent_runtime_run_profile_identity_at
原样返回,实际只丢 source——第 22 节证据表原写「保留 source/profile」会
误导实现者去修一个没坏的东西,一并订正。

降级无声:retry 走 start_game_creator_agent_background_task_with_link_in_
session_lane_at,该路径对 source 无门禁;validate_agent_runtime_run_profile_
binding_record 也只在 autonomous-game-build 档要求可信 source。于是造出一个
正规启动路径造不出来的状态。

后果分两类。放行类:reject_supervisor_plan_root_steer 只认精确 source,
重试后不再命中,steer 重新放开,违反第 4.1 / 23.1 节裁决。死路类:
root_control_authority 转 false 后广告层删掉 agent.goal_contract 与
agent.acceptance_update,validate_goal_contract_record 也拒绝建约,重试后
的根 run 建不出 Goal Contract,第 13.0 节审批前置门的取证永远收敛不了。
agent.delegate 不受该权限影响、委派照发,所以故障要到审批那一步才暴露。

处置:不回改已合入的 M1A-1,第 23.8 节新列 M1A-3,一并交付第 4.1 节要求的
强判据函数与 generic fallback 前的 exact plan root 分支;M1C-2a 依赖随之改为
M1C-1、M1A-3。修法边界写死:gui/cli 根 run 的现役降级行为不在范围,只能在
兜底之前插分支、不得改兜底默认值。

decision-log 原条目对应半句加删除线并挂指针,避免后续 PR 沿用旧结论。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 13:50:24 +00:00
parent 65f471210f
commit fa42d4e490
2 changed files with 18 additions and 4 deletions
@@ -1,5 +1,16 @@
# 决策记录
## 2026-08-13 订正 `M1A-1` 的 retry 复核结论;plan 根 run retry 保源单列为 `M1A-3`
- **被订正的是同日 `M1A-1` 条第三项第三类中的 `lifecycle_control.rs` `resolve_game_creator_agent_runtime_retry_configuration_at`。** 原结论「不适用且已被 profile 挡住,本包不改函数」**只对了一半**:该处确实不会让 plan 误得 autonomous 语义(`autonomous-game-build` 分支先判 profile),但 `M1A-1` 的复核模板只问了「plan 进 matcher 后会不会**误得**不该有的语义」,没有问「plan 落到通用兜底后会不会**丢掉**该有的语义」。retry 这个调用点既是判据也是 run 构造器,两个方向都要问。
- **实际缺陷**plan 根 run 是 `standard` + 顶层无 parent,两个特例分支都不命中,落入 `agent-background-task` 字面量兜底。`run_profile``agent_runtime_run_profile_identity_at` 原样返回、不受影响,**丢的只有 source**。
- **为什么无声**retry 走 `start_game_creator_agent_background_task_with_link_in_session_lane_at`,该启动路径对 source 无门禁;而 supervisor 正规启动路径 `start_game_creator_supervisor_background_task_for_session_at` 有 trusted 检查。`validate_agent_runtime_run_profile_binding_record` 也只在 `profile == autonomous-game-build` 时要求 trusted source`standard` 档照写。于是 retry 造出一个**正规启动路径造不出来的状态**:`agentId=project-supervisor` + root binding + `standard` + `source=agent-background-task`,全程零告警。
- **后果分两类**。放行类:`reject_supervisor_plan_root_steer` 只认精确 source 字符串,重试后不再命中,**steer 重新放开**,直接违反第 4.1 / 23.1 节裁决。死路类:`root_control_authority` 判 binding.source 是否 trusted,变 `false` 后广告层删掉 `agent.goal_contract``agent.acceptance_update``root_goal_contract_required``false``validate_goal_contract_record` 也拒绝建约——重试后的根 run **建不出 Goal Contract**,第 13.0 节审批前置门要的验收取证永远收敛不了,且**用户会走到审批那一步才撞墙**。`agent.delegate` 不受 `root_control_authority` 影响,委派仍可发出,所以故障不会在 retry 当场暴露。
- **处置**:不回改已合入的 `M1A-1`,新列 `M1A-3`(见技术方案第 23.8 节)一并交付第 4.1 节要求的两件事——① 所有 plan 根 run 例外共用的**强判据函数**(须核 durable binding 并逐项相等,不得只比较内存中的 `runtime.source``M1A-1` 交付的 `agent_runtime_supervisor_source_is_plan` 是纯字符串比较,用于**拒绝** steer 是安全的,但不足以**授予** retry 的 source 保留);② generic standard fallback **之前**的 exact plan root 分支。`M1A-3` 必须早于 `M1C-2a` 合入。
- **修法边界**`project-supervisor-gui` / `-cli` 根 run 重试同样降级为 `agent-background-task`,这是现役行为,不在本次范围。只能在兜底分支**之前**插精确分支,不得改兜底默认值(第 4.1 节「不扩大现役 retry 的破坏面」)。
- **前瞻风险**:M1 将实现「每个项目同一时刻最多一条非终态 plan lineage」。若该判据按 plan source 判定,重试产物会**隐身**——不占 lineage 名额却实际在跑,用户此时能并发开出第二条策划链路。`M1A-3` 修好 source 保留即消解。
- 关联文档:技术方案第 4.1 节(第 5、7 段)、第 22 节证据表 `plan retry` 行、第 23.8 节 `M1A-3`
## 2026-08-13 M1A-1`project-supervisor-plan` 进可信 matchersteer 独立否决
- 落地:新增 `AGENT_RUNTIME_SUPERVISOR_PLAN_SOURCE = "project-supervisor-plan"` 并加入 `agent_runtime_supervisor_source_is_trusted`。启动路径 `start_game_creator_supervisor_background_task_for_session_at` / Tauri command 接受该 source`standard` 放行,`plan + autonomous-game-build` 返回 `kind=plan-autonomous-profile-unsupported`。旧字面 `project-supervisor-plan-chat` 仍不在 matcher 内。
@@ -7,7 +18,7 @@
- 消费点复核(`rg agent_runtime_supervisor_source_is_trusted`,测试除外):
- **适用(plan 进 matcher 后语义正确)**`commands.rs` 启动门、`task_start.rs` 启动门、`goal_contract.rs``validate_goal_contract_record` / `create_game_creator_agent_runtime_goal_contract_at``acceptance_graph.rs``update_game_creator_agent_runtime_acceptance_graph_at` / `goal_contract_acceptance_completion_blocker_at_locked``provider_request_builders.rs``root_control_authority``run_configuration.rs` 根 binding 写入(autonomous 组合另由启动门拒绝)。
- **不适用 → 独立否决**`commands.rs` `steer_game_creator_agent_runtime_task``steering.rs` `goal_contract_root_steer_task_at`(及 `steer_..._for_profile_at` 入口)。不得用「不进 matcher」实现。
- **不适用且已被 profile 挡住,本包不改函数**`task_start.rs` `current_autonomous_game_build_root_task_at`(先要求 `run_profile == autonomous-game-build`);`lifecycle_control.rs` `resolve_game_creator_agent_runtime_retry_configuration_at`autonomous 分支才读 trusted sourcestandard 走 `agent-background-task`);`project_gates.rs` `ensure_current_autonomous_ready_child_mutation_at_locked``profile != autonomous``Ok(())`);`autonomous_completion.rs``autonomous_game_build_root_run_active_at` / `validate_autonomous_completion_contract` / `ensure_autonomous_completion_contract_for_task_at` 均先看 autonomous profile`failed_terminal_autonomous_root_contract_before_task_at` 由后者以及 `autonomous_effective_root_task_at` 调用,后者先要求已存在完成合同(完成合同只由 autonomous 根写入)。
- **不适用且已被 profile 挡住,本包不改函数**`task_start.rs` `current_autonomous_game_build_root_task_at`(先要求 `run_profile == autonomous-game-build`);~~`lifecycle_control.rs` `resolve_game_creator_agent_runtime_retry_configuration_at`autonomous 分支才读 trusted sourcestandard 走 `agent-background-task`~~ **← 本条已于同日订正,见本文件上方「订正 `M1A-1` 的 retry 复核结论」条:结论只对了「不会误得 autonomous 语义」这一半,漏了「会丢掉 plan 语义」这一半;该函数改由 `M1A-3` 处理,后续 PR 不得沿用此处的「本包不改」结论**`project_gates.rs` `ensure_current_autonomous_ready_child_mutation_at_locked``profile != autonomous``Ok(())`);`autonomous_completion.rs``autonomous_game_build_root_run_active_at` / `validate_autonomous_completion_contract` / `ensure_autonomous_completion_contract_for_task_at` 均先看 autonomous profile`failed_terminal_autonomous_root_contract_before_task_at` 由后者以及 `autonomous_effective_root_task_at` 调用,后者先要求已存在完成合同(完成合同只由 autonomous 根写入)。
- 本包不做:工具面、brief、`plan.submit_gdd`、planning sidecar、审批、前端入口。
- 回归:`autonomous_supervisor_source_allowlist_includes_game_chat_and_plan``plan_source_rejects_autonomous_profile_and_accepts_standard``plan_root_steer_is_rejected_inside_and_outside_trusted_matcher``plan_supervisor_start_rejects_autonomous_and_allows_standard`
- 关联文档:`docs/technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md` 第 23.8 节 `M1A-1`