补齐总控静态与隔离混合协作验收

新增同一 Supervisor Session/run 下 static delegate 与 isolated all-join 的真实 Provider 门禁。
补齐首批确认、并行重叠、强杀恢复、持久化身份和零泄漏审计。
增加双向完成屏障回归、命令入口及 Runtime/开发文档记录。
修正原生计划元调用与业务 action 数量的验收边界。
This commit is contained in:
AIGameCreator App
2026-07-17 16:37:26 +08:00
parent 4474fb9eab
commit c607451edd
9 changed files with 2298 additions and 192 deletions
+1
View File
@@ -15,6 +15,7 @@
"agent-run": "node scripts/run-cli-with-config.mjs --agent-run",
"agent-run:smoke": "node scripts/smoke-agent-run-local-provider.mjs",
"agent-runtime:real-e2e": "node scripts/agent-runtime-real-e2e.mjs",
"agent-runtime:mixed-swarm-real-e2e": "node scripts/agent-runtime-real-e2e.mjs --suite supervisor-swarm-static-isolated-autonomous-chat",
"agent-runtime:supervisor-swarm-autonomous-chat-real-e2e": "node scripts/agent-runtime-real-e2e.mjs --suite supervisor-swarm-autonomous-chat",
"agent-runtime:supervisor-swarm-transient-retry-real-e2e": "node scripts/agent-runtime-real-e2e.mjs --suite supervisor-swarm-transient-retry",
"agent-runtime:steer-real-e2e": "node scripts/agent-runtime-steer-real-e2e.mjs",
File diff suppressed because it is too large Load Diff
@@ -33704,7 +33704,7 @@ pub(crate) fn game_creator_agent_runtime_tool_plan_system_prompt_for_agent(
return prompt;
}
let prompt = format!(
"{prompt}\n\n你当前是项目唯一面向用户的 Project Supervisor,并拥有最终回复权。每一轮都必须把用户原始目标视为最高层业务目标,专业 Agent 回执只能补充证据,不能把回执内容改写成新目标。总控不能替代已有专业角色完成其领域交付:只要仓库目标同时包含两个以上互不依赖的专业方向,就必须自行查看静态角色目录,选择最匹配的不同专业 Agent,并在同一个 native planning 批次用带 acceptanceCriteria 和 expectedArtifacts 的 agent.delegate 发起委派,让这些方向并行;用户不需要点名 Agent、指定数量或提醒并行。只有没有匹配专业角色、纯协调工作或一两步轻量读取时才由总控直接处理。互不重叠的临时并行检查通过 agent.spawn_isolated 分派;已有委派未收束时不要重复委派。需要等待专业 Agent 时返回空 response,让 Runtime 的 delegate/all-join 完成屏障保持同一父 run;取得 readyDelegateReceipts 或 readyIsolatedJoins 后直接整合结果。readyDelegateReceipts 中 contractStatus=evidence-ready 只说明终态、产物和验证等客观证据齐全,你仍须按 acceptanceCriteria 判断语义是否满足;needs-repair 不得当作成功。客观或语义不满足时可以发起一次新 agent.delegate,并把 repairOfDelegationId 指向已认领原 delivery;不得对返工再返工或为同一原 delivery 创建第二个返工。专业结果冲突且无法依据用户目标裁决时,合并问题后用一次 user.input_request 询问用户。只有实现路径、产品取舍或缺失事实会实质改变结果时才调用 user.input_request;项目内可读取事实、权限确认和工具失败不得伪装成用户问题。只在所有必要回执已认领、所有必要返工也已认领、项目副作用已验证且没有待确认动作或待回答请求时给用户最终回复。不要向用户暴露内部 task/event、工具计划、动态 child ID 或调试状态。"
"{prompt}\n\n你当前是项目唯一面向用户的 Project Supervisor,并拥有最终回复权。每一轮都必须把用户原始目标视为最高层业务目标,专业 Agent 回执只能补充证据,不能把回执内容改写成新目标。总控不能替代已有专业角色完成其领域交付:只要仓库目标同时包含两个以上互不依赖的专业方向,就必须自行查看静态角色目录,选择最匹配的不同专业 Agent,并在同一个 native planning 批次用带 acceptanceCriteria 和 expectedArtifacts 的 agent.delegate 发起委派,让这些方向并行;用户不需要点名 Agent、指定数量或提醒并行。只有没有匹配专业角色、纯协调工作或一两步轻量读取时才由总控直接处理。互不重叠的临时并行检查通过 agent.spawn_isolated 分派;当同一目标同时需要边界清晰的专业委派和互不重叠的临时检查时,必须把两类协作放进同一个 native planning 批次一次性提交,不能拆成先后轮次。提交首个协作批次前,先分别完整枚举当前目标中的长期专业交付和临时隔离检查;两类都非空时,遗漏任一类的批次都不得提交。已有委派未收束时不要重复委派。需要等待专业 Agent 时返回空 response,让 Runtime 的 delegate/all-join 完成屏障保持同一父 run;取得 readyDelegateReceipts 或 readyIsolatedJoins 后直接整合结果。readyDelegateReceipts 中 contractStatus=evidence-ready 只说明终态、产物和验证等客观证据齐全,你仍须按 acceptanceCriteria 判断语义是否满足;needs-repair 不得当作成功。客观或语义不满足时可以发起一次新 agent.delegate,并把 repairOfDelegationId 指向已认领原 delivery;不得对返工再返工或为同一原 delivery 创建第二个返工。专业结果冲突且无法依据用户目标裁决时,合并问题后用一次 user.input_request 询问用户。只有实现路径、产品取舍或缺失事实会实质改变结果时才调用 user.input_request;项目内可读取事实、权限确认和工具失败不得伪装成用户问题。只在所有必要回执已认领、所有必要返工也已认领、项目副作用已验证且没有待确认动作或待回答请求时给用户最终回复。不要向用户暴露内部 task/event、工具计划、动态 child ID 或调试状态。"
);
format!(
"{prompt}\n\n普通 agent.run_status 的 claimedDelegateContracts 只提供已认领合同目录。语义复核或返工前必须用原 delegationId 再调用 agent.run_status,读取 claimedDelegateContract 中未截断的 acceptanceCriteria 和 expectedArtifacts,并在 repair agent.delegate 中逐项原样提交。若返工因合同未完整继承而失败,失败 observation 中的 claimedDelegateContract 是同一 durable delivery 的权威快照,必须逐项据此修正;只有该字段缺失或身份不确定时才按同一 delegationId 重读,不得无目标地重复 run_status 或从 action_history 摘要猜测。"
@@ -14768,6 +14768,197 @@ async fn project_supervisor_mixed_waiting_recovery_does_not_plan_until_all_join_
fs::remove_dir_all(root).ok();
}
#[tokio::test]
async fn project_supervisor_mixed_waiting_recovery_does_not_plan_until_static_delivery_ready() {
use platform_agent::game_creation::{
GameCreationIsolatedAgentArtifact, GameCreationIsolatedAgentChildResult,
GameCreationIsolatedAgentChildSpec, GameCreationIsolatedAgentJoinMode,
GameCreationIsolatedAgentResultStatus, GameCreationIsolatedAgentSpawnRequest,
};
let root = unique_project_path();
init_local_game_project_at(&root, "project-1", "混合委派反向等待恢复测试")
.expect("project init");
let (sender, receiver) = mpsc::channel();
let base_url = spawn_mock_llm_server_responses_with_capture(
vec![final_tool_plan_response(
"不应在 static delivery ready 前请求 Provider",
)],
Some(sender),
);
let _config_guard = write_test_local_config(format!(
r#"{{
"agentLlm": {{
"project-supervisor": {{
"apiKey": "mixed-reverse-waiting-key",
"baseUrl": {base_url:?},
"model": "mixed-reverse-waiting-model",
"apiKind": "openai_responses"
}}
}}
}}"#
));
let task = "等待已认领的动态隔离 all-join 与尚未完成的静态专业回执";
let parent_run_id = "project-supervisor-mixed-reverse-waiting-run";
let mut parent_state = start_game_creator_agent_runtime_task_at(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
task,
parent_run_id,
"agent-chat",
"等待反向混合委派",
vec!["取得两类交付后统一收束".to_string()],
)
.expect("start reverse mixed waiting parent");
let static_delivery = new_static_delegate_delivery(
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
&parent_state.session_id,
parent_run_id,
"project-supervisor-mixed-reverse-static-action",
"project-supervisor-mixed-reverse-static-delivery",
"design-director",
"project-supervisor-mixed-reverse-static-session",
"project-supervisor-mixed-reverse-static-run",
);
create_or_read_static_delegate_delivery_at(&root, &static_delivery)
.expect("create waiting static delivery");
fs::create_dir_all(root.join("game/mixed-reverse")).expect("create mixed evidence directory");
fs::write(
root.join("game/mixed-reverse/evidence.txt"),
"mixed reverse evidence\n",
)
.expect("write mixed evidence");
let isolated_request = GameCreationIsolatedAgentSpawnRequest {
children: vec![GameCreationIsolatedAgentChildSpec {
template_agent_id: "code-prototype".to_string(),
task: "完成独立 mixed 只读检查".to_string(),
acceptance_criteria: vec!["mixed 只读检查已完成".to_string()],
expected_artifacts: vec!["game/mixed-reverse/evidence.txt".to_string()],
write_scopes: vec!["game/mixed-reverse/**".to_string()],
}],
join_mode: GameCreationIsolatedAgentJoinMode::All,
};
let group = create_or_read_isolated_group_at(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
parent_run_id,
&parent_state.session_id,
"project-supervisor-mixed-reverse-isolated-action",
&isolated_request,
)
.expect("create reverse mixed isolated group");
let instance = resolve_isolated_agent_instance_at(&root, &group.instance_ids[0])
.expect("resolve reverse mixed isolated instance");
record_isolated_child_result_at(
&root,
&GameCreationIsolatedAgentChildResult {
delegation_id: instance.delegation_id.clone(),
instance_id: instance.instance_id.clone(),
template_agent_id: instance.template_agent_id.clone(),
run_id: instance.run_id.clone(),
status: GameCreationIsolatedAgentResultStatus::Completed,
summary: "mixed 只读检查已完成".to_string(),
artifacts: vec![GameCreationIsolatedAgentArtifact {
path: "game/mixed-reverse/evidence.txt".to_string(),
sha256: "c".repeat(64),
}],
evidence: Vec::new(),
verified_revision: None,
error: None,
},
)
.expect("record reverse mixed isolated result")
.expect("reverse mixed isolated join ready");
let claim_action_id = "project-supervisor-mixed-reverse-run-status-action";
let claimed_observation = observe_agent_runtime_run_status(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
parent_run_id,
Some(claim_action_id),
&serde_json::json!({ "scope": "self" }),
);
assert_eq!(claimed_observation.status, "ok");
assert!(claimed_observation
.detail
.as_deref()
.is_some_and(|detail| detail.contains("readyIsolatedJoins")));
assert!(isolated_join_completion_barrier_at(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
parent_run_id,
)
.expect("read claimed isolated barrier")
.is_none());
let waiting_static = static_delegate_completion_barrier_at(
&root,
GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID,
parent_run_id,
)
.expect("read waiting static barrier");
assert_eq!(waiting_static.waiting_count, 1);
parent_state.status = "running".to_string();
parent_state.phase = "waiting-for-isolated-join".to_string();
parent_state.current_action = "等待动态隔离 Agent 的 all-join".to_string();
parent_state.waiting_on = "静态与隔离 Agent 完成".to_string();
parent_state.next_step = "保持等待,不请求 Provider".to_string();
parent_state.loop_iteration = 5;
parent_state.max_loop_iterations = 18;
append_game_creator_agent_runtime_task(&root, &parent_state)
.expect("append reverse mixed waiting parent task");
write_game_creator_agent_runtime_state(&root, &parent_state)
.expect("persist reverse mixed waiting parent state");
let observations = vec![claimed_observation];
let context = build_game_creator_agent_runtime_context_bundle(
&root,
&parent_state,
task,
&AgentRuntimeToolPlan::default(),
&observations,
5,
&AgentRuntimeContextWindowTracker::default(),
)
.expect("build reverse mixed waiting context");
write_game_creator_agent_runtime_context_bundle(&root, &context)
.expect("persist reverse mixed waiting context");
resume_game_creator_agent_background_tasks_at(&root)
.expect("resume reverse mixed waiting parent");
let deadline = std::time::Instant::now() + Duration::from_secs(2);
loop {
let runtime =
read_game_creator_agent_runtime_at(&root, GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID)
.expect("read reverse mixed waiting parent")
.state;
if runtime.phase == "waiting-for-delegate-receipts" {
assert_eq!(runtime.run_id, parent_run_id);
assert_eq!(runtime.loop_iteration, 5);
assert_eq!(runtime.max_loop_iterations, 18);
break;
}
assert!(
std::time::Instant::now() < deadline,
"mixed parent did not switch to static waiting"
);
tokio::time::sleep(Duration::from_millis(10)).await;
}
assert!(receiver.recv_timeout(Duration::from_millis(200)).is_err());
resume_game_creator_agent_background_tasks_at(&root)
.expect("repeat reverse mixed waiting parent resume");
assert!(receiver.recv_timeout(Duration::from_millis(200)).is_err());
let stable =
read_game_creator_agent_runtime_at(&root, GAME_CREATOR_PROJECT_SUPERVISOR_AGENT_ID)
.expect("read stable reverse mixed waiting parent")
.state;
assert_eq!(stable.run_id, parent_run_id);
assert_eq!(stable.phase, "waiting-for-delegate-receipts");
assert_eq!(stable.loop_iteration, 5);
fs::remove_dir_all(root).ok();
}
#[test]
fn repository_context_v1_pending_fingerprint_blocks_project_mutation() {
let root = unique_project_path();
@@ -45182,6 +45373,8 @@ async fn project_supervisor_prompts_are_total_control_and_reject_isolated_templa
"专业 Agent 回执只能补充证据",
"总控不能替代已有专业角色",
"同一个 native planning 批次",
"必须把两类协作放进同一个 native planning 批次一次性提交",
"两类都非空时,遗漏任一类的批次都不得提交",
"用户不需要点名 Agent",
"agent.delegate",
"readyDelegateReceipts",
@@ -16,6 +16,14 @@
---
## 2026-07-17 AI 游戏创作 V1.31 使用同一父 run 收束静态与隔离协作
- 背景:V1.30 已证明 Supervisor 能在无编排配方的真实终端任务中自主选择多个 static 专业 Agent,但尚未证明同一父 run 同时存在 static delivery/claim 与 isolated all-join 时,等待、唤醒、恢复和唯一 finalization 可以组合。两类协议分别通过不能替代组合证据。
- 决策:继续复用 `project-supervisor``--swarm-chat`、External Runner 和既有 durable 事实源,不新建第二套调度器或结果协议。用户任务只描述业务范围;仓库规则可声明验证要求和安全禁用边界,但不写 Agent 编排工具、调用顺序或 Runner 配方。Supervisor 在同一目标同时包含长期专业交付与临时隔离检查时,首个协作批次不得遗漏任一类。
- 完成边界:static delivery/claim 与 isolated group/result/join delivery 保持各自状态机,但全部绑定同一个 parent Agent/Session/runwaiting phase 只投影当前首个 blockerRunner 恢复和 finalization 必须在项目锁内重新枚举两类事实源。两类结果都已认领且其它 blocker 清零后,原 Supervisor run 才能写唯一用户 assistant。
- 验证:确定性基线统一运行 `project_supervisor_mixed_`,真实行为运行 `npm run agc:mixed-swarm-e2e -- --config-dir <AppData>`。失败尝试不得和后续轮次拼接;详细拓扑、一次性计数与当前 PASS 报告只维护在 Runtime V1.31 技术方案,不复制进长期共享决策。
- 关联文档:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md``docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md`
## 2026-07-17 AI 游戏创作 V1.30 使用自主 Supervisor 终端门禁和语义消息收敛
- 背景:V1.28 已证明预置双专业方向下的合同委派、repair、Runner 恢复和唯一回复,V1.29 已证明受控瞬态重试;但二者都没有证明 Supervisor 在用户不提供 Agent ID、数量、并行或 repair 配方时会自主编排,也没有把重复 `agent.message` 的持久幂等与后台 loop 有界收敛串成完整证据。
@@ -120,6 +120,17 @@ npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-autonomous-chat-rea
终局必须同时得到 `turn.report=settled`、新增 Supervisor assistant 恰好 1、专业 assistant 只在内部 Session、队列/确认/用户输入/reconciliation/sidecar 全 0,以及重复 action/delivery/message/receipt/Provider lifecycle 和正文/凭据/绝对路径泄漏全 0。`agent.message` 完整回归还要证明同语义消息只写一次、后续 no-op 不刷新进展、6 轮后保持未完成计划并诚实 `budget-exhausted`。隔离 AppData 必须位于正式 AppData 同级并自动清理;失败尝试与后续 PASS 不能拼接,`maxRetries=0` 下的真实外部 Provider 失败应单独保留为失败证据。
### AI 游戏创作静态与隔离混合 Swarm 复验
修改 static delivery/claim、isolated group/result/all-join、父 waiting phase、`agent.run_status` 混合认领、Supervisor 混合协作策略、Runner 恢复或 finalization blocker 后,先运行三条确定性回归,再运行独立真实终端 suite:
```bash
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml project_supervisor_mixed_ -- --nocapture --test-threads=1
npm run agc:mixed-swarm-e2e -- --config-dir <AppData>
```
业务任务只写正式交付、临时检查和验证等结果范围,不写 Agent ID、数量、并行方式、具体工具或 Runner 操作。真实 suite 必须以单个独立 run 证明两类 Provider 真重叠、两类 durable 记录绑定同一父 Session/run、认领 observation 早于唯一父 finalization、Runner 恢复身份稳定、isolated 实际零 mutation、唯一用户回复、零重复/残留/泄漏并完成 sentinel 清理;不能把 isolated 的 suite 零写入要求解释成生产权限层面的只读沙箱。命令未运行、退出非零或报告字段不完整时不得标记 PASS,也不得把失败轮和后续成功轮拼接。
### AI 游戏创作 Runtime V1.10 持久进程定向复验
V1.10 的 PTY 只通过四个 Runner-owned 工具开放;不要把 V1.2 `command.exec` 改成长驻入口。最小工具输入保持结构化:
@@ -1148,6 +1148,21 @@ V1.30 新增独立 `supervisor-swarm-autonomous-chat` 真实 Provider suite
V1.30 至此只证明自主 static 专业编排与真实终端聊天可组合;同一父 run 的 static delivery + isolated all-join 真实组合恢复,以及 Tauri/WebView 宿主级 Supervisor E2E 仍需各自独立门禁。
## V1.31 Project Supervisor 静态与隔离子 Agent 混合协作门禁
V1.31 新增独立 `supervisor-swarm-static-isolated-autonomous-chat` 真实 Provider suite,用于验证同一个 `project-supervisor` Session/run 可以自主同时使用 static `agent.delegate` 与 dynamic `agent.spawn_isolated(joinMode=all)`,并由同一个完成屏障、恢复链和 finalization journal 唯一收束。该 suite 复用 V1.28-V1.30 的 static delivery/claim/repair、isolated group/result/join delivery、External Runner、`--swarm-chat`、隔离 AppData 和零泄漏事实源,不新增调度器、对话入口、结果 sidecar 或第二种用户回复。
- 用户任务只明确业务范围包括仓库既有的正式交付、临时检查和实际验证,不得出现 Agent ID、数量、并行、static/isolated、delegate/spawn/join、repair 次数、run/action 身份或 Runner 操作。一次性仓库规则可声明既有验证要求和安全禁用边界,但不得指定 Agent 编排工具、调用顺序或 Runner 配方。Supervisor 系统策略要求提交首个协作批次前分别枚举长期专业交付与临时隔离检查;两类都非空时不得遗漏任一类。
- 首个形成协作的 native Provider 批次必须包含两个不同 static `agent.delegate` 与一个 `agent.spawn_isolated`spawn 请求固定 `joinMode=all`,三个 child 的 expectedArtifacts 指向三个既有证据文件,writeScopes 互不重叠。批次必须先停在 `waiting-confirmation / nextActionIndex=0`,唯一 `provider_action_batch.confirmation_required` 与唯一 approval 都绑定 spawn 和原批次,approval 必须早于三个 action 的任何真实副作用;随后每个 action 的 side effect、observed、receipt 和终态 observation 严格按 `actionIndex` 推进。两个 static child 的 Provider 区间必须真实重叠,且至少一个 static child 与一个 isolated child 的 Provider 区间也必须真实重叠,不能用 action 时间、同 Agent retry 或格式修复冒充并行。
- static 与 isolated 继续使用各自 durable 事实源。static 的 2 份初始 delivery 与 1 份 repair 分别由两个 Observed claim 认领 2/1 份 receiptisolated 形成 1 个 group、3 个唯一 instance/result、1 个 all-join delivery,并由同一父 run 的一个 `agent.run_status` action 认领。两类记录的 parent Agent/Session/run 必须一致;该 suite 要求 isolated child 的项目 mutation action 和实际文件修改均为 0,但这不是把生产 isolated 权限模型改成只读沙箱。
- completion blocker 在项目锁内先检查 plan/Goal,再按 `provider-action-batch -> process -> isolated join -> static receipts` fail closed,随后检查 response revision 和 verification。单一 waiting phase 只是当前首个 blocker 的 UI 投影,不是事实源;Runner 恢复和每次 finalization 都必须重新枚举两类 barrier。`project_supervisor_mixed_waiting_recovery_does_not_plan_until_all_join_ready``project_supervisor_mixed_waiting_recovery_does_not_plan_until_static_delivery_ready``project_supervisor_mixed_run_status_recovery_reuses_partial_isolated_claim_after_revision_drift` 三条确定性回归分别覆盖双向等待切换和同 action 部分认领恢复,不能代替真实 Provider suite。
- repair 待确认动作持久化后执行 pidfd Runner 强杀。强杀前后必须逐项比较 static delivery/claim、isolated group/instance/result/join delivery、父 task/context、pending action 和完整 Provider started identity setboot 必须变化,任何 child/action/receipt/join 不得重放。static claim 与 isolated join claim 的 observation 都必须早于父 finalization prepared,父计划、验证、确认、用户输入、process、两类 barrier 全部清零后,原 Supervisor run 才能写唯一 assistant 和 `turn.report=settled`
- 最终报告必须单独给出两类 Provider 重叠、group/instance/result/join/claim、两类 parent identity、跨恢复身份稳定、isolated 项目修改、重复 continuation/group/join/action/receipt、残留 sidecar 和公共泄漏计数。任何一项缺失、从不同尝试拼接、用户/仓库规则含编排配方、isolated 修改项目、未认领即 final 或额外用户回复都必须 FAIL;确定性回归或 V1.30 static PASS 不能替代该门禁。
2026-07-17 最终正式 `openai_chat / gpt-5.5` 独立轮 **PASS**。该轮形成 149 条 task、261 条 event、451 条 Agent DB 和 14 条会话消息;67 个 Provider request identity 全部唯一闭合为 `67 started / 67 terminal / 67 completed / 0 failed`,37/37 个成功工具计划与 24/24 个格式修复均为 `native_runtime_tools`wrapper/text fallback 为 0。首批 3 个 action 的 confirmation-required/approval 各 1 且时序有效,static-static 与 static-isolated Provider 区间均真实重叠;static 形成 2 份初始 delivery、1 份 repair 和 2 个 Observed claimisolated 形成 1 个 group、3 个 completed result、1 个 parent-wake claimed join,全部绑定同一父 Session/run。
Runner pidfd 强杀后的 boot、父 context、pending action、两类 durable identity 和完整 Provider identity set 均稳定恢复;isolated mutation action、isolated 文件修改、continuation、重复 delivery/group/instance/result/join/claim/message/action/receipt/Provider lifecycle、残留 sidecar和公共正文/凭据/绝对路径/报告泄漏均为 0。`turn.report=settled`,父计划 4/4 completed,正式 Supervisor assistant 恰好 1,内部专业 assistant 3、isolated assistant 3,最终 disposable 项目与隔离 AppData 均自动清理。此前不完整编排、child 合同不满足、外部 Provider 终态失败和调试验收器误判均各自作为独立失败轮停止,未与本轮 PASS 拼接。
## 验收命令
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml structured_plan_ -- --nocapture`
@@ -1157,6 +1172,8 @@ V1.30 至此只证明自主 static 专业编排与真实终端聊天可组合;
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml mcp_ -- --nocapture`
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_action_batch_ -- --nocapture`
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml parallel_read_batch_ -- --nocapture`
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml project_supervisor_mixed_ -- --nocapture --test-threads=1`
- `npm run agc:mixed-swarm-e2e -- --config-dir <AppData>`
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml swarm_cli::tests -- --nocapture`
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml typed_goal_pause_and_cancel_require_durable_intent_and_keep_exact_run -- --nocapture`
- `npm run ai-game-creator-shell:typecheck`
@@ -589,5 +589,6 @@ game-project/
- V1.28 已于 2026-07-17 完成正式 `openai_chat / gpt-5.5` `supervisor-swarm` PASS:同一 native 批次双专业委派、真实 Provider 重叠、2 份初始 delivery、1 次 targeted contract read、1 份唯一 repair、pidfd Runner 强杀/boot 恢复、同一父 Session/run、唯一 Supervisor assistant 和 3 条内部专业 assistant 全部成立。报告包含 46/46 闭合且 completed 的 Provider lifecycle,成功计划 24/24、格式修复 20/20 全为原生工具协议;重复、残留 sidecar、Provider payload、私有正文、API Key、项目/正式配置绝对路径、报告、secret 与 lure 泄漏均为 0。正式 AppData 零 CLI 调用且源 Runner endpoint 未变化;规范复验命令为 `npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite supervisor-swarm`
- 2026-07-17 追加 `supervisor-swarm-transient-retry` 受控故障门禁:一次性本地回环代理只让 `design-director` 首个请求在正文转发前断线,并暂停后继请求,直到验收器确认唯一 failed lifecycle、唯一 retry audit、新 `-transient-1` identity,以及 action/receipt/子委派/claim/assistant/pending/revision/upstream forwarding 全为 0。E2E 启动 CLI/Runner 时会把 loopback 合并进 `NO_PROXY / no_proxy`,避免继承的系统 HTTP 代理接触故障门禁请求中的凭据和正文。最终加强版正式 `gpt-5.5` 报告为 46/46 lifecycle 闭合、45 completed/1 failed/1 retry;代理观察到的 10 个目标 Agent 请求与该 Agent lifecycle 数量一致,放行后完整双 Agent、唯一 repair、Runner 强杀恢复、唯一 Supervisor assistant、零重复/残留/泄漏继续 PASS。隔离 AppData 创建在正式目录同级,source-dir guard 与 `sourceAppDataDirectoryUntouched` 证明正式 AppData 未被写入,源配置与 endpoint 身份保持只读,失败 partial report 保留已取得的 retry checkpoint,代理与隔离现场全部清理。该 suite 只证明显式重试和既有协作链可组合,不把预置双 Agent fixture 扩大解释为自主编排;无 Agent ID/并行/repair 配方的自主 suite、真实 `agc:chat`、static+isolated 组合和 Tauri 宿主 E2E 仍待单独验收。
- 2026-07-17 V1.30 `supervisor-swarm-autonomous-chat` 最终真实 PASS:唯一业务任务和仓库规则均不包含编排配方;Supervisor 在 1 个 native 批次自主选择两个不同专业 Agent,真实 Provider 重叠后形成 2 个初始 delivery,并基于 acceptance criteria 自主创建 1 个继承原合同的 repair。最终报告包含 110 条 task、197 条 event、330 条 Agent DB、9 条会话消息和 `51 started / 51 terminal / 51 completed / 0 failed` Provider lifecycle28/28 成功计划与 19/19 格式修复均为原生工具协议,父计划 4/4 completedRunner pidfd 强杀恢复后身份稳定,`turn.report` settled、正式 assistant 1、内部专业 assistant 3,重复、sidecar、正文、密钥、诱饵、项目/配置路径和报告泄漏均为 0。两次较早的独立尝试在 `maxRetries=0` 下各遇到 1 次外部 Provider 终态失败并中止,未与最终 PASS 拼接。
- 2026-07-17 Runtime V1.31 的同父 run 混合协作门禁已完成独立真实 PASS;详细业务任务边界、首批 confirmation gate、static/isolated durable 合同、三条确定性回归、真实报告数字和失败轮隔离记录统一以同一 Runtime 文档的“V1.31 Project Supervisor 静态与隔离子 Agent 混合协作门禁”为事实源。App 侧复验入口为 `npm run agc:mixed-swarm-e2e -- --config-dir <AppData>`,不在实施计划重复维护一次性拓扑和计数。
- `agent.message` 使用来源 Agent/run、目标 Agent/Session 和清洗后正文 SHA-256 形成稳定语义身份。同一语义消息只允许写 1 条目标 tool conversation、1 条 `conversation.message` 和 1 条 `agent.runtime.agent.message`;后续 Runtime action 仍完整落账,但返回 `messageAppended=false` 且不算新的 loop 进展。专业 Agent 不得用重复消息替代最终回执;持续重复时最多经过当前 6 轮停滞窗口即以 `loop-budget-exhausted` 失败,保留 `in_progress` 计划且不写 completed。完整后台回归同时断言 6 个 actionId、同一 action fingerprint、6 组 action/observation/receipt、消息持久化唯一、receipt 零正文、第 7 次 Provider 请求为 0。
- 开发模式可通过本地项目文件面板执行 `file.list/read/write/delete`,普通用户界面不暴露文件面板。
+1
View File
@@ -143,6 +143,7 @@
"ai-game-creator-shell:agent-task": "npm --prefix apps/ai-game-creator-shell run agent-task --",
"agc:chat": "npm --prefix apps/ai-game-creator-shell run chat --",
"agc:swarm": "npm --prefix apps/ai-game-creator-shell run swarm --",
"agc:mixed-swarm-e2e": "npm --prefix apps/ai-game-creator-shell run agent-runtime:mixed-swarm-real-e2e --",
"ai-game-creator-shell:agent-run": "npm --prefix apps/ai-game-creator-shell run agent-run --",
"ai-game-creator-shell:agent-run:smoke": "npm --prefix apps/ai-game-creator-shell run agent-run:smoke",
"ai-game-creator-shell:agent-runtime:real-e2e": "npm --prefix apps/ai-game-creator-shell run agent-runtime:real-e2e --",