清理旧策划修订写入入口并记录认证契约冲突

删除无生产调用的用户修订写入函数,保留持久记录兼容与门禁
调整原有门禁测试的历史记录夹具,保持行为断言
将 OAuth 契约冲突与关闭条件记录到 AGC 主方案
警告清单仅保留 AuthBridge 暂缓状态及主方案链接
This commit is contained in:
2026-09-23 17:58:17 +00:00
parent c62a911745
commit 7d6fff577d
3 changed files with 60 additions and 66 deletions
@@ -532,19 +532,10 @@ pub(crate) fn mark_static_delegate_delivery_ready_with_result_at(
/// claim 里的 `structuredResult` 是「父 Agent 在那个 action 上观察到了什么」的冻结
/// 快照;delivery 是当前真相。两者绝大多数时候必须逐字相等——不等就是漂移或篡改。
///
/// 唯一的例外是审批:用户在审批卡上点「修改 / 退回」后,
/// `mark_static_delegate_delivery_user_revision_requested_at` 会把 delivery 从
/// `EvidenceReady` 原地改写成 `UserRevisionRequested`,而 claim 快照仍停在
/// `EvidenceReady`。那不是漂移,是一次只由审批产生、且只能朝这个方向走的合法转移
/// 快照记的那句「当时观察到 evidence-ready」现在依然为真,不该被改写。
///
/// 按全等判会把它当成冲突:`agent.run_status` 每次重放这条 claim 都 failed
/// Supervisor 永远拿不到回执、也就永远建不出修订委派。生产实测卡死在第 43 轮空转,
/// 报「静态委派 claim 与 delivery 身份或结果冲突」。原型没有 claim 这层快照,单一
/// 真相就地改,结构上不存在这个冲突——这里翻译的是同一个语义:比较的是「delivery 是
/// 不是 receipt 的合法后继」,不是「两者永远全等」。
///
/// 放行面刻意压到最小:除 `contractStatus` 外每个字段都必须逐字不变,且方向唯一。
/// 兼容旧策划审批留下的持久记录:delivery 已从 `EvidenceReady` 转为
/// `UserRevisionRequested`,claim 仍保存当时观察到的 `EvidenceReady`。
/// 旧审批写入入口已退役,这里只识别存量记录的合法后继,不要求恢复旧写入链。
/// 除 `contractStatus` 外每个字段都必须逐字不变,且仅允许上述单向转移
fn static_delegate_structured_result_follows_claim_snapshot(
snapshot: Option<&StaticDelegateStructuredResult>,
current: Option<&StaticDelegateStructuredResult>,
@@ -565,42 +556,6 @@ fn static_delegate_structured_result_follows_claim_snapshot(
rebased == *snapshot
}
/// Mark an already claimed, evidence-ready planning delivery as waiting for a
/// user-requested revision. Approval is the only producer of this durable
/// status; keeping the transition here makes its evidence precondition and
/// idempotency explicit instead of allowing a generic delivery writer to
/// manufacture the state.
pub(crate) fn mark_static_delegate_delivery_user_revision_requested_at(
root: &Path,
parent_agent_id: &str,
parent_run_id: &str,
delegation_id: &str,
) -> Result<StaticDelegateDeliveryRecord, String> {
validate_static_delegate_id(parent_agent_id, "parentAgentId", 96)?;
validate_static_delegate_id(parent_run_id, "parentRunId", 160)?;
validate_static_delegate_id(delegation_id, "delegationId", 160)?;
let mut delivery = read_static_delegate_delivery_at(root, delegation_id)?
.ok_or_else(|| format!("静态委派 delivery 不存在:{delegation_id}"))?;
if delivery.parent_agent_id != parent_agent_id || delivery.parent_run_id != parent_run_id {
return Err("用户修订只能改写同一 Supervisor 父 run 的 delivery".to_string());
}
if delivery.status != StaticDelegateDeliveryStatus::ClaimedByParent {
return Err("用户修订只能改写已由 Supervisor 认领的 delivery".to_string());
}
let Some(result) = delivery.structured_result.as_mut() else {
return Err("用户修订的原 delivery 缺少 structuredResult".to_string());
};
match result.contract_status {
StaticDelegateContractStatus::UserRevisionRequested => return Ok(delivery),
StaticDelegateContractStatus::EvidenceReady => {}
_ => return Err("用户修订只能从 EvidenceReady delivery 派生".to_string()),
}
result.contract_status = StaticDelegateContractStatus::UserRevisionRequested;
delivery.updated_at = unix_timestamp();
write_static_delegate_delivery_at(root, &delivery)?;
Ok(delivery)
}
pub(crate) fn suppress_static_delegate_delivery_at(
root: &Path,
expected: &StaticDelegateDeliveryRecord,
@@ -3297,16 +3252,10 @@ mod tests {
parent_run_id,
"m1c1-user-revision-barrier-first",
None,
StaticDelegateContractStatus::EvidenceReady,
StaticDelegateContractStatus::UserRevisionRequested,
);
// 直接构造旧审批已写入的持久状态,验证现役 barrier 的读取行为。
write_static_delegate_delivery_at(&root, &first).expect("write first delivery");
mark_static_delegate_delivery_user_revision_requested_at(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
parent_run_id,
&first.delegation_id,
)
.expect("mark first delivery for user revision");
let first_barrier = static_delegate_completion_barrier_at(
&root,
@@ -3362,13 +3311,13 @@ mod tests {
"the previous revision is satisfied once its continuation is claimed"
);
mark_static_delegate_delivery_user_revision_requested_at(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
parent_run_id,
&continuation.delegation_id,
)
.expect("mark a repair-node delivery for the second revision");
continuation
.structured_result
.as_mut()
.expect("continuation structured result")
.contract_status = StaticDelegateContractStatus::UserRevisionRequested;
write_static_delegate_delivery_at(&root, &continuation)
.expect("write repair-node delivery awaiting a second revision");
let second_barrier = static_delegate_completion_barrier_at(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
@@ -7,7 +7,7 @@
## 1. 基线与范围
首次诊断的基线提交为 `016356e509f11a1a638ce45ed51b9e40ef3e36a2`,诊断时工作树干净。环境为 Windows x64、Rust `1.98.1`、Node `v24.15.0`、npm `12.0.2`。第 2~6 节和附录保留首次诊断快照;后续处理状态及契约核查见第 7~20 节,不能将附录的全部条目视为仍未解决。
首次诊断的基线提交为 `016356e509f11a1a638ce45ed51b9e40ef3e36a2`,诊断时工作树干净。环境为 Windows x64、Rust `1.98.1`、Node `v24.15.0`、npm `12.0.2`。第 2~6 节和附录保留首次诊断快照;后续处理状态及契约核查见第 7~22 节,不能将附录的全部条目视为仍未解决。
AGC Rust 使用默认 features、dev profile237 是本轮编译器诊断数,不代表 237 个独立根因,也不是所有平台、features 和 test targets 的总数。另有 5 条不带常规源码 span 的 ts-rs 宏提示,不计入 237。
@@ -652,6 +652,25 @@ W076 只将 Pending(String) 收窄为 Pending;三处生产返回前继续记
按用户要求未跑全量编译;AGC 默认应用构建、正式 editor features、Linux/macOS 构建及应用单测均未执行。最近一次应用 warning 实测仍为第 14 节的 50 条;第 15~20 节合计处理 46 条,预期剩余 **4 条暂留契约项:W004、W005、W006、W113**,不能将此预期当作重新编译结果。5 条 ts-rs 提示和前端 chunk 体积提示另行处理。
## 21. 旧策划用户修订写入入口清理(2026-09-23)
本批只处理 W113。第 13 节依据 Fast GDD 审批说明提出的疑点已消解:策划 V1/V2 均已退役,现役 Design Agent 的审批修改 `DesignSession`,不写静态委派 delivery。不存在要求恢复旧审批写入链的现行合同;此结论替代此前 W113 的“契约待厘清”状态。
- 删除无生产调用的 `mark_static_delegate_delivery_user_revision_requested_at`,不将旧业务入口藏入 `cfg(test)`
- 保留 `UserRevisionRequested` 的持久化 wire 值、证据校验、claim 快照合法后继判断、lineage 计数和完成 barrier;历史项目记录仍按原规则读取与重放,不修改或删除用户数据。
- 原 barrier 测试中的两次 helper 调用改为直接准备同一持久状态:首条记录以 `UserRevisionRequested` 构造,后续修订记录保留原证据,仅更新状态并落盘。原有首次阻拦、等待继续、继续完成解除以及再次修订阻拦的全部断言保留;未迁移测试到其它业务入口,也未新增测试。
- claim 兼容注释改为存量记录语义,不再声称现役审批会调用旧 helper。现役 Design Agent 审批及 OAuth/AuthBridge 三条均未修改。
验证:定向 rustfmt、编码检查、文档索引和 `git diff --check`;静态核对旧 helper 无代码引用及既有 barrier 断言不变。未运行 Cargo 编译、应用测试或全量构建,不能将静态检查视为运行验证。
最近一次应用 warning 实测仍为 50 条;第 15~21 节合计处理其中 47 条,预期剩余 **W004、W005、W006 共 3 条 AuthBridge 契约项**,尚未重新编译确认。5 条 ts-rs 提示及前端 chunk 体积提示仍另行处理。
## 22. AuthBridge / OAuth 契约冲突与暂缓决策(2026-09-23)
W004(认证桥 API URL)、W005(认证文件读取上限)、W006(`CodexAppServerCredential::AuthBridge`)明确暂缓。生产入口尚未接通 OAuth,下游实现与文档承诺仍存在,是否支持待定;保留现有实现和 warning,不以 `allow` 或扩大 `cfg(test)` 隐藏。
完整冲突证据、暂缓边界和“退役 / 正式接入”两种关闭条件维护在 [AGC 主方案](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md#oauth-认证路线的契约冲突与待决边界)。本清单只跟踪诊断状态,删除本清单不影响契约记录。
## 附录:237 条编译器诊断位置
以下是诊断的人工可读整理,不保存原始构建日志、本机路径或 target 缓存路径。位置相对 `apps/ai-game-creator-shell/src-tauri/`;行号只对应本节基线,修改后以符号搜索及重新编译为准。每条保留一个主要 span,编号用于本清单内跟踪,不表示独立业务缺陷。生成产物项须回到 `build_support/runtime_prompt_bundle.rs` 处理。
@@ -8,7 +8,31 @@
图片产物按项目需求选择,不恢复按固定 Agent 身份要求视觉资源的旧完成门禁。已停用门禁的空调用、不可达检查和无消费者包装直接清理;现役 `validate_manifest_required_visual_asset`、图片检查、内部切片提交及各完成合同继续按各自调用场景执行,不因清理旧门禁而一并删除。
自主任务父身份校验只核对当前父任务及 Run Profile 绑定,不代表 Goal Contract 已持久化,也不新增等待 Goal 文件的前置条件。manifest seed 同步保留执行状态,不以素材检查结果重新推导任务状态。用户修订的持久状态判据继续供 lineage 重放与修订请求校验使用,不依赖已无消费者的查询包装。
自主任务父身份校验只核对当前父任务及 Run Profile 绑定,不代表 Goal Contract 已持久化,也不新增等待 Goal 文件的前置条件。manifest seed 同步保留执行状态,不以素材检查结果重新推导任务状态。用户修订的持久状态判据继续供 lineage 重放与修订请求校验使用,不依赖已无消费者的查询包装或旧策划审批写入入口。现役 Design Agent 审批只更新自身会话;旧 `UserRevisionRequested` delivery 仍保留读取、claim 重放和完成门禁兼容,不为消除 warning 删除持久状态支持
## OAuth 认证路线的契约冲突与待决边界
**状态(2026-09-23):明确暂缓,待决定 AGC 是否支持使用用户 Codex OAuth 登录态。** AuthBridge 认证桥尚未接通正式入口;既不能认定为现役已支持能力,也不能仅因生产无构造点而宣布整条链退役。
### 冲突事实与证据
- **生产入口**`src/agent/codex_app_server/mod.rs``acquire_at_workspace` 只在正式路径构造 `PlatformSession` 或显式自定义连接的 `AppDataKey``find_game_creator_codex_auth_path``read_game_creator_codex_auth_bridge` 及旧凭据 resolver 限定为 `cfg(test)`;没有正式配置 / feature 接通 AuthBridge 构造。当前[模型别名与对话选择方案](./【技术方案】AGC后台模型别名与对话选择-2026-09-05.md)描述的是官方平台路由与显式自定义 Key。
- **仍存在的实现与承诺**:提交 `485ed50b26217d20fad2ac192c949fd3f20914da`2026-09-21PR #439)新增 `model_catalog.rs``model_catalog/auth_handoff.rs` 及相关测试,并在[本方案“SDK 串行工具的等价接入”](#sdk-串行工具的等价接入)写入 OAuth 模型目录来源校验、私有凭据轮换续传及身份隔离要求。这里“目录”指模型及能力列表,不是文件目录。
- **时间顺序**:正式凭据 fallback 被限定测试的记录见 `2e15289264`2026-09-02);9 月 21 日提交新增下游 OAuth 处理,却仍保留该测试限定入口。因此不能简单把 OAuth 承诺当作早于现役路线的过期说明。
- **验证边界**:OAuth 目录测试使用真实 Codex 配合模拟认证和本地服务,轮换测试验证私有缓存及身份隔离;这些不能证明正式客户端已接通真实用户 OAuth 登录。每回合模型目录捕获也服务现役平台代理,不能随 OAuth 专属链整体删除。
### 暂缓期间的处理
保留认证桥相关 warning、现有实现及待决记录,不新增 `allow`,不为清零把整条业务链继续移入 `cfg(test)`,不擅自接通用户登录态读取,也不把现状记录为“已支持 OAuth”。该待决项与其它已完成的 warning 清理独立,不阻止其它改动提交。
### 下一决策点与关闭条件
| 决策 | 关闭条件 |
| --- | --- |
| 不支持用户 Codex OAuth 登录态 | 同步撤销相关文档承诺,删除 AuthBridge reader / variant、OAuth 专属目录分支、轮换链及专属测试;保留现役平台 / 自定义 Key 路由、共享模型目录和隔离运行环境,完成定向验证。 |
| 支持用户 Codex OAuth 登录态 | 先明确入口、授权与凭据隔离合同,再接通正式构造路径;验证真实登录、模型目录来源、轮换续传、身份切换与错误恢复,不能仅凭模拟测试或取消编译告警关闭。 |
当前尚未选择上述任一路线。本节是该冲突的维护位置,不依赖临时编译警告清单;决定后在此更新为最终合同,决策历史由 Git 保留。记录冲突本身不构成功能接入或退役决定。
## 2026-09-23 Direct 宿主继续请求输入修复
@@ -134,6 +158,8 @@
### SDK 串行工具的等价接入
> OAuth 状态(2026-09-23):下列 OAuth 目录与凭据轮换要求已有下游实现和测试,但正式凭据入口尚未接通 AuthBridge。是否支持用户 Codex OAuth 登录态仍待决,详见本方案的[契约冲突与待决边界](#oauth-认证路线的契约冲突与待决边界)。平台代理使用的共享模型目录能力继续有效。
- DirectProject 对外保留完整补丁和计划能力,由宿主 MCP 提供 `agc_apply_patch``agc_update_plan`。精确关闭 SDK 的旧计划工具注册;缺少合法回包通道的原生问答工具不再声明可用,需要用户信息时使用现有聊天。
- 通过同一可信捆绑 Codex 和身份/路由隔离的 HOME 取得完整模型目录,只置空 `apply_patch_tool_type` 以移除 SDK 全局串行补丁处理器。不得修改模型名称或其它 metadata,不为未知模型伪造显式条目;匹配和 fallback 仍由 SDK 执行。
- 代理模式的 bundled 目录和 OAuth 的实际远端/有效缓存来源分别核验,不能把模型目录导出 exit0 当作远端成功。每个 Direct 用户回合创建新模型目录快照和进程;旧执行器完全收束后才进入下一回合,不在活动执行中重启或重放。该行为是按回合冻结 metadata,不是实例内动态 overlay。