合并AI游戏创作智能体与通用Runtime基座
Project CI / Frontend tests (push) Failing after 27s
Project CI / Repository checks (push) Successful in 3m20s
Project CI / Backend tests (push) Successful in 3m52s
Project CI / Native shell tests (push) Successful in 13m19s

合并 codex/ai-game-creator-app 的独立客户端、多智能体 Runtime、Runner 与可扩展 LLM Provider 能力
保留 master 最新画布、钱包、后端和原生壳约束并完成四处语义化冲突合并
补齐根 Vitest 对独立 Tauri guest 模块的隔离测试别名并保持 HostBridge 依赖边界
统一正式工作台与 game-chat 的安全本地预览组件及 native-shell 静态门禁
修复合并态 Rust 格式、前端 lint 与共享文档验证口径
This commit is contained in:
AIGameCreator App
2026-07-30 18:01:19 +08:00
484 changed files with 383375 additions and 1517 deletions
+1
View File
@@ -9,6 +9,7 @@
3. [server-rs 与 SpacetimeDB 数据契约](./【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md)
4. [平台入口与玩法链路](./【玩法创作】平台入口与玩法链路-2026-05-15.md)
5. [本地开发验证与生产运维](./【开发运维】本地开发验证与生产运维-2026-05-15.md)
6. [AI 游戏创作项目开发工作台 PRD](./prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md)
团队长期约定、决策、流程和排障摘要统一从 [项目记忆入口](./project-memory/README.md) 读取。代码、当前融合文档与项目记忆冲突时,以代码和最新融合文档为准。
@@ -0,0 +1,304 @@
# AI 游戏创作项目开发工作台 PRD
更新时间:`2026-07-20`
## 1. 产品定位
项目开发工作台是 AI 游戏创作独立客户端中承接“做游戏”后的唯一项目级工作区,不是单独的新页面,也不新建第二套项目、资产、Agent 或预览系统。
工作台固定由四个区域组成:
1. 左侧平台导航。
2. 中央主视窗。
3. 右侧 Project Supervisor 对话与确认区。
4. 底部专业 Agent 状态栏。
中央主视窗在“资源管理”和“运行测试”之间切换。正式预览始终在客户端当前窗口内展开,只允许载入当前项目启动的 `127.0.0.1:<port>` 本地 HTTP 预览,不调用系统外部浏览器。
## 2. 创作工具平台接入声明
- 工作台模式:对话式 Project Supervisor 项目工作台,属于 Agent 原生创作例外。
- 例外原因:该工作台负责跨策划、美术、程序、数值、音频和发布专业组的持续协作,结构化表单不能覆盖多轮项目开发与确认恢复。
- 复用边界:图片、音频、上传、素材库、画板和外部生成继续复用现有平台能力,不在工作台内新建平行资产系统。
- 创作链路:做游戏入口 -> 本地项目工作台 -> 资源/运行迭代 -> 导出或后续发布链路。
- 业务真相:项目 manifest、Agent Runtime、持久对话、本地预览状态和后端计费投影;前端只保存短生命周期展示态。
- 当前切片不新增玩法 `playId`、公开作品 read model、发布路由或 SpacetimeDB schema。
## 3. 已确认产品决策
### 3.1 预览与窗口
- 游戏预览直接在当前客户端窗口内展开。
- 客户端仅交付横屏,默认与最小窗口均为 `1280×800`
- 右侧 Supervisor 和底部 Agent 状态栏常驻;窗口不得缩小到破坏该结构。
- 浏览器窄屏样式只作为开发兼容,不属于本版本产品合同。
### 3.2 版本与资源替换
- 可运行版本不可变。
- 替换版本引用资源时创建下一迭代版本,不原地修改既有版本。
- 新版本必须记录 `parentVersionId`、替换前后资源身份和创建原因。
- 当前运行中的版本不消费尚未生成的新版本变更。
### 3.3 资源布局
- “按依赖”和“按类型”分别保存画布位置。
- 切换布局模式后恢复该模式最后一次用户手动拖动结果。
- 新资源首次进入某个布局时才执行默认不重叠排版;已有坐标不得被自动排序覆盖。
- 依赖布局使用资源生成/引用关系;类型布局按资源大类、子类型、尺寸规格排序。
- 不同资源分区不可互相拖入。
### 3.4 数值微调
- 数值修改立即写入当前项目的编辑态配置。
- 当前已拉起的体验预览和测试切片不热更新;必须重新拉起后才能消费新值。
- 自然语言新增数值项只能映射到预定义参数注册表,不允许生成或修改代码。
### 3.5 专业 Agent
现有六个专业组为:
| group | 普通用户名称 | 当前职责 |
| --- | --- | --- |
| `design` | 策划组 | 玩法规格、界面原型、规则与验收口径 |
| `art` | 美术组 | 角色、场景、UI、动画和美术素材 |
| `code` | 程序组 | 可运行原型、模块实现和工程验证 |
| `balance` | 数值组 | 速度、生命、得分和难度参数 |
| `audio` | 音频组 | 背景音乐、音效和音频资源 |
| `publishing` | 发布组 | 质量评审、试玩、打包和发布准备 |
- 底栏默认突出策划、美术、程序三组。
- 允许在同一底栏展开数值、音频、发布组,不删除既有专业组。
- 状态、当前任务和完成进度来自真实 manifest/Runtime。
- 泥点消耗必须来自后端计费归因投影;无数据时显示“未统计”,不得用前端估算。
### 3.6 审批与扩展能力
- 默认档位为严格审批。
- P0 只有严格审批是有效运行合同。
- 高风险审批依赖未确定的 Rank 算法,作为低优先级待解决事项。
- 无需审批只有在 Runtime、计费、副作用、sandbox 和 reconciliation 均支持对应策略后才能开放。
- 未开放选项使用“视觉不可用但可点击说明原因”,不使用无法触发说明的原生 `disabled`
- 普通用户暂不开放 Agent.md 编辑和自定义 Skill 安装;后续必须先定义来源审核、版本、权限、沙箱和回滚合同。
## 4. 工作台状态机
### 4.1 主视窗
```text
resources
-> run(存在 runnableVersion 且 loopback preview 可启动)
run.playing
-> run.paused(用户暂停或切片结束)
-> resources(先暂停当前预览表现,再切换视图)
run.paused
-> run.playing(继续当前切片)
-> run.relaunching(数值或版本编辑态发生变化)
-> resources
```
运行入口不可用时仍允许点击,显示“当前无可运行版本”,但不切换状态。
### 4.2 测试切片
```text
idle -> starting -> playing -> paused -> completed
| |
+-> failed +-> playing
completed -> starting(nextSlice)
```
- 单个切片完成后自动进入 `paused`
- 上一项/下一项会停止当前切片并启动目标切片。
- 数值编辑态变化后,当前切片标记 `stale`;重新拉起前不消费新值。
### 4.3 资源聚焦
```text
idle -> focused(document|art|audio|version) -> idle
```
- 文档:在中央画布展开并独立滚动。
- 美术/音频:进入对应媒体聚焦状态,工具能力复用现有编辑器。
- 版本:高亮版本引用资源;替换动作只创建下一迭代版本。
### 4.4 历史成果与当前状态
- “当前工作状态”只展示当前 Supervisor run 下的专业 Runtime。
- “项目已有成果”按项目持久保存,不随 Supervisor run 切换而清空。
- Agent 文本成果只认可带合法 `agent-finalization-<32 lower hex>` messageId 的 assistant 消息。
- 新 run 失败、待确认或未完成时继续展示最近一次成功成果;新的成功 finalization 才替换同 Agent 的旧成果。
- 文本回执不得冒充图片、音频、项目文件或 manifest asset。
## 5. 数据合同
以下合同先冻结字段语义;P0 只实现标注为 P0 的部分。
### 5.1 工作台视图状态(P0)
```ts
type ProjectWorkbenchViewState = {
schemaVersion: 'game-creator-workbench-view.v1';
projectId: string;
mode: 'resources' | 'run';
approvalMode: 'strict' | 'risk' | 'none';
expandedAgentGroups: Array<'balance' | 'audio' | 'publishing'>;
};
```
P0 中 `approvalMode` 只能有效写入 `strict`;其它值只能作为不可用选项展示。
### 5.2 资源画布布局(P1
```ts
type ProjectResourceCanvasLayout = {
schemaVersion: 'game-creator-resource-layout.v1';
projectId: string;
mode: 'dependency' | 'type';
revision: number;
positions: Array<{
resourceId: string;
section: 'document' | 'version' | 'art' | 'audio';
x: number;
y: number;
manuallyPlaced: boolean;
}>;
updatedAt: number;
};
```
两个 mode 是两份独立坐标集合;服务端或本地项目持久层以 `projectId + mode` 做 CAS 更新。
### 5.3 资源类型与替换兼容性(P1)
```ts
type ProjectResourceDescriptor = {
resourceId: string;
category: 'document' | 'version' | 'art' | 'audio';
subtype: string;
width?: number;
height?: number;
durationMs?: number;
format: string;
};
type ProjectVersionResourceReplacement = {
sourceVersionId: string;
sourceResourceId: string;
replacementResourceId: string;
compatibility: {
categoryEqual: boolean;
subtypeEqual: boolean;
sizeSpecEqual: boolean;
};
};
```
三项兼容性必须同时为 true 才能创建下一版本。
### 5.4 游戏迭代版本(P1
```ts
type GameIterationVersion = {
versionId: string;
parentVersionId: string | null;
projectRevision: number;
resourceBindings: Array<{ slotId: string; resourceId: string }>;
parameterSnapshotId: string;
createdReason: 'initial' | 'resource-replacement' | 'agent-revision';
createdAt: number;
};
```
版本写入后不可修改。
### 5.5 测试切片与数值参数(P2)
```ts
type GameTestSlice = {
sliceId: string;
versionId: string;
title: string;
order: number;
startCondition: string;
endCondition: string;
status: 'idle' | 'starting' | 'playing' | 'paused' | 'completed' | 'failed';
};
type GameTunableParameterDefinition = {
parameterId: string;
label: string;
valueType: 'integer' | 'number' | 'boolean' | 'enum';
min?: number;
max?: number;
step?: number;
enumValues?: string[];
writePath: string;
codeMutationAllowed: false;
};
```
参数写入立即增加编辑态 revision;当前 preview/slice 保持旧 revision,并显示“需要重新拉起”。
### 5.6 Agent 泥点归因(P2
```ts
type ProjectAgentMudPointAttribution = {
projectId: string;
agentGroup: 'design' | 'art' | 'code' | 'balance' | 'audio' | 'publishing';
chargedMudPoints: number;
refundedMudPoints: number;
netMudPoints: number;
asOf: number;
};
```
该投影只能由后端账本聚合产生。
## 6. 分阶段范围
### P0:当前实施切片
- 复用现有四区工作台壳。
- 资源/运行切换与客户端内 loopback 预览。
- 只读资源画布、文档展开、美术/音频聚焦入口。
- Supervisor 正式会话、上传、Runtime 确认与安全错误。
- 当前 run 专业状态与项目历史成果分离。
- 默认三专业组,并可展开另外三组。
- 严格审批有效;风险/无需审批可点击查看未开放原因。
- 橙色低保真视觉与 `1280×800` 横屏边界。
### P1
- 依赖/类型两套坐标持久化。
- 资源关系线与首次自动布局。
- 版本资源高亮、兼容性判断和不可变下一迭代版本。
- 美术/音频编辑状态接线。
### P2
- 测试切片正式协议与恢复。
- 参数注册表、立即写编辑态和预览重新拉起。
- 泥点归因 read model。
- Agent.md/Skill 安全合同。
- 高风险审批 Rank 与无需审批运行合同。
## 7. P0 验收
1. `1280×800` 下页面无横向或纵向溢出,输入框与 Agent Dock 始终可见。
2. 运行入口不可用时点击给出原因;可用时只在客户端内打开 loopback 预览。
3. 当前 Supervisor run 变化后,旧成功 Agent 文本成果仍可查看;普通失败 assistant 不进入资源区。
4. 底栏默认显示策划、美术、程序,可展开数值、音频、发布;状态与任务来自真实 Runtime/manifest。
5. 风险审批和无需审批不能改变运行策略,点击后明确提示尚未开放;严格审批继续使用现有 Runtime 门禁。
6. 不显示伪造泥点、伪造资源完成度、伪造图片或外部浏览器成功提示。
## 8. 非目标
- 本切片不实现 P1/P2 持久合同。
- 不修改 SpacetimeDB schema。
- 不开放普通用户 Agent.md/Skill。
- 不自动确认 Agent 动作,不自动触发可能扣费的生成。
- 不把当前项目工作台推广为其它玩法的默认创作模式。
@@ -0,0 +1,48 @@
# Agent Swarm 纯聊天验证入口计划
更新时间:`2026-07-14`
## 目标
提供一版不依赖正常客户端 GUI 的终端聊天入口,让开发者选择一个父 Agent,通过真实 Agent Runtime 验证静态委派、动态隔离子 Agent、并行执行、确认动作、回执汇总和多轮持久化。
## 范围
- 新增 `--swarm-chat [--init] <本地项目绝对路径> [parentAgentId]`,省略时默认进入 `project-supervisor`
- 新增总控短命令 `npm run agc:chat -- --config-dir <项目外 AppData 绝对路径> [--init] <project>`;保留 `agc:swarm` 显式父 Agent 调试入口。
- 普通输入进入父 Agent background Runtime;不使用一次性 `--agent-chat`
- 复用 External Runner、active Session、现有 conversation、Agent 私有记忆、项目黑板、`agent.delegate``agent.spawn_isolated`、terminal receipt 和 all-join。
- 展示全部 Agent 的状态、事件、父子身份和委派关系,并支持在终端批准或拒绝待确认动作。
- 提供 `/help``/agents``/status``/history``/quit`
## 非目标
- 不新增 Tauri 窗口、浏览器页面或本地 HTTP / SSE bridge。
- 不新增 Provider 调用路径、Agent 数据库或 conversation 格式。
- 不伪造 token streaming;首版展示 Runtime 状态 / 事件流和最终回复。
- 不在终端退出时取消 Runner、run 或 Runner-owned process session。
## 实现步骤
1. 扩展 CLI command、参数解析和项目外 `--config-dir` 门禁。
2. 新增独立终端 REPL 模块,复用项目初始化、Runtime resume、任务投递和 conversation 读取。
3. 轮询全 Agent Runtime,按身份去重输出状态和事件;待确认时走现有 confirm / reject。
4. 用“全 Runtime 非活跃 + 全队列为空 + 稳定观察窗口”判断一轮收束,再读取父 Agent 当前 Session 的新增 assistant 消息。
5. 增加 npm 短命令、确定性测试、真实启动 smoke 和文档同步。
## 验收清单
- CLI parse、绝对路径、项目初始化、`--config-dir`、空输入、EOF 和 slash command。
- 同一父 Agent 连续两轮使用同一 Session,退出重进后历史可见。
- 两个静态 Agent 并行委派,多个动态 child 并行并形成唯一 all-join。
- approve / reject 均能在终端完成,拒绝后父 Agent 能继续修正计划。
- 父 Agent 暂时 idle、child 仍运行或 receipt 尚未认领时不提前结束。
- Runner 或终端重启后恢复同一 run / session,不重放副作用。
- 真实 Provider transcript 与 task / event / Agent DB / receipt / conversation 一致,最终父回复唯一且无密钥泄漏。
## 当前进度
- 已完成终端入口、短命令、Runtime 状态 / 事件输出、approve / reject、active Session 历史、same-run steer、活跃 `/quit`、启动 / 收束恢复扫描和 Runner 失联阻断。
- 已用真实 `gpt-5.5` 观察到两个静态 Agent 并行、两条 child result、receipt 排队与重启恢复;终端确认、拒绝和活跃退出均生效。同一父 Session 连续 4 轮固定回复及 8 条消息历史恢复通过,最终双安静窗口收束返回 `FOURTH_OK`
- 未通过父 Agent 最终汇总:全量 `agent.run_status` 输出截断导致第一轮预算耗尽;第二轮 receipt continuation 未恢复原始只读目标并请求文件写入,已拒绝。
- 待办:修复定向状态查询或 receipt continuation 目标恢复,复验唯一最终父回复;再补动态 isolated child 并行、唯一 all-join 和 Runner 强杀恢复。
File diff suppressed because one or more lines are too long
@@ -45,12 +45,236 @@ hermes
npm install
```
仓库当前不使用 npm workspaces,根目录 `npm install` 是统一安装入口。子包新增运行时依赖时,必须同步写入根 `package.json` 和根 `package-lock.json`;不能只修改子包 `package.json`
完整联调开发环境:
```bash
npm run dev
```
AI 游戏创作独立客户端常用短命令:
```bash
npm run agc
```
开发侧需要无 UI 验收某个单 Agent 的完整 Runtime 时使用:
```bash
npm run ai-game-creator-shell:agent-task -- --config-dir /absolute/app-data --init /absolute/project code-prototype "修复失败测试并完成验证"
```
省略 `--init` 时项目必须已经由客户端初始化。所有 Runtime 写命令都必须显式传入项目外 `--config-dir` 并投递给独立 Runner`--runner-status` 和 Agent 状态查询只读取已有配置与 endpoint,不得创建 AppData、修改权限或为了查询启动 Runner。遇到权限确认会返回非零并保留待确认动作,继续操作应回到开发窗口,不能用 CLI 静默绕过。
### 通用 Agent Runtime 内核抽取复验
修改 `server-rs/crates/agent-runtime-core`、AGC capability registry、Agent catalog、Run Profile 或 Completion Policy 后,先运行纯内核与适配器定向门禁:
```bash
npm run agent-runtime-core:check
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml interaction_ -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml native_runtime_capability_registry_is_the_bidirectional_catalog -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml game_creator_runtime_ -- --nocapture --test-threads=1
```
修改 Provider 中立契约、注册表、`platform-llm` adapter 或 AGC interaction Provider 路由时,追加:
```bash
cargo test --manifest-path server-rs/crates/agent-runtime-core/Cargo.toml --test provider_registry
cargo test --manifest-path server-rs/Cargo.toml -p platform-llm
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml agent::interaction::tests:: -- --nocapture
cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --tests
```
验收必须同时证明同 protocol 多实例可并存、能力不匹配时 adapter 零调用、三种现役 protocol 仍复用原 HTTP/SSE/parser,以及 AGC stream/non-stream/fallback 均经 registry。Provider Key、base URL、HTTP client 和 raw-log 目录必须保留在 `LlmClient/LlmConfig` 实例,不得下沉 core descriptor/error 或进程全局状态。
修改通用 run 状态机、Store/ToolHost、Agent lane、action 恢复或 delegation/join 时,追加执行内核 conformance 和 AGC 恢复优先级回归:
```bash
cargo test --manifest-path server-rs/crates/agent-runtime-core/Cargo.toml --test runtime_execution_conformance
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml background_agent_runtime_legacy_waiting_task_blocks_pending_recovery -- --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml background_agent_runtime_recovers_stale_running_before_pending_task -- --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml background_agent_runtime_recovers_pending_task_after_cancelled_canonical_run -- --test-threads=1
```
action conformance 必须在 ToolHost 调用前看到 durable `executing`,并在 observation commit 失败后用全新 engine 重载快照;只在同一进程里重试不能作为 crash recovery 证据。all-join 结果顺序按 child 注册顺序,不按完成先后。
内核必须保持纯 Rust,只允许 `serde / serde_json` 和标准库依赖;用 `cargo tree --manifest-path server-rs/crates/agent-runtime-core/Cargo.toml --depth 1` 核对不得出现 Tauri、`platform-llm`、MCP、HTTP、图片、浏览器、SpacetimeDB 或游戏领域 crate。AGC 的 function name、schema、Agent id、profile、权限和持久协议必须保持兼容;新增内建 capability 只能经统一 registry 建立双向唯一 binding,不能重新增加平行字符串清单。独立 core 测试会生成 crate 内 `Cargo.lock/target` 时,开发者只保留源码和 manifest,交付前清理生成物;正式 AGC lock 仍需提交 path dependency 变更。
### AI 游戏创作 Runtime V1.2 定向复验
`command.exec` 动作必须保留固定程序和逐项 argv,不得把参数拼成 shell 字符串。例如,定向执行当前仓库的受控命令测试时,action 形状为:
```json
{
"program": "cargo",
"args": ["test", "project_command_"],
"cwd": "apps/ai-game-creator-shell/src-tauri",
"timeoutSeconds": 120
}
```
该 action 仍需开发窗口精确确认;不能用 CLI 或项目策略把 `command.exec` 默认改为 `auto`。实现或调整 Runtime V1.2 后,从仓库根目录优先运行以下定向命令:
只有 `cargo check/test/clippy/fmt/build``npm test`、规范命名的 npm 验证脚本和精确 `node --test` 可以形成验证凭证;`git``rg``cargo metadata` 与普通 `npm run` 即使成功也只是诊断结果,最后仍需执行验证型命令。
```bash
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml project_command_
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml config_file_overrides_defaults_without_env
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml llm_reasoning_effort_supports_provider_default_and_explicit_levels
npm run test -- packages/shared/src/contracts/gameCreationApp.test.ts
npm run ai-game-creator-shell:typecheck
```
第一条覆盖固定程序 / argv 拒绝规则、输出清洗、超时和源码改写检测;第二条覆盖全局 / per-Agent 配置继承,第三条覆盖 `default / low / medium / high` 到 Provider 请求的映射;后两条覆盖共享 `confirm` 契约、配置结构和发布默认 `high`。模块级定向验证通过后,再按改动范围运行 `npm run ai-game-creator-shell:check``npm run check:encoding``git diff --check`
### AI 游戏创作 Swarm 显式重试真实复验
正常 `supervisor-swarm` 全部 completed 不能替代真实 retry 证据。修改 Runtime 显式重试、Provider lifecycle、隔离 AppData 或 Swarm 验收器后,先跑代理夹具和静态门禁,再运行独立真实 suite:
```bash
npm run test -- apps/ai-game-creator-shell/tests/llmTransientFaultProxy.test.ts
npm run ai-game-creator-shell:typecheck
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_retry_ -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_transient_retry_ -- --nocapture --test-threads=1
npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-transient-retry-real-e2e -- --config-dir <AppData>
```
V1.39 真实门禁把一次故障注入到 Project Supervisor 的首次 tool-plan,使退避期强杀发生在子 Agent Provider 请求产生之前;恢复后仍须在同一父 Session/run 完成双专业 Agent 真重叠与唯一 repair。suite 使用 `30s` 退避,必须先观察 sidecar 已落盘且 task/state 均为 `running / waiting-for-provider-retry`,再强杀 Runner;新 boot 接管后 sidecar identity、字节、attempt、slot 与 `retryAt` 不变,重启后和到期前代理请求数都只能为 1。代理的 metadata-only 请求日志只允许保存序号与毫秒时间,第二个请求的 `acceptedAtMs` 必须不早于 `retryAtMs`,且不得包含 URL、method、headers 或正文。forwarding gate 放行前 action、receipt、子委派、claim、assistant、pending、project revision 与 upstream forwarding 全为 0;受控 request identity 必须恰好包含 1 个 failed lifecycle、1 条 retry audit 和 1 个 `-transient-1` 后继 identity。其它真实瞬态失败按 incidental failure/retry 分开计数,每条仍须通过既有 lifecycle、retry audit、唯一后继和终局门禁且两类计数相等;不能把它们混入受控注入链,也不能跳过唯一 Supervisor assistant 和零重复/残留/泄漏要求。首批双专业 Agent 使用正式 collaboration policy 固定为同批两个指定 static delegate,不能只靠提示碰运气;该 suite 已在 Provider 退避边界完成唯一一次 Runner 强杀,后续 repair 只验证持久 pending/确认链,不重复制造第二个 kill 边界。
V1.40 final-reply 持久恢复先运行确定性门禁:
```bash
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_retry_waiting_final_reply_restart_commits_once -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_retry_waiting_final_reply_compaction_resumes_without_new_tool_plan -- --nocapture --test-threads=1
```
第一条测试必须停在 final-reply retry sidecar 已提交而 task/state 尚未投影的窗口,恢复扫描补齐 waiting 后在到期前保持零请求;第二条必须让 final-reply 前置自动压缩先失败并进入 `requestKind=final-reply-context-compaction` 等待态,到期后恢复同一压缩请求,再继续原 final-reply。两条链路都不得重新调用 tool-plan;失败和恢复请求只比较 HTTP body 字节、SHA-256 和长度,测试失败不得打印正文。真实 Provider 验收必须另起独立 suite,在 Supervisor 已认领全部专业回执、repair 和宿主验证后注入 final-reply 故障并于退避期强杀 Runner;该 suite 尚未 PASS 前,不能复用 V1.39 首次 tool-plan 的真实证据。Provider 成功返回到 finalization journal `prepared` 之间的崩溃窗口仍须独立补齐和验收,当前门禁不能据此宣称 Provider 调用 exactly-once。
### AI 游戏创作 Runtime V1.41 成功交接与回复流恢复复验
修改 Provider 成功响应、持久重试、finalization、response stream 或 Runner idle 判定后,至少运行:
```bash
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_handoff_ -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml response_stream_ -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml durable_provider_handoff_prevents_shutdown_even_when_corrupt -- --nocapture --test-threads=1
```
复验和排障按 durable ownership 的顺序取证:
1. 先按 handoff 中保存的真实 `providerRequestId / requestSlot / attempt` 核对 Provider lifecycle。成功响应必须先原子写入 handoff 并回读完全一致,再为同一真实 requestId 补 `completed`;恢复不得生成替代 requestId。
2. 在 handoff 已提交、lifecycle 仍只有 `started` 的 checkpoint 停止执行,关闭 mock Provider 后再恢复。final-reply 必须零网络回放并只产生唯一 assistant/completed/committed stream;前置压缩只允许在回放压缩结果后发出后续必要的 final-reply,不能重复 tool-plan 或 compaction。
3. 同一 run 同时存在 handoff 与 retry 时,完全匹配才允许回放并清理 retryidentity、attempt 或 slot 冲突必须零网络进入 `needs-reconciliation`,保留两份 sidecar 和真实 requestId 证据,不要为了让 Runner 退出而手工择一删除。
4. finalization 已到 `runtime-completed` 后,故意删除 stream、保留 `streaming` 半句、注入 committed 写失败、在 committed 后 journal 清理前停止,并在期间推进全局 project revision。恢复必须始终使用 journal 固定的 run/request slot/steer cursor/response revision 与正文重建或幂等提交,写入后回读成功才可删除 journal。
5. 固定身份或正文冲突、stream 写入或回读失败时,断言 journal 保留且恢复扫描继续处理同一 finalizationRunner 对 primary、`.previous` 或损坏 handoff 都应保持 busy`runner.shutdown_if_idle` 不得返回 idle。终局再核对 retry/handoff/finalization sidecar 全部为零,并扫描公共 task/event/Agent DB/CLI,确保没有响应正文、thinking、凭据、Provider URL 或绝对路径。
V1.41 只覆盖无 tool call 的 `context-compaction / final-reply-context-compaction / final-reply`。Runner 在 Provider 成功后、handoff 原子提交并回读前被硬杀时,仍只能把未闭合 `started` 视为结果未知并失败关闭;该窗口不是 exactly-once。`tool-plan` 及其 function arguments 不进入 handoff,真实外部 Provider 的 final-reply 退避期 Runner 强杀仍需独立 E2E,不能用上述确定性测试或 V1.39 PASS 代替。
### AI 游戏创作 Runtime V1.42 Supervisor final-reply 强杀真实复验
V1.42 不改变生产 Runtime 协议,只补一次性 fault proxy selector 和独立真实 suite。先完成确定性门禁,再显式传入发布 AppData 的绝对路径运行长链路:
```bash
npm run test -- apps/ai-game-creator-shell/tests/llmTransientFaultProxy.test.ts
node apps/ai-game-creator-shell/scripts/agent-runtime-real-e2e.mjs --self-test
npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-final-reply-transient-retry-real-e2e -- --config-dir <发布AppData绝对路径>
```
1. proxy selector 只允许读取冻结的 `sequence / acceptedAtMs`,不得接触 URL、header、body 或 Key。harness 从持久层识别同一父 Session/run 的唯一 base final-reply,先核对 `2` 初始加 `1` repair delivery 均已 claim、两次 observed claim 完整覆盖 `3` receipts 且 assistant 为 `0`selector 再在 proxy reset/forward 该请求前,以可信宿主 Node 在 disposable project cwd 同步运行固定的 `node verify-e2e.mjs`。仅 `real-e2e-command=passed` marker 成功且无失败 marker 才允许注入;失败、超时或 marker 无效时不注入,stdout/stderr 不得写入 state、checkpoint、report 或公共日志。父 run 的 `project.verify` audit/receipt/observation 计数仅用于诊断,不是注入门禁。
2. base final-reply failed lifecycle、retry audit、sidecar 和 task/Runtime `running / waiting-for-provider-retry` 全部成立后,才在 `30s` backoff 内用 pidfd `SIGKILL` 强杀 suite 自有 Runner。新 boot 必须保持 Session/run/request fingerprint/attempt/next slot/sidecar 字节/retryAt;重启后和到期前零新请求,到期后只允许唯一 `-transient-1`,并证明 `acceptedAtMs >= retryAtMs`
3. forwarding gate 放行前再次比较 delivery/claim/receipt、assistant、pending、project revision、可信宿主 marker 结果和父 tool-plan 数;后者在恢复前后必须相等,父 `project.verify` 仍只保留诊断计数。终局要求唯一成功 parent final-reply、唯一 Supervisor assistant、唯一 committed response streamretry/handoff/finalization artifacts、重复和公共正文/Key/绝对路径泄漏均为 `0`
4. task/Runtime 到达终态后仍要显式等待 pending、retry、handoff、finalization、confirmation sidecar 全部清零,并设置 `10s` 硬超时。终态采样与 durable 清理之间允许存在短窗口,但超时仍有残留必须判该轮 **FAIL**,不得复用后续轮次的清理结果。
5. 并行 Agent 执行 `file.write / file.patch / file.delete` 时统一走 Runtime 短等待项目写锁。锁竞争失败只返回脱敏错误,尤其不得让 `file.write` observation 携带绝对锁路径后再进入 pending 持久化;定向 Rust 回归至少覆盖短等待写锁和 `file.write` 错误脱敏两条边界。
`supervisor-swarm-transient-retry` 继续只复验首次 tool-plan,不能替代新 suite。确定性门禁已完成 fault proxy `14/14`、E2E self-test **PASS**、前端 `308/308`,以及 shell typecheck、`platform-llm 41/41``platform-agent 17/17``shared-contracts 7/7`。真实外部 Provider suite 共执行六轮,前五轮均为 **FAIL** 且不得拼接:第一、二轮沿用既有失败记录;第三轮因终态后过早观察到 `1` 个 finalization journal 失败;第四轮因 quality-review 普通 tool-plan 连续 transport/connectivity 失败并耗尽重试、未进入目标故障而失败;第五轮因并行 `file.write` 与项目写锁竞争,绝对锁路径进入失败 observation 后触发 pending 持久化拒绝和 `needs-reconciliation` 而失败。完成终态 sidecar 等待和写锁/脱敏修正后,第六轮在同一轮内完整 **PASS**
第六轮使用 `gpt-5.5 / openai_chat`,形成 `2` 条初始加 `1` 条 repair delivery 和 `3` 条专业 Agent assistant,精确命中 Project Supervisor base final-reply,可信宿主 verify marker 门禁通过;受控 Provider `failed=1 / retry=1`、incidental `failure=0 / retry=0``30s` backoffpidfd `claim=2 / signal=2`Runner `resumed=true / identityStable=true`。父 tool-plan 在故障前后均为 `13`parent final-reply 与最终 assistant 唯一,response stream `sequence=2 / committed`pending、retry、handoff、finalization、confirmation sidecar、全部重复计数及 API Key、私有正文、项目路径、正式配置路径和公共报告泄漏扫描命中均为 `0`。V1.41 handoff 落盘前 unknown-result 边界和 tool-plan handoff 未覆盖状态保持不变。
suite 只能读正式 AppData,在其同级目录写入 sentinel 管理的 `0600` 私有副本和 overlay;启动 CLI/Runner 时须把 loopback 合并进大小写两套 no-proxy 环境,防止系统 HTTP 代理绕过本地故障门禁;source-dir guard 必须证明本 suite 前缀未进入源目录,源配置和 endpoint 身份保持不变,报告不得保存 Provider URL、headers、正文、凭据或绝对配置路径。sidecar 先于 task/state 投影是合法提交窗口,验收器应等待完整等待态后再强杀;若后续协作或终局失败,partial report 仍应保留已取得的 retry checkpoint,但失败轮不得与后续成功轮拼接。
### AI 游戏创作自主 Swarm 终端复验
日常人工验收优先使用短入口,不再手工拼 AppData、临时项目和预览命令:
```bash
npm run agc:test
npm run agc:test:chat
```
`agc:test` 委托确定性 lane-defense E2E,使用本地 loopback Provider 完成 Runtime、项目写入和真实浏览器 `37/37` 门禁,不消耗外部 Provider。`agc:test:chat` 按当前平台自动查找发布客户端 AppData 中的 `game-creator.config.json`,把主配置和可选 local overlay 私有复制到 sentinel 管理的单次隔离 AppData,绝不复制正式 `agent-runner.endpoint.json`、Runner lock、备份或其它文件;随后创建一次性项目,进入 `project-supervisor + autonomous-game-build`。用户只输入一条需求并以 EOF 交付,收束后复用正式 localhost preview server 并打开试玩。正常收束后按 `Ctrl+C`,脚本先通过内部 CLI 仅关闭已经空闲的隔离 Runner,再清理隔离 AppData 和一次性项目;Runner 仍有任务或无法确认退出时必须同时保留项目与隔离配置并报告路径,不得触碰或强退正式客户端 Runner。需要主动保留项目时显式追加 `-- --keep-project`,需要覆盖配置来源或项目时使用 `--config-dir` / `--project-dir` 绝对路径。脚本不得读取或打印 API Key,显式项目永不自动删除,非空且未初始化目录必须拒绝。
修改 Supervisor 自主编排、`agent.message`、static delivery/claim/repair、Swarm CLI `turn.report`、Runner 恢复或 autonomous harness 后,先跑确定性收敛门禁,再运行真实终端 suite:
```bash
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml background_agent_runtime_bounds_duplicate_agent_message_livelock -- --nocapture
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml agent_runtime_context_window_ -- --nocapture
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml project_supervisor_ -- --nocapture
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml swarm_cli::tests:: -- --nocapture
npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-autonomous-chat-real-e2e -- --config-dir <AppData>
```
业务任务和一次性仓库规则不得出现 Agent ID、数量、并行/同轮、工具、repair 次数、run/action/delegation 或 Runner 配方。PASS 必须由真实发布二进制的 `--swarm-chat` 自主形成至少两个不同专业 Agent 的同批委派和真实 Provider 重叠,在 acceptance criteria 不满足时只形成一个继承原合同的 repair;repair 确认边界执行 Runner 强杀后仍保持父 Session/run、delivery、claim、pending action 和 Provider started 身份。父 run 的 `project.verify` 是允许的宿主验证,其它意外父 pending action继续失败关闭。
终局必须同时得到 `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 游戏创作 Supervisor 协作策略复验
修改 `.agent/collaboration-policy.json`、Supervisor 首波预检、Provider action batch v2、委派后总控 mutation/MCP 门禁、协作 finalization blocker 或对应恢复顺序后,先跑确定性回归,再运行独立真实 suite:
```bash
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml supervisor_collaboration_ -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml provider_action_batch_ -- --nocapture --test-threads=1
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml project_supervisor_mixed_ -- --nocapture --test-threads=1
npm run agc:collaboration-policy-e2e -- --config-dir <AppData>
```
真实 suite 必须在隔离 AppData 和单个父 Session/run 中写入 mixed 策略,要求两个指定 static Agent 与同一 group 的三个 isolated child。首批 batch 必须先停在 `waiting-confirmation / nextActionIndex=0` 且副作用为 0;此时强杀 Runner,恢复后 batchId、policy/contract fingerprint 和全部 actionId 必须逐项稳定,再继续完成 V1.31 mixed chain。为避免长链路被偶发外部 transport 抖动误判,suite 只在隔离配置副本中启用有限瞬态重试,必须同时证明正式 AppData、源配置和 Runner endpoint 未被改动,并在报告中保留 retry 计数。最终仍要求两类真实 Provider 重叠、唯一 Supervisor assistant、零重复/残留/泄漏和 sentinel 清理;命令未运行或报告门禁不完整时不能把确定性测试或 V1.31 PASS 当成 V1.32 PASS。
### AI 游戏创作 Runtime V1.10 持久进程定向复验
V1.10 的 PTY 只通过四个 Runner-owned 工具开放;不要把 V1.2 `command.exec` 改成长驻入口。最小工具输入保持结构化:
```json
{"tool":"command.start","input":{"program":"npm","args":["run","dev"],"cwd":".","timeoutSeconds":300}}
{"tool":"command.poll","input":{"processId":"proc-...","cursor":"v1:proc-...:0","maxChars":8000,"waitMs":1000}}
{"tool":"command.stdin","input":{"processId":"proc-...","data":"q","appendNewline":true,"eof":false}}
{"tool":"command.terminate","input":{"processId":"proc-...","cursor":"v1:proc-...:254"}}
```
定向复验按以下顺序取证:
1. 用 Runner-owned PTY fixture 覆盖 start、增量 poll、stdin、自然退出和 terminate;确认 `processId` 绑定完整 owning project / Agent / task / session / run / start action / Runner boot,而不是 OS PID。
2. 让发起 App / CLI 在 start 后退出,确认 Runner 仍持有会话;随后分别在 launch、running、stdin 和 graceful / force 终止窗口强杀 Runner,确认恢复只进入 reconciliation,不增加 fixture launch / stdin 次数,也不按 PID 重连。
3. terminate 必须携带最后一次 poll 的 `nextCursor`,返回同一 cursor 且不消费输出;活会话和 unresolved reconciliation 期间尝试 finalization 与 `runner.shutdown_if_idle`,必须分别被完成门禁和 busy 状态阻断;终止成功必须同时满足 child terminal、同组残留清理、wait / reap 和 PTY drain。
4. 使用不同静态 Agent、动态 sibling、run 和项目重放同一 `processId`,全部必须失败关闭。扫描 task、event、Agent DB、receipt、action history、activity/output、UI snapshot 和报告,PTY 输出正文命中数必须为 0,stdin 只能出现 `bytesWritten / contentSha256 / stdinOpen / eof`
5. Linux 用忽略 SIGHUP 的 npm / Node fixture 验证 Runner 强杀后 owner watchdog 回收同一前台进程组;Windows 验证 kill-on-close Job Object。仍要明确 PTY、固定 argv、隔离环境和两阶段终止不是容器或 OS sandbox,主动 `setsid` / 外部 service 仍不在完整隔离承诺内。
实现用例统一使用可检索的 `process_session_` 前缀。先运行定向 Rust 用例,再跑 Tauri 全量和真实 Provider
```bash
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml process_session_ -- --nocapture
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml
npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite process-session
npm run ai-game-creator-shell:agent-runtime:real-e2e -- --config-dir <AppData> --suite process-session-runner-kill
```
定向命令必须实际匹配到 V1.10 用例,`0 tests` 不算通过。真实 Provider fixture 不得把工具顺序、processId、readiness 文本所在 chunk 或 OS PID 写进任务提示;验收器只按持久 action identity、fixture 计数、私有输出和公共泄漏扫描判定。三项门禁实际通过后才能把日期、Provider、数量和 PASS 结果写入技术方案或 decision log;未运行或被外部配置阻断时只记录 `BLOCKED` / 未验收事实。
`npm run agc` 会启动 Tauri 开发客户端;其 `beforeDevCommand` 通过 `npm run agc:serve` 先完成壳 typecheck,再启动或复用配套 SpacetimeDB、`api-server` 和固定 `127.0.0.1:3080` Vite。开发态只打开游戏创作聊天入口使用 `npm run agc:game-chat -- [--project-path <absolute-path>]`。只需要浏览器预览同一客户端时可用 `npm run agc:serve`;只启动配套后端和数据库时可用 `npm run agc:backend -- --database <name>`
Linux 多用户共享同一台机器开发时,本地 dev 脚本会为当前 Linux 用户分配一个固定端口段并写入系统级注册表 `/var/tmp/genarrative-dev-port-ranges/registry.json`,自动分配从 `10000-10099` 开始,每段 100 个端口,五个 dev 服务依次使用 `start``start + 4`,其中 BgFilter worker 固定为 `start + 4`。可用 `GENARRATIVE_DEV_PORT_RANGE``npm run dev -- --port-range` 手动指定端口段用于特殊场景;注册表会阻止不同用户使用相同或重叠段,并让同一用户后续启动继续复用自己已占用的固定段。该机制只在 Linux 生效,Windows 把第五个服务纳入原有统一端口探测与漂移逻辑。
本地 `npm run dev``npm run dev:spacetime``npm run dev:api-server``npm run dev:bgfilter-worker` 会在 Rust 子进程环境中绕过项目默认 `sccache` wrapper,避免损坏的本机 cache daemon 阻断 `spacetime publish` 或 Rust 服务启动;显式设置的非 sccache 自定义 wrapper 会被保留。生产 / Jenkins 构建仍按流水线自身的 sccache 策略执行。
@@ -238,6 +462,7 @@ npm run check:native-shells
```
该命令会覆盖 H5 HostBridge 关键测试、微信 / Expo / Tauri 三端桥接层文件结构门禁、完整相对路径文档反查、微信 capability 到真实 WebView / 支付 / 分享页面流程和测试清单的映射门禁、H5 HostBridge 事件订阅双能力门控反查、H5 `navigation.canGoBack` 消费 hook 与直达二级页返回锚点测试、移动端和桌面端单端源码清单门禁、Expo 壳 typecheck / test / EAS build config smoke / config smoke / Metro export smoke、Tauri 壳 typecheck / cargo test、桌面壳 release `--no-bundle` 构建烟测,以及可分发壳与 H5 HostBridge 真实调用链的临时替身词扫描,确认 Expo managed config、移动端 EAS 原生包构建 profile、移动端 iOS / Android production bundle、打包 H5 资产、Tauri release 入口、H5 页面内导航保留完整原生宿主上下文和 H5 HostBridge 真实调用链没有漂移;扫描范围包含微信小程序壳生产 `.js`、Tauri `Info.plist`、共享 HostBridge 契约、H5 native transport,并自动覆盖已接入真实宿主能力 facade 的 H5 生产调用链文件,但不扫描 Expo export、Tauri `target/`、Cargo / Metro 缓存或 release 构建产物。移动壳配置检查必须反查 EAS 生产 profile、文本 / 文档 / 图片 / 音频导入边界都来自共享 HostBridge 契约。登录与支付外链跳转必须保持在该调用链扫描内,`src/services/authService.ts``src/services/payment/paymentRedirect.ts` 是必扫文件;`AuthGate` 的登录成功、退出登录、身份边界刷新和登录状态异常重试都必须通过 `app.reloadWebView` 优先路径,并由 `src/components/auth/AuthGate.test.tsx` 进入该门禁。壳源码和配置继续严格禁止 mock / fake / placeholder / stub / TODO / FIXME / 占位 / 模拟 / 伪造 / 未实现 / 临时;H5 业务调用链允许正常表单 `placeholder` 属性、业务占位图文案和真实兼容 / 故障语义中的“未实现”“临时”表述,但仍禁止 mock / fake / stub / TODO / FIXME / 模拟 / 伪造等替身痕迹。
根仓 Vitest 加载独立 AI 游戏客户端源码时,不得为了模块解析把 `@tauri-apps/api``@tauri-apps/plugin-*` 加入根 H5 依赖;根测试只通过 `vitest.config.ts` 的精确别名使用无副作用测试替身,独立客户端的正式 Tauri guest 依赖继续只由 `apps/ai-game-creator-shell/package.json` 与其 lock 管理。隔离 worktree 验收前需分别执行根 `npm ci``npm ci --prefix apps/ai-game-creator-shell`
反馈页上传凭证在原生壳声明 `file.importImage` 时必须优先走宿主图片导入;移动壳声明 `file.captureImage` 时才显示拍摄凭证入口,并把拍摄图片同样转为 `File` 后复用反馈页原有数量、大小、MIME、data URL 预览和提交 payload 校验。
Expo / Tauri 声明 `navigation.openNativePage` 时,只用于现役同源 H5 路由的受控导航和宿主上下文续接;微信小程序不再声明该能力。旧儿童动作 Demo、模板工作台、生成页、结果页和运行态不得作为 HostBridge 导航验收入口。
H5 支付链接跳转在原生壳声明 `app.openExternalUrl` 时必须优先走宿主系统浏览器;原生壳未接真实支付 SDK 前不得声明 `payment.request`,也不得把外部 H5 支付跳转伪装成原生支付成功。
@@ -273,6 +498,11 @@ npm run check:server-rs-ddd
- 仓库 CI 入口是 `.gitea/workflows/project-ci.yml`,向 `master``codex/ai-game-creator-app` 推送和所有 PR 创建、更新时必须运行,也允许手工触发。
- CI 固定拆分为 `Repository checks``Frontend tests``Backend tests``Native shell tests` 四个 required job;对应 PR context 完整名称是 `Project CI / Repository checks (pull_request)``Project CI / Frontend tests (pull_request)``Project CI / Backend tests (pull_request)``Project CI / Native shell tests (pull_request)`,首次运行后仍须从 Gitea 最近一周 context 表复核。测试使用独立 job,不能只藏在综合检查 step 中;原生壳验收单独运行以便定位重型构建失败。
- 四个 job 共同覆盖 `npm run check`,并追加 `npm run check:server-rs-ddd``cargo test --locked --workspace --no-fail-fast --manifest-path server-rs/Cargo.toml``cargo check -p api-server --all-targets --manifest-path server-rs/Cargo.toml``cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`。后端 runner 安装 `ffmpeg`,避免视频抽帧测试因工具缺失提前返回。`codex/ai-game-creator-app` 分支必须用独立 lockfile 安装 AI 游戏创作壳依赖,其原生壳入口还必须覆盖 `npm run ai-game-creator-shell:check`、release build smoke,并检查 AI Tauri `Cargo.lock` 不漂移。原生壳 job 还要通过 Google 官方签名 APT 源安装 `google-chrome-stable`,用于 headless preview 的真实 DOM / canvas smoke;同时安装 `ripgrep`,把 `actions/setup-node` 的完整 Node.js 22 发行目录与 root-owned rustup proxy 映射到 `/usr/local`,供只接受受信任系统命令目录的 `command.exec` 沙箱测试使用,不能放宽生产命令目录白名单。Tauri 的 1132 项级别 suite 固定 `--test-threads=1`,避免共享 Agent Runtime 后台锁与异步终态在 libtest 并行调度下互相干扰。
- checkout 必须使用完整历史。PR 将 base SHA 写入 `SPACETIME_SCHEMA_BASE_REF`,直接推送 `master` 使用 before SHA;事件基线不可解析时直接失败。Gitea 检查的是 PR head 而非预合并 commitworkflow 必须拒绝不包含最新 base commit 的过期 PR,分支保护同时保持“PR 过期禁止合并”。
- 普通 PR job 不读取业务 secret,不运行真实 API/SpacetimeDB/OSS/支付/生成/live smoke,也不执行会修改外部状态的维护、迁移、发布或备份命令。
- Gitea 至少升级到 `1.26.4` 后才能注册执行 PR job 的 runner`ubuntu-latest` 标签只映射到固定 digest 的 Ubuntu 24.04 级 Docker/临时隔离镜像,不使用浮动镜像 tag,不映射 host,不向 job 暴露 Docker socket、业务 secret 或不必要内网。runner 能访问 Gitea、GitHub Actions 与 `actions/node-versions`、nodejs.org、npm、Rust 分发、crates.io 和 Google Chrome 的 `dl.google.com` 官方签名 APT 源;workflow 的官方 action 固定完整 commit,若内网禁用 GitHub,先在当前 Gitea 镜像对应 commit 并改用绝对 URL。受控镜像优先预装 rustup。Gitea 1.26 的任务超时由 runner 全局配置控制;首次运行成功后,`master` 分支保护必须要求上述四个 job 全部成功。
- `genarrative-station` 当前使用 Gitea `1.26.4` + 基于 Runner `2.0.0-dind-rootless` 的固定 digest 修补镜像:只修复 `systempaths=unconfined` 的空 slice 被 `mergo` 丢失,真实 job 必须保持 `MaskedPaths=[]``ReadonlyPaths=[]`;外层仍非 privileged、无 `CAP_SYS_ADMIN`,内部 Docker 只监听 Unix socket`docker_host: "-"` 阻止 socket 进入 job。job 只在 `gitea-actions` internal network,通过 `/git` reverse gateway 访问 Gitea,通过拒绝私网、保留地址和 metadata 的 80/443 proxy 访问公共依赖;直连公网和 Gitea 数据网必须失败。内层 bwrap 所需 namespace/proc 选项只能用于该 rootless DinD,不能放宽宿主 rootful runner。系统依赖步骤在 root job 中不调用 sudo,非 root 时用 `sudo -E` 保留受控 proxyCargo 关闭 HTTP multiplexing 并设置 10 次网络重试,rustup bootstrap/toolchain 安装也按有界次数重试。AI 原生壳 job 把 Node 发行目录与 rustup proxy 安装到 `/usr/local` 的受信任只读路径,并在测试前执行完整 bwrap canary。宿主 compose helper 必须把 `/opt/gitea-stack` 挂到同名绝对路径,避免相对 volume 错误落到 `/stack` 空目录。
- 四个 job 共同覆盖 `npm run check`,并追加 `npm run bgfilter-worker:smoke-test``npm run check:production-health-patrol``npm run check:production-api-release``npm run check:production-api-deploy``npm run check:server-rs-ddd``cargo test --locked --workspace --no-fail-fast --manifest-path server-rs/Cargo.toml``cargo check -p api-server --all-targets --manifest-path server-rs/Cargo.toml``cargo check -p spacetime-module --manifest-path server-rs/Cargo.toml`。BgFilter 的 `.test.mjs` 使用 Node test runner,必须由 workflow 显式调用;生产巡检 / 发布 / 部署行为检查只运行无密钥临时 fixture,不连接现场环境。`ffmpeg` 由预构建 job 镜像提供,避免视频抽帧测试因工具缺失提前返回。`codex/ai-game-creator-app` 分支的原生壳入口还必须覆盖 `npm run ai-game-creator-shell:check` 和 release build smoke。
- checkout 必须使用完整历史。PR 将 base SHA 写入 `SPACETIME_SCHEMA_BASE_REF`,直接推送 `master` 使用 before SHA;事件基线不可解析时直接失败。Gitea 检查的是 PR head 而非预合并 commitworkflow 必须拒绝不包含最新 base commit 的过期 PR,分支保护同时保持“PR 过期禁止合并”。
- 普通 PR job 不读取业务 secret,不运行真实 API/SpacetimeDB/OSS/支付/生成/live smoke,也不执行会修改外部状态的维护、迁移、发布或备份命令。
@@ -348,3 +578,27 @@ npm run check:server-rs-ddd
3. 是否有长期知识需要写入 docs/project-memory/shared-memory
4. 建议的测试命令和提交信息。
```
## AI 游戏创作 App 命令沙箱验证
- Linux `command.exec / command.start / project.verify` 必须经过受信任系统 bubblewrap;缺失或 namespace / mount preflight 失败时工具失败关闭,不能回退宿主执行。
- 修改命令执行、PTY、项目验证或发布配置后,至少运行 `GENARRATIVE_COMMAND_SANDBOX_REAL_TEST=1 cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml command_sandbox -- --nocapture --test-threads=1``cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml command_exec``cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml process_session -- --test-threads=1`
- 真实门禁必须同时证明项目内 Cargo / npm / Git 成功,项目外普通文件读写失败,`.git / .agent / .agents / .codex / .hermes` 写入失败,网络默认不可达,shell / PTY 后代在 `setsid + chdir` 后仍继承相同边界;process record、poll / stdin / terminate 和 project.verify 审计必须断言 `bubblewrap / workspace-write / disabled / workspace-v1`。另测 `RUSTUP_HOME=$HOME``.rustup -> $HOME` 必须在目标执行前失败。Linux deb / rpm 包必须声明 `bubblewrap` 依赖;AppImage 发布说明必须要求宿主预装受支持的 bwrap,缺失时只能返回 sandbox unavailable。
## AI 游戏创作 App Provider 成功交接验证
- 文本回复继续使用 `game-creator-provider-handoff.v1`tool-plan/function arguments 使用独立 `game-creator-tool-plan-handoff.v1`,禁止为省事放宽文本 handoff。两类 handoff 都必须在 Provider lifecycle `completed` 前原子落盘并回读。
- tool-plan `repair-0..N` 必须共用持久 retry 与 handoff-first 恢复;测试停止点按 request kind/精确 slot 命中,不能让较早的 tool-plan 抢占 final-reply 断点。恢复测试必须关闭 mock Provider,证明零网络、原 requestId 唯一闭合、audit 幂等和终局零 sidecar。
- function arguments 只能进入私有 `0600` handoff 和后续 pending/action batch。参数命中密钥、配置痕迹或结构化可执行路径中的绝对路径时失败关闭,不得先脱敏再执行;源码正文与计划叙述不能用日志路径 token 扫描,以免把 HTML `</tag>` 当路径。未闭合/错配 thinking wrapper 要保留无正文的无效事实并走 repair,不能清洗成可执行计划。公共事件、Agent DB、CLI 和报告只保留哈希、计数与安全身份字段;tool-plan protocol 不保存原始 callId/callIds/responseId/providerRequestId,只保存 call ID SHA-256 数组、catalog-bound function names、response ID SHA-256/字符数和 Provider request ID SHA-256repair 只保存 call ID/function name SHA-256 及协议错误/preview 哈希。protocol/repair 审计必须在 Agent DB append 锁内按完整身份全历史 compare-and-append。
- steer/cancel/终态/身份漂移删除 tool-plan handoff 前,必须先按账本顺序幂等闭合全部实际 requestId lifecycle;不能只闭合当前 base entry 后删除后继 repair。Runner 恢复必须扫描 hash 路径归属、primary/`.previous` 和安全临时文件,回收合法终态残留;Unix 读写、扫描和删除固定在逐层打开的目录句柄,handoff 根目录和 Agent 目录用跨进程 `flock` 序列化,临时文件再用非阻塞 `flock` 判断写入方是否仍持有。已有 primary 的安装通过 `RENAME_EXCHANGE` 双端复核并在冲突时回滚;删除先以 `RENAME_NOREPLACE` 隔离到可恢复 temp 名、复核 inode,再按原 fd 清空并同步私有内容。Windows 逐层使用相对父句柄打开,并用 `GetFileInformationByHandleEx` 直接枚举已验证目录句柄,拒绝 reparse point/junction 与硬链接,临时文件以禁止共享的独占句柄表示活跃写入。不得再用文件名中的 PID 或进程存活推断临时文件所有权。未知、链接、身份替换或内容冲突项保持 busy 并失败关闭;主动忽略 advisory lock 的同 UID 进程仍属于宿主 OS 信任边界,不能宣称为完整沙箱隔离。
- 修改 Provider handoff/retry/Runner idle 判断后,至少运行 `tool_plan_``tool_plan_handoff_``provider_handoff_``provider_retry_`、相关强杀恢复用例、Tauri 串行全量 `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml -- --test-threads=1`、编码检查和 `git diff --check`;涉及跨平台扫描、PID 或临时文件回收时追加 `cargo check --tests --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --target x86_64-pc-windows-gnu`。当前默认并发全量会受 Tauri 共享执行器饱和影响,曾在不同异步投影断言上偶发失败;它只作竞态诊断,失败时必须精确复跑,不能替代串行门禁,也不能把精确复跑结果伪装成默认并发 PASS。真实 Provider suite 单轮 PASS 前,确定性 mock 结果不得写成外部验收完成。
- `supervisor-swarm-tool-plan-handoff-runner-kill` 已实现并在 Shell/Root 两级注册。真实外部 Provider 复验从仓库根目录运行:
```bash
npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-tool-plan-handoff-runner-kill-real-e2e -- --config-dir <发布AppData绝对路径>
```
- suite 必须使用 sentinel-owned sibling AppDatametadata-only zero-fault proxy 不注入 Provider 故障,为转发请求只做协议校验,请求日志仅记录验收所需的序号/时间等元数据,不得持久化或暴露 URL、method、headers、正文或凭据。每轮随机 capability 必须严格绑定 disposable project、目标 Agent、run 和实际 request slot,任一身份漂移、复用或越权命中都失败关闭。
- checkpoint 只允许在目标 tool-plan handoff 原子落盘并逐字段回读一致后、同一实际 requestId lifecycle `completed` 前 ACK;收到 ACK 后才可用 pidfd `SIGKILL` 强杀 suite 自有 Runner。新 boot 恢复前不得出现由该计划产生的 action、pending、delivery、claim 或其它副作用。
- 单轮验收必须证明同一 requestId 唯一闭合且没有替代 identityproxy `networkReplayCount=0`protocol/repair audit 幂等,handoff plan fingerprint 与恢复后的 durable pending/action batch 对应;终局 retry/tool-plan handoff/provider handoff/finalization/confirmation sidecar、重复 lifecycle/audit/action/message、capability/Runner/AppData 临时资源和正文/API Key/Provider URL/项目及正式配置绝对路径泄漏全部为 `0`。失败轮不得与后续轮拼接。
- 当前该 suite 的实现、E2E self-test、Tauri/Rust 串行全量 `1054 passed / 4 ignored / 0 failed`、Linux `cargo check --tests``x86_64-pc-windows-gnu cargo check --tests` 已通过。2026-07-20 的真实外部 Provider 单轮已到达 checkpoint,并证明旧/新 Runner boot 切换、同一请求恢复、`networkReplayCount=0`、恢复前零 action/pending/delivery 与生命周期唯一闭合;但该轮随后因专业 Agent 连续连接失败而以 FAIL 结束,另一独立轮首批工具数不满足 fixture 也以 FAIL 结束,因此仍没有该 suite 的外部 PASS,且不得拼接两轮证据。Provider 成功到 handoff 原子落盘回读前的 unknown-result 仍未关闭,手动 context-compaction 也不在覆盖内;确定性 mock、命令注册成功或其它 suite PASS 都不能替代单轮完整真实验收。
@@ -14,6 +14,7 @@
| 创作入口、草稿架和玩法链路 | `docs/【玩法创作】平台入口与玩法链路-2026-05-15.md` |
| 创作流程统一阶段计划 | `docs/planning/【玩法创作】创作流程统一总计划-2026-05-30.md` |
| 宿主壳、移动 App、桌面 App 与 AI H5 沙箱边界 | `docs/【前端架构】宿主壳能力统一协议-2026-06-17.md``docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md` |
| AI 游戏创作独立 App、Agent Runtime、Runner、浏览器验证与动态隔离子 Agent | `docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md``docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` |
| 本地启动、验证、部署、埋点和运营查询 | `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md` |
| 微信小程序虚拟支付 | `docs/【技术方案】微信虚拟支付接入-2026-05-26.md` |
| UI 像素资产与 9-slice 规范 | `UI_CODING_STANDARD.md` |
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,32 @@
# AI 游戏创作高风险审批 Rank 待解决事项
更新时间:`2026-07-20`
## 背景
项目开发工作台规划“严格审批 / 高风险审批 / 无需审批”三档。严格审批可直接复用现有 Runtime 确认门禁;高风险审批仍缺少可执行 Rank 合同,当前不能由前端自行判断。
## 待确定
- Rank 的事实源和版本号。
- 成本、历史错误率、资源不可逆性、代码/命令副作用、外部发布等维度的权重。
- 单动作 Rank 与批次 Rank 的聚合方式。
- Rank 阈值由谁配置、如何审计和回滚。
- 模型建议与 Runtime 强制规则冲突时的裁决顺序。
- 计费发生前、外部调用前、项目写入前分别在哪个阶段执行门禁。
- Runner 恢复、重复 action、reconciliation 和策略升级时如何保持确定性。
- 普通用户可见的风险原因和不泄露内部诊断的展示格式。
## 临时产品边界
- P0 只启用严格审批。
- 高风险审批在界面中保持视觉不可用,但允许点击查看“Rank 规则待定,暂不可用”。
- 不得把高风险审批静默降级成严格审批或无需审批。
- Rank 合同、Runtime 实现和确定性回归完成前不得开放。
## 关闭条件
1. PRD 冻结 Rank 输入、阈值、版本和恢复语义。
2. Runtime 在副作用前执行同一 Rank 决策,前端只展示后端结果。
3. 覆盖计费、文件写入、命令、外部生成、批次动作、重放和 reconciliation 回归。
4. 普通用户界面能说明为何需要确认,但不暴露 provider、fingerprint、密钥或绝对路径。
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -225,9 +225,9 @@ npm run check
仓库级 Gitea Actions 工作流固定为 `.gitea/workflows/project-ci.yml`,在向 `master``codex/ai-game-creator-app` 推送、创建或更新 PR,以及手工触发时运行。工作流拆成四个必须通过的 job:
- `Repository checks`:执行 `npm run lint`、主站与后台生产构建、内容数据检查和提交差异空白检查。
- `Frontend tests`:独立执行根 `npm run test``npm run bgfilter-worker:smoke-test``npm run check:production-health-patrol``npm run check:production-api-release``npm run check:production-api-deploy`,让 Vitest、Node test smoke harness 及不依赖真实服务的生产巡检 / 发布 / 部署行为 fixture 在 Gitea job 中持续执行;其中 `.test.mjs` 使用 Node test runner,不依赖 Vitest 的 `scripts/**/*.test.ts` 收集规则。
- `Frontend tests`按根 lockfile 与 `apps/ai-game-creator-shell/package-lock.json` 分别执行干净的 `npm ci`,再独立执行根 `npm run test``npm run bgfilter-worker:smoke-test``npm run check:production-health-patrol``npm run check:production-api-release``npm run check:production-api-deploy`,让 Vitest、Node test smoke harness 及不依赖真实服务的生产巡检 / 发布 / 部署行为 fixture 在 Gitea job 中持续执行;其中 `.test.mjs` 使用 Node test runner,不依赖 Vitest 的 `scripts/**/*.test.ts` 收集规则。
- `Backend tests`:执行 `npm run check:server-rs-ddd``cargo test --locked --workspace --no-fail-fast``api-server --all-targets` 编译和 `spacetime-module` 编译;runner 安装 `ffmpeg`,避免视频抽帧测试因工具缺失提前返回。依赖真实服务或密钥的测试必须显式 `ignored`,不能让普通 PR job访问现场环境。
- `Native shell tests`独立执行 `npm run check:native-shells`,覆盖微信壳、Expo 和 Tauri 的完整验收,并确认 Tauri `Cargo.lock` 没有被构建过程改写,避免把重型原生壳或依赖锁漂移隐藏在基础检查末尾`codex/ai-game-creator-app` 分支的同名脚本还会执行 `npm run ai-game-creator-shell:check` 和 AI 游戏创作壳 release build smoke。
- `Native shell tests`按根 lockfile 与 AI 游戏创作壳独立 lockfile 安装依赖后执行 `npm run check:native-shells`,覆盖微信壳、Expo 和 Tauri 的完整验收,并确认桌面壳与 AI 游戏创作壳的 `Cargo.lock` 没有被构建过程改写。`codex/ai-game-creator-app` 分支的同名脚本还会执行 `npm run ai-game-creator-shell:check` 和 AI 游戏创作壳 release build smoke;共享 Agent Runtime 后台锁 suite 固定 `--test-threads=1`,不能用并行偶发失败后的逐项通过替代整套稳定门禁
四个 job 合起来覆盖根 `npm run check`,并补齐根检查没有包含的 BgFilter worker smoke harness、无密钥生产巡检 / 发布 / 部署行为 fixture、server-rs DDD、正式 workspace Rust 测试与现役后端编译门禁。普通 PR CI 不注入业务密钥,不启动真实 API、SpacetimeDB、OSS、支付、图片生成或生产 live smoke;需要现场环境、可变外部状态、Docker 编排或发布凭据的 `check:*` 继续按对应专题和 Jenkins 发布流程执行,不能遍历所有同名前缀脚本冒充 PR 门禁。
@@ -704,6 +704,27 @@ OpenTelemetry 现阶段默认开启 OTLP traces / metrics / logs,但本地日
旧结构化创作 / RPG 的 Responses `web_search` 开关已退出 api-server 配置;部署环境不再保留 `GENARRATIVE_RPG_LLM_WEB_SEARCH_ENABLED``GENARRATIVE_CREATION_AGENT_LLM_WEB_SEARCH_ENABLED`
`platform-llm` 请求默认使用 Responses 协议;需要接旧 OpenAI Chat Completions 兼容网关时,调用方必须显式选择 Chat Completions。三种协议(`openai_chat``openai_responses``anthropic`)都使用原生 function tools,并统一从最终 `LlmRunResponse.tool_calls` 读取工具调用;流式 `on_delta` 只发送文本,不能把工具参数当作文本增量转发。Anthropic 工具请求使用 `input_schema``Required` 使用对象形态 `{ "type": "any" }`Anthropic 当前不支持 `web_search`、图片内容和纯 system 消息。AI 游戏创作独立 App 是客户端,不读取 `.env`;发布 App 启动时会在 Tauri 应用配置目录生成 `game-creator.config.json`,主窗口“配置”面板读写该运行时文件,真实密钥和本机覆盖项写入该文件,仓库内 `apps/ai-game-creator-shell/game-creator.config.json` 只作为默认模板,开发 CLI 无 AppHandle 时才回退读取仓库旁边的 gitignored 覆盖文件。LLM 维度由 `llm.apiKind` 控制,默认 `openai_responses`,可设为 `openai_chat` 接旧 Chat Completions 兼容网关,或 `anthropic` 接 Anthropic Messages。
流式工具片段按协议 slot 聚合,Responses 允许从 `response.completed` / `response.incomplete``response.output[]` 恢复只在整体终态事件中携带的工具调用与正文。`response.incomplete` 中的工具调用即使参数是完整 JSON 也返回 `Deserialize`,截断正文则保留为可用的降级结果。收尾时空参数默认 `{}`,非空参数必须是完整 JSON;解析失败、流式工具缺少身份或参数截断属于 `Deserialize`。流式已声明工具调用但没有聚合出工具 slot 属于 `StreamUnavailable`,由调用方决定是否回退非流式;文本和工具调用均为空才是 `EmptyResponse`
验收证据分为三类:`cargo test -p platform-llm` 的确定性用例验证 checked-in SSE fixture 的 parser 行为;`tests/live_stream_tool_calls.rs` 中默认执行的本地解析测试验证 `PLATFORM_LLM_LIVE_API_KIND` 归一与失败关闭;同文件默认忽略的真实端点用例只做归一后的工具调用 smoke,检查最终工具名、id 和完整参数 JSON,文本增量字符数仅用于打印观测。该 smoke 不录制或逐事件比较原始 SSE,fixture 即使来源于真实抓包也不能据此宣称转录无偏差。
真实端点 smoke 必填 `PLATFORM_LLM_LIVE_BASE_URL``PLATFORM_LLM_LIVE_API_KEY``PLATFORM_LLM_LIVE_MODEL``PLATFORM_LLM_LIVE_API_KIND` 可选,取值为 `anthropic` / `openai_chat` / `openai_responses`,省略或仅含空白时默认 `openai_responses`,未知非空值直接失败,避免拼写错误静默测到另一种协议。仓库根目录没有 `Cargo.toml`,必须显式指定 workspace manifest
```bash
PLATFORM_LLM_LIVE_BASE_URL=https://api.example.com/anthropic \
PLATFORM_LLM_LIVE_API_KEY='<从密钥管理处取,勿写入仓库>' \
PLATFORM_LLM_LIVE_MODEL='<模型名>' \
PLATFORM_LLM_LIVE_API_KIND=anthropic \
cargo test -p platform-llm --manifest-path server-rs/Cargo.toml --test live_stream_tool_calls -- --ignored --nocapture
```
PowerShell 下按测试文件头部示例依次设置三个必填变量,并按需设置 `$env:PLATFORM_LLM_LIVE_API_KIND`,再执行同一条 `cargo test`。切换 `PLATFORM_LLM_LIVE_API_KIND` 逐个跑三种协议,才算覆盖完整;`--nocapture` 会打印解析出的工具名、id、参数和文本增量字符数,便于核对。
该用例只从进程环境变量读取凭据,不读 `.env.secrets.local`,也不会写入任何文件。真实 API Key 一律不得提交进仓库,也不要写进 `docs/`、脚本默认值或测试 fixture;临时密钥用完应在上游及时吊销。
创意 Agent `gpt-5` 文本链路已从 APIMart 切到 VectorEngine`api-server` 读取 `VECTOR_ENGINE_BASE_URL` / `VECTOR_ENGINE_API_KEY` 构造 OpenAI-compatible LLM client,并自动补齐 `/v1` 前缀用于 Responses 协议。排查或切换密钥后,可在本地运行:
创意 Agent `gpt-5.4-mini` 文本链路已从 APIMart 切到 VectorEngine`api-server` 读取 `VECTOR_ENGINE_BASE_URL` / `VECTOR_ENGINE_API_KEY` 构造 OpenAI-compatible LLM client,并自动补齐 `/v1` 前缀后请求 `/chat/completions`。通用 `/api/llm/chat/completions` 代理使用 `GENARRATIVE_LLM_PROVIDER=openai-compatible``GENARRATIVE_LLM_BASE_URL=https://api.vectorengine.cn/v1``GENARRATIVE_LLM_MODEL=gpt-5.4-mini`,未单独配置 `GENARRATIVE_LLM_API_KEY` 时可复用 `VECTOR_ENGINE_API_KEY`。排查或切换密钥后,可在本地运行:
```bash