合并 master 最新变更
Project CI / Repository checks (pull_request) Successful in 6m28s
Project CI / Frontend tests (pull_request) Successful in 10m58s
Project CI / Backend tests (pull_request) Successful in 23m10s
Project CI / Native shell tests (pull_request) Successful in 25m43s

保留共享组件库与 UI 组件复用规范变更

整合 AGC 自主构建与项目工具链最新变更

合并 decision-log 两侧有效决策记录
This commit is contained in:
2026-08-31 14:06:51 +08:00
507 changed files with 20676 additions and 6155 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# 项目记忆目录
本目录只保存可以通过 Git 共享、并且对当前开发仍有效的项目知识。`.hermes/` 只放 Hermes 工具资源,不作为项目知识库。
本目录只保存可以通过 Git 共享、并且对当前开发仍有效的项目知识。`.codex/` 只放 Codex 工具资源,不作为项目知识库。
## 当前结构
+110 -16
View File
@@ -17,6 +17,78 @@
---
## 2026-08-26 运行中自主扩图提案留在编排层
- 背景:`agent-runtime-orchestration` 已能构造和调度动态 DAG,但 LLM 在执行中发现缺少步骤时没有通用的安全扩图合同。
- 决策:新增严格 serde 的 `GraphProposal``TaskProposal` + `GraphEdge`)和 `GraphLimits`,由 `TaskGraph::apply_proposal` / `expand_with_proposal` 在内存中构造不可变候选图;新节点默认 `Pending`,边方向为前置 `from` → 依赖方 `to`
- 安全与一致性:所有 Agent、端点、重复引用、环、节点/边/深度/扇出预算在候选返回前一次校验;边只能指向新节点,禁止给已运行任务原地追加依赖。任一失败保留旧图。成功后的 epoch、基图版本、proposal 幂等和持久化由宿主负责,crate 不调用 LLM/Provider/ToolHost/Runner,也不写 `.agent/runtime/**`
- 验证:非游戏 conformance 覆盖有效扩图、ready/wave 重算、未知 Agent/端点、重复边、已有任务修改、环、预算、严格 JSON 和原子失败;关联文档为 `docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.55。
## 2026-08-26 通用多 Agent DAG 编排与执行内核分层
- 背景:`agent-runtime-core` 已承接 catalog、run/action 生命周期、lane、宿主 ToolHost、spawn/all-join 和 Provider 契约,但动态任务图的 ready 选择、依赖波次与返工下游闭包仍混在 `platform-agent::game_creation`,其它产品无法复用且非法环会被合并成伪 wave。
- 决策:新增纯 Rust `agent-runtime-orchestration`,依赖方向固定为 `agent-runtime-orchestration -> agent-runtime-core`。公共层只持有任务 ID、Agent ID、通用状态和依赖边,统一负责构图校验、ready、active/satisfied 波次、下游闭包和全量/返工选择;动态构图仍必须是 DAG,跨轮循环通过新的 pass / epoch 表达。
- 产品边界:16 个游戏任务、六组角色、产物/验收条件、Evaluator Markdown 和中文语义路由继续留在 `platform-agent`;AGC 组合根使用公共层校验任务图与 `AgentCatalog`。Runtime store、Runner、Provider、权限、ToolHost、委派 journal、isolated write scope 和 `.agent/runtime/**` 不迁移、不双写。
- 验证方式:非游戏 conformance 覆盖并行分支、汇合、repair closure、AgentCatalog 和非法图失败关闭;`platform-agent` 锁定种子 DAG 与现役波次/返工顺序,并验证环拒绝和 catalog 注入。根检查脚本必须执行新 crate 测试。
- 关联文档:`docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md` V1.54。
## 2026-08-27 `plan.submit_gdd` 拒绝无审批决定的 `user_revision`
- 背景:结构校验允许 `round=0 + user_revision + confirmed`,提交闸原先只做结构、身份和 Session CAS。Provider 可在首次 collecting、澄清续跑或提交前质量返工里把未确认项标成用户审批修改,审批卡显示「已确认」。
- 决策:新版本 create 时,payload 含 `user_revision` 则当前 session 的 `lastDecisionRef.action` 必须是 `revise``reject`;否则 `PLAN_INVALID_REQUEST`。同 `submissionId` replay 不重判。不恢复 session 前缀逐项相等,不把 `user_revision` 与审批意见正文对齐,也不在这次处理 `round≥1``user_option` 伪造。
- 影响范围:`planning_submit.rs` 提交闸;Fast GDD 技术方案第 5.1 / 8.2 / 12 节。
- 验证方式:首次 collecting 带 invented-confirmation 必须拒绝且不落 GDDreject continuation 再交 `user_revision` 的 v2 仍成功。
- 关联文档:`docs/technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md`
## 2026-08-28 planning continuation 必须沿当前 delivery 游标推进
- 背景:`lastDecisionRef.action=revise/reject` 在用户修订后的质量返工中必须继续有效,但仅凭该历史指针无法证明当前 `agent.delegate` 选择的是本次 planning session 的当前分支。
- 决策:不新增用户修订授权字段,也不在 `plan.submit_gdd` 重复遍历 approval receipt/GDD lineage。已有 planning session 创建新 child 时,`repairOfDelegationId` 必须直接等于旧 session 的 `latestDelegationId`;不一致即在 Provider 启动前以 `PLAN_NEEDS_RECONCILIATION` 拒绝。合法用户修订及其后质量返工继续保留 `lastDecisionRef`,成功提交新的 GDD 后仍由 submit successor 清理该指针。
- 影响范围:`planning_coordinator.rs` continuation 投影门;Fast GDD 技术方案第 8.2 节和提交步骤;不改变静态委派通用返工合同或 `PlanSessionV1` schema。
- 验证方式:新增当前游标 continuation 正向/旧 delivery 负向回归;CI 继续验证首次伪造 `user_revision` 拒绝、用户修订后质量返工提交成功及现有澄清/返工 lineage。
- 关联文档:`docs/technical/【技术方案】立项策划AgentFast GDD-2026-08-10.md``apps/ai-game-creator-shell/src-tauri/src/agent/runtime_protocol/planning_coordinator.rs`
## 2026-08-27 退款 emergency spool 容量溢出保持可恢复
## 2026-08-27 退款 emergency spool 容量溢出保持可恢复
- 背景:本机 emergency spool 仅作为 SpacetimeDB 完全不可达时的最后恢复路径,原有 `MAX_BYTES` 分支会直接返回 `Dropped`,导致扣费已经完成但没有可重放记录。
- 决策:达到普通 outbox `MAX_BYTES` 时,将退款记录写入同一持久目录的 `refund-overflow-*` 文件;该文件与普通 pending 文件一样由启动恢复和后台 worker 重放到 SpacetimeDB,且按 refund ledger id 保持幂等。溢出文件不计入普通阈值,但必须触发容量告警;底层磁盘写入失败仍进入关键退款人工补偿流程。
- 影响范围:api-server wallet refund emergency spool、资产失败退款日志、loadtest / 预览 Compose 持久卷、后端架构与开发运维文档。
- 验证方式:运行 api-server `wallet_refund_outbox` 定向测试,确认超限写入并保留 overflow 文件;运行 SpacetimeDB profile 测试、Compose 配置校验、编码和 diff 门禁。
## 2026-08-27 短期认证状态进入共享 typed projection
- 背景:短信验证码和微信 OAuth state 仍只存在 API 进程内 HashMap,多节点请求或 API 重启会直接丢失,无法满足无粘性会话的鉴权恢复要求。
- 决策:`AuthStoreProjectionView` 增加 `phone_codes``wechat_states` typed 字段,由 `auth_store_projection_meta` 以 JSON 投影持久化;启动恢复、CAS 同步和失败后的权威刷新都覆盖这两类短期状态。验证码哈希使用部署级稳定盐(当前复用 `GENARRATIVE_JWT_SECRET`),各 API 节点必须一致;发码前先刷新权威投影并用占位验证码记录做一次 projection CAS,只有占用成功才调用短信 provider,避免跨节点冷却竞态;认证 handler 在发码、消费验证码、创建/消费微信 state 后都要完成 projection sync,失败即返回服务错误;所有会读取或变更本机认证工作集的认证主链路(登录、刷新、`/me`、会话管理、密码、绑定和微信 state)在领域操作前先从正式投影做一次受 CAS 保护的只读刷新,受保护 Bearer 中间件也会在进入业务 handler 前执行同样的刷新,刷新失败时 fail closed,不能依赖粘性会话;同步遇到 CAS 冲突时,若本次尝试期间没有新的本地变更则恢复正式快照,若仍有待同步 revision 则由后续认证请求重试,避免节点永久卡在 pending。微信 OAuth state 设置有界活动数量,避免单个 JSON 投影无界膨胀。短期状态仍由 `module-auth` 内存工作集执行领域校验,但不再把本机 HashMap 当作持久化或跨节点真相。
- 影响范围:`module-auth` projection、`spacetime-module` auth schema/procedure、`spacetime-client` bindings/facade、api-server 手机号 / 微信 handler、认证架构与运维文档。
- 验证方式:运行 module-auth projection roundtrip(验证码可跨恢复校验、微信 state 可跨恢复消费)、SpacetimeDB schema/runtime/DDD 门禁、api-server 定向测试、编码和 diff 检查。
---
## 2026-08-27 外部生成历史采用受控保留清理
- 背景:`external_generation_job``external_generation_job_summary``external_generation_job_event` 都是持久化表;摘要和 payload 边界收紧后,已确认的终态历史仍会继续占用 SpacetimeDB 常驻内存,且事件审计链会随任务数量增长。
- 决策:新增仅 migration operator 可调用的 `prune_external_generation_job_history_and_return`。默认按 `source_module=editor-canvas`、30 天保留期和 `job_id` 游标分批运行;只删除主任务与摘要状态一致、属于 completed / failed / cancelled、摘要已有 `notification_acknowledged_at` 且终态时间达到 cutoff 的任务。事件、摘要和主任务仍按同一事务顺序删除,但每次事务最多删除 256 条事件;事件未删完时保留任务与摘要并返回同一个 job cursor,维护脚本下一次继续,避免单个任务形成无界事务写集。默认 dry-run,必须固定 dry-run 返回的 cutoff 后再 applypending / running、未确认通知、摘要缺失或状态不一致的数据永不删除。其他 source module 必须显式指定并单独评估;资产对象和钱包流水不随任务历史删除;不新增自动定时器或 runtime 清理权限。
- 影响范围:`server-rs/crates/spacetime-module/src/external_generation.rs`、外部生成事件 job_id 单列索引、SpacetimeDB 生成 bindings、`scripts/spacetime-maintain-external-generation-jobs.mjs`、架构与生产运维文档。
- 验证方式:覆盖终态 / 活跃态 / 已确认与未确认摘要、状态或身份不一致、cutoff 边界测试;运行 SpacetimeDB module tests/check、bindings 生成、schema/encoding/diff 门禁,并在维护窗口先 dry-run 再 apply。
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`、PR #203
## 2026-08-27 SpacetimeDB 工具链统一升级到 2.8.3
- 背景:SpacetimeDB 2.8.0 引入 TypeScript submodule 与调度延迟观测,2.8.1 修复 v1 WebSocket 订阅移除死锁、TypeScript SDK `array<u8>` 读缓存别名和 Rust string 默认值支持,2.8.2 修复 table accessor 改名自动迁移,2.8.3 修复 scheduled function 从实际执行时间重排导致的长期漂移。仓库若继续锁定 2.7.0,会保留这些已知运行时与 SDK 问题。
- 决策:`server-rs/Cargo.toml``spacetimedb``spacetimedb-sdk``spacetimedb-lib` 精确锁定 2.8.3;本地 CLI / standalone、Rust bindings、worker smoke 本地镜像、官方容器压测镜像和生产 provision 下载根同步对齐 `v2.8.3`CLI / standalone commit 门禁为 `8e410d28...`。2.8.3 不再使用 2.7.0 的 hotfix3 特殊资产标签口径,但同版本 commit 校验继续保留。
- 影响范围:Rust workspace lockfile、SpacetimeDB bindings、本地 dev 版本门禁、容器 smoke / loadtest、server provision Jenkins 与项目 SpacetimeDB skills / 文档;现役 module 未使用 submodule,本次不修改 schema 或 migration。
- 验证方式:核对 CLI 版本和 commit,重新生成 Rust bindings,运行 `npm run check:spacetime-schema`、相关 Cargo check / tests、server provision 工具测试、dev 调度测试、encoding 和 diff 门禁。
- 关联文档:`docs/【后端架构】server-rs与SpacetimeDB数据契约-2026-05-15.md``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
## 2026-08-26 Fast GDD 修订后先取证再允许再次委派
- **现象**:GDD v1 经用户选择“修改”后,策划子 Agent 正确提交 v2,但 plan 根 Supervisor 的 `Delegated` 阶段仍同时广告 `agent.delegate` 与审批前置工具;模型可能在 Acceptance Graph 重新取证前重复创建修订 delivery,随后被 `PLAN_PROVIDER_USAGE_DEFERRED` 拦停。
- **决策**plan 根阶段增加轻量的 `AwaitingAcceptanceEvidence` 状态。当前根最新 GDD 无 approval receipt/pending、session `latestSubmittedRef` 精确指向该提交、delivery 已由根认领且 Acceptance Graph 返回 `NeedsEvidence` 时,只广告 `file.read``agent.acceptance_update``agent.run_status`;只有用户真正对最新审批卡选择修改/退回后,才恢复 `agent.delegate`
- **边界**:不放宽 Provider usage 门禁,不重构 delegation/repair lineage,不自动生成证据或审批 pending;审批 pending 仍只由既有 acceptance gate 在 `agent.acceptance_update` 成功后创建。
- **验证**:新增一条阶段工具面回归,并通过 15 条 M1C-2a acceptance gate 定向测试、plan root 原生工具目录测试、`cargo check --all-targets`、格式与 diff 检查。
- **锁边界修正(2026-08-27**:阶段判定拆为 `plan_root_supervisor_stage_at_locked` 与负责取得一次项目锁的外层入口;Provider tool-plan builder 已持有项目锁时直接复用 locked 入口。Acceptance Evidence 判据和阶段工具面不变,禁止在持锁调用链中再次获取 `.agent/project.lock`
- **回归验证**planning submit 定向测试 68 passed、Provider request builder 定向测试 17 passed、Tauri `cargo check``cargo fmt --check` 通过。
## 2026-08-24 AGC Direct 媒体能力只通过客户端语义工具开放
- 背景:资源页已经补齐视频、角色动画、音效和背景音乐的 create/derive 能力,但 Direct Codex 只能准备标准美术包,无法查询已登记源资源或表达新增媒体意图。直接开放 Tauri invoke 会把项目路径、revision、operation、幂等键、登录态和事务权力交给模型。
@@ -1298,8 +1370,8 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- OSS 固定恢复入口为 `<prefix>/<database>/latest.json`。CAS 文件和 full/history catalog 保持不可变;latest pointer 只保存最新 full catalog 与已发布 history catalog 的 object key、长度和 SHA,不包含主机绝对路径或文件内容。每次 state 变化先验真全部引用 catalog,再覆盖上传并 HEAD 验真 latest pointer,成功后才落本地 statehistory 还必须在 pointer 成功后才允许删除源文件。全新机器可仅凭 bucket、database、prefix 与 OSS 凭据自动下载 pointer 和 full catalog。
- dev 带宽不足时,允许把已冻结的 dev 基线经 `10.2.0.10 -> 10.2.4.16` 内网 rsync 到 release 独立 staging,再用 release 出口上传 dev bucketstaging 不得指向 release `/stdb`,不得停止或修改 release 服务,传输凭据必须临时创建并在演练后移除。catalog 不记录 staging 绝对路径,files state 可回传 dev 继续 history。
- 恢复边界:恢复时默认从 OSS `latest.json` 自动定位 full catalog,创建目录并按相对路径下载每个对象、逐文件校验长度与 SHA;本地 state 只用于备份续跑,不再是异机恢复前置条件。远程 dev 已完成真实 OSS、清理、重启和异机隔离恢复演练;release timer 与 publish 前备份继续保持原行为。
- systemd 接线:主 service 保持 `archive-full`。Server-Provision 新增默认值为 `archive-full``DATABASE_BACKUP_PROFILE`dev 或 release 显式选择 `files-history`,必须为各自主机指定独立 work-dir并先用 current release 脚本执行 history dry-run,确认已有 full state 后才安装仓库托管 drop-in,并删除现场手写旧 drop-in。切回默认 profile 必须删除所有 history 覆盖
- 影响范围:`scripts/database-backup-to-oss.mjs`、备份门禁、生产 env 示例、systemd 模板、Server-Provision、SpacetimeDB 运维与恢复流程;release timer 可在独立 baseline 验证后显式选择 profile,publish 前备份是否切换仍需单独决策。
- systemd 接线:主 service 保持 `archive-full`。Server-Provision 新增默认值为 `archive-full``DATABASE_BACKUP_PROFILE`development 可显式选择 `files-history`,必须指定独立 work-dir 并先用 current release 脚本执行 history dry-run,确认已有 full state 后才安装仓库托管 drop-inrelease 拒绝 `files-history`,直到流式 catalog 改造完成,以免大目录扫描再次触发 Node 内存峰值。切回默认 profile 必须删除所有 history 覆盖;备份 unit 同时设置 Node heap 与 systemd memory 上限,避免备份异常拖垮业务主机
- 影响范围:`scripts/database-backup-to-oss.mjs`、备份门禁、生产 env 示例、systemd 模板、Server-Provision、SpacetimeDB 运维与恢复流程;release timer 固定使用 archive-full,publish 前备份是否切换仍需单独决策。
- 验证方式:`npm run check:database-backup``npm run check:production-ops``npm run check:encoding``git diff --check`;dev 现场必须完成逐文件 full catalog、重复 full 零 PUT、history dry-run、上传后清理、STDB 重启和按 catalog 隔离恢复 roundtrip。
- 关联:<https://github.com/clockworklabs/SpacetimeDB/issues/5542#issuecomment-4981566448>。
@@ -2166,13 +2238,15 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 验证方式:微信小程序首点登录仍打开原生登录页;小程序支付仍跳转 `/pages/wechat-pay/index` 并保留 hash 回灌确认;订阅授权仍跳转 `/pages/subscribe-message/index` 且返回不阻断生成;普通浏览器分享、H5 支付和 Native 二维码支付不受影响。前端验证运行 HostBridge、auth、payment、分享、订阅和个人中心充值相关定向测试,并执行 `npm run typecheck``npm run check:encoding`
- 关联文档:`docs/【前端架构】宿主壳能力统一协议-2026-06-17.md`
## 2026-06-15 SpacetimeDB 本地 skills 只保留 CLI / Concepts / Rust
## 2026-06-15 SpacetimeDB 本地 skills 范围(已由 2026-08-27 决策覆盖)
> 2026-08-27 覆盖说明:本节记录的“三个本地 skill”方案已收敛为单一项目适配层;当前口径见下方“SpacetimeDB 项目 skill 与官方插件职责收敛”。
- 背景:本仓库的 SpacetimeDB 接入已固定为 `server-rs + Axum + SpacetimeDB`,本地 skill 需要从上游 SpacetimeDB `skills/` 更新到 2.5 口径,同时避免继续维护当前项目不使用的 TypeScript server/client、C# 和 Unity 专用 skill。
- 决策:`.codex/skills/` 下只保留 `spacetimedb-cli``spacetimedb-concepts``spacetimedb-rust` 三个本地 SpacetimeDB skill;删除 `spacetimedb-typescript``spacetimedb-csharp``spacetimedb-unity`。前端 / Node 侧如需处理 SpacetimeDB 订阅或绑定,按当前生成绑定、项目代码和官方文档核对,不再依赖仓库内单独 TypeScript skill
- 影响范围:`AGENTS.md` SpacetimeDB skill 清单`.codex/skills/` 本地 skill 维护范围、后续 SpacetimeDB 设计 / CLI / Rust module 开发协作口径
- 验证方式:用上游 `clockworklabs/SpacetimeDB@master``skills/` 目录对照,运行本地 skill 校验、删除引用扫描、`git diff --check -- .codex/skills AGENTS.md .hermes/shared-memory/decision-log.md``npm run check:encoding`
- 关联文档:`AGENTS.md``.codex/skills/spacetimedb-cli/SKILL.md``.codex/skills/spacetimedb-concepts/SKILL.md``.codex/skills/spacetimedb-rust/SKILL.md`
- 决策:当时仅在仓库内维护与当前后端路线相关的 SpacetimeDB skill,通用 SDK/CLI 内容按上游资料核对;该历史范围已由 2026-08-27 的项目适配层方案替代
- 影响范围:当时的 `AGENTS.md` SpacetimeDB skill 清单和本地 skill 维护范围;当前范围以新的项目适配层及官方插件路由为准
- 验证方式:保留当时的上游 skill 对照、本地 skill 校验、删除引用扫描、diff 和编码检查记录
- 关联文档:`AGENTS.md``.codex/skills/genarrative-spacetimedb/SKILL.md``docs/【协作规范】Agent工作入口与执行准则-2026-06-22.md`
## 2026-06-13 图片大图预览统一为黑底全屏查看器
@@ -3387,9 +3461,9 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 背景:新增玩法的创作工具如果默认复制既有玩法的聊天式 Agent、轻输入 Agent 或专属素材模型,平台会不断复制出不可控分支,后续接入、测试和恢复语义都会漂移。
- 决策:新增玩法创作工具统一收敛为平台级 SOP:默认使用表单/图片输入创作工作台;单图资产统一通过 `CreativeImageInputPanel`;系列素材统一走批量规划、sheet 生图、后端切图、透明化、OSS 持久化和局部重生成流水线;不把任一玩法专属素材模型当平台通用模型。
- 影响范围:`CONTEXT.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``.codex/skills/genarrative-play-type-integration/SKILL.md``.hermes/skills/genarrative-play-type-integration/SKILL.md`后续新增玩法 PRD 和工程实现。
- 影响范围:`CONTEXT.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``.codex/skills/genarrative-play-type-integration/SKILL.md`、后续新增玩法 PRD 和工程实现。
- 验证方式:新增玩法 PRD 必须显式声明单图资产槽位和系列素材槽位;新增工作台测试确认没有默认聊天式 Agent 输入;skill 通过 `quick_validate.py`
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``.codex/skills/genarrative-play-type-integration/SKILL.md``.hermes/skills/genarrative-play-type-integration/SKILL.md`
- 关联文档:`docs/【玩法创作】平台入口与玩法链路-2026-05-15.md``.codex/skills/genarrative-play-type-integration/SKILL.md`
## 2026-05-20 敲木鱼玩法按完整平台纵切接入
@@ -3964,13 +4038,13 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 验证方式:VN 定向前端测试、`npm run typecheck``npm run check:encoding``cargo test -p api-server visual_novel``cargo test -p api-server creation_agent_document_input`
- 关联文档:`docs/prd/AI_NATIVE_VISUAL_NOVEL_TEMPLATE_PRD_2026-05-05.md`
## 2026-05-04 在仓库 `.hermes/` 中建立团队共享记忆
## 2026-05-04 建立仓库级项目知识与工具边界
- 背景:团队有 3 名开发人员,均在各自本地安装 Hermes,并需要独立拉取仓库、修改代码本地测试;团队希望形成共享的长期项目记忆
- 决策:不共享个人 `~/.hermes`,先在 Genarrative 仓库内使用 `.hermes/` 保存可 Git 同步的团队共享记忆、计划和未来 skills
- 影响范围:`AGENTS.md``.hermes/README.md``docs/project-memory/shared-memory/`
- 验证方式:任一开发者拉取仓库后,在项目根目录启动 Hermes,均可读取同一套 `docs/project-memory/shared-memory/` 文件
- 关联文档:`.hermes/README.md``docs/project-memory/shared-memory/team-conventions.md`
- 背景:团队有 3 名开发人员,需要独立拉取仓库、修改代码本地测试,同时共享稳定的项目知识与工具约定
- 决策:长期项目知识统一保存在 `docs/project-memory/`仓库内 `.codex/` 保存可 Git 同步的 Codex skills、插件资源、hooks 和配置模板;个人 `~/.codex` 始终保持本机私有
- 影响范围:`AGENTS.md``.codex/README.md``docs/project-memory/shared-memory/`
- 验证方式:任一开发者拉取仓库后,先读 `AGENTS.md`,即可按入口读取同一套 `docs/project-memory/shared-memory/` `.codex/skills/`
- 关联文档:`.codex/README.md``docs/project-memory/shared-memory/team-conventions.md`
## 2026-04-25 后端唯一落地口径固定为 Rust / SpacetimeDB
@@ -5843,7 +5917,7 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 决策:Linux `command.exec / command.start / project.verify` 的安全事实源从固定 program / argv 白名单或平行 npm spawn 升级为同一个 bubblewrap OS sandbox launcher。approval policy 继续决定是否确认,sandbox 独立限制文件系统和网络;普通 confirm 永远不能扩大 sandbox。
- 决策:Linux 只允许受信任系统 bubblewrap,缺失、权限异常或 namespace setup 失败必须在项目命令执行前失败关闭,不用裸 userns、代理变量或宿主全权限回退。当前机器 bubblewrap 0.11.1 已通过真实 namespace smoke,裸 userns 因 AppArmor uid_map 限制不可作为可靠 fallback。
- 决策:项目根可写,`.git / .agents / .codex / .hermes` 只读,`.agent` 隐藏且不可写,项目外普通用户文件不挂载,network namespace 默认隔离;HOME / TMP / cache 使用 sandbox 私有目录,所有 shell、PTY 和后代继承同一边界。
- 决策:项目根可写,`.git / .agents / .codex` 只读,`.agent` 隐藏且不可写,项目外普通用户文件不挂载,network namespace 默认隔离;HOME / TMP / cache 使用 sandbox 私有目录,所有 shell、PTY 和后代继承同一边界。
- 决策:Linux sandbox 生效后,program 扩展为受信任 PATH 中的裸可执行名,argv 仅保留结构长度与控制字符门禁,允许 shell 管道和项目脚本;Windows 在等价原生 sandbox 落地前继续使用 V1.10 固定白名单与 Job Object,不能宣称通用命令或 Codex CLI 级隔离。
- 验收门禁:项目内构建 / 测试 / Git 读取成功;项目外读写、控制目录写入和网络访问失败;子进程与 PTY 会话继承相同边界;bubblewrap 不可用时零项目命令执行。真实 Provider 还需在无固定命令配方下自行发现并运行项目命令。
- 审计与发布:process record v2 保存 launch 当时的 backend / mode / network / profile,后续 process 工具从 durable/live 身份读取,preflight 失败使用 unavailable / not-established,不能按平台静态宣称已建立。共享 `os-workspace-sandbox` capability 只标记 Linuxdeb / rpm 声明 bubblewrap 依赖,AppImage 依赖宿主预装并保持 fail-closed。
@@ -7717,6 +7791,20 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 安全:DirectProject 使用真实 `game/` writable root、`approvalPolicy=never`,原生命令网络保持关闭,联网资料继续走受控 `agc_web_search`Codex 子 Agent、Apps、插件、hooks、图片生成、Goals、Workspace Dependencies、Tool Suggestion 与未审计浏览器/电脑控制继续关闭。配置了 AGC LLM Key 或可解析的 `OPENAI_API_KEY` 登录态时,真实 provider 凭据只留在 AGC 本地代理;前者仍走已配置上游,后者只走 OpenAI 官方 API,Codex 仅获得连接级随机代理令牌。无法安全代理的 OAuth `auth.json` 继续关闭原生 shell/unified exec。app-server 使用隔离 `CODEX_HOME`shell 用 `shell_environment_policy` glob 排除 provider key、proxy、loopback bridge 和受控开关。
- 上下文:Direct 系统提示词只保留身份、cwd、边界和 Skill 索引;不再预注入项目源码快照、项目提示词或 Skill 正文。浏览器工具回传结构化事实,不强制固定三次整改循环;Codex 自行解释证据并决定是否继续。sandbox writableRoots 不提供 deny-read`.agent`/`../assets` 的不可读约束需靠行为合同和真实 smoke 验证。
## 2026-08-27 GDD 修改后历史 receipt 不得污染当前审批恢复
- 现象:GDD“修改”已成功生成下一版本且当前 pending 身份正确,但 hydrate 持续返回 `recoveryPending=true`,审批卡显示“审批状态正在恢复”。
- 原因:恢复扫描会重放全部历史 approval receipt;旧版本 receipt 仍拿当前单例 approval pending 做 identity 比对。修改后当前 pending 已属于新版本,旧 receipt 的 identity 不同是正常状态,却被误记为投影缺口。
- 决策:receipt 的 index、Markdown、audit、submit observation、session 等投影继续允许全量恢复;approval pending 只由 lineage 最新 GDD 的 receipt 读取、更新和清理。历史 receipt 不得检查或改写当前 pending,也不得因此提升 `recoveryPending`
- 审批意见消息按 receipt 的 `rootRunId` 解析到原 Supervisor task 所属会话恢复;不会按当前 active session 重新路由。已存在于归档会话的幂等消息允许重放且不新增消息,缺失消息仍保持恢复失败,不静默写入其他会话。
- 验证:沿用现有审批恢复与 planning submit 定向测试;未新增独立测试,避免为非代表性 fixture 引入额外状态构造。
## 2026-08-27 审批修订以最新用户意见更新 GDD 决定快照
- `decisions` 表示当前 GDD 版本的决定快照,不再作为新提交必须逐项复制的 session 历史前缀。审批修订可以修改、推翻、删除或新增决定;Runtime 只校验结构、身份、CAS、版本和原型验证项双射,不做自然语言修改范围门禁。
- 新增 `answerSource=user_revision`,用于标记来自审批修改意见的当前决定,按 `round=0` 记录;`default` 仍只表示未提问的默认建议,澄清来源仍使用 `user_option` / `user_freeform`
- planning Prompt 约束为:以当前 GDD 为基线,仅修改用户意见明确涉及的内容及保持内部一致性所必需的派生内容,未涉及内容保持不变;意见与旧决定冲突时以最新意见为准。
## 2026-08-24 AGC UI 原型桥接与自主 UI workflow
- 决策:`ui-prototype` 图片与 `UI` JSON 编辑资源保持两种正式类型。Agent 通过受控 `ui.workflow.run``prepare -> recognize -> status -> finalize` 创建页面资源、关联源图、持久化 UI State 和 manifest 阶段;`recognize` 直接复用 UI Editor 的 provider-backed 结构识别、多树合并与组件绑定命令,按 `reference-ready -> structure-ready -> merge-ready -> binding-ready` 逐阶段写入并推进项目 revision。页面可显式关联已登记图片/图标和字体,图片/图标按 5 项一批绑定,字体安全元数据进入绑定上下文且未知引用失败关闭。Runtime 回执携带 `revisionAdvanceCount`;Provider 未配置、请求失败、工具调用缺失、结果不匹配、未产出可渲染组件或仍有待审节点时保留最近真实阶段,禁止用 deterministic seed 冒充语义处理完成。
@@ -7760,3 +7848,9 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 决策:新增 `PlatformBackActionButton` canonical 返回动作组件,统一 compact / regular 尺寸、返回图标和 platform / editorDark surface`src/components/common/PlatformBackActionButton.tsx` 仅保留兼容出口。
- 迁移:`LoginScreen``BindPhoneScreen``CustomWorldEntityCatalog` 将已有共享 `Platform*` chrome 直接从 `@genarrative/shared/components` 引入;展示页新增返回动作示例并保留整行开关示例。
- 边界:媒体、上传、资源换签、业务弹窗等带副作用组件继续留在网站业务层。
## 2026-08-28 AGC 自主构建放开编排约束
- `autonomous-game-build` 中,manifest `dependencies` 只作为上下文,不阻塞 ready;代码、设计、美术、音频和发布任务允许并行启动,child 不依赖固定回执顺序或固定 run 身份才能推进。
- 任务最终状态不再提前绑定平台画布、preview、static smoke 或发布产物检查;这些内容不参与该档位的完成判定,也不会因缺失而重置已完成任务。父 run 在任务图进入终态后直接收束并回复。
- 本档位仍沿用现有项目根和工具权限边界;本次调整只解除流程编排与平台产物验收前置,不新增第二套任务系统。
@@ -1,6 +1,6 @@
# 开发工作流
更新时间:`2026-08-25`
更新时间:`2026-08-27`
## 标准流程
@@ -8,6 +8,8 @@
确认工作树与目标分支 → 读取入口和当前专题 → 查代码真相 → 小步修改 → 定向验证 → 更新当前文档/记忆 → 检查提交边界
```
任务开始时先写清一句话交付结果、验收判据和不做项,再按“必须项 / 风险项 / 可选项”排序。先完成修改、定向验证和边界检查组成的最小闭环;设置时间盒和检查点,新增发现只有在影响交付判据时才扩大范围,否则记录为后续事项。不要让工具探测、历史整理或验证便利自行改变任务目标。
## 开始前
- 运行 `git status --short`,保留用户已有的未提交修改;不要在共享工作树中使用破坏性 Git 命令。
@@ -35,6 +37,8 @@
## 验证路由
SpacetimeDB 任务统一先读取 `.codex/skills/genarrative-spacetimedb/SKILL.md`;该项目适配层按需调用已安装的官方 `spacetimedb` 插件 skill,插件提供通用 SDK/CLI/MCP 知识,项目 skill 负责 Genarrative 架构边界和验证门禁。
按改动范围选择定向门禁,不以无关全量扫描代替契约验证:
| 范围 | 至少运行 |
@@ -58,4 +62,4 @@
## Gitea CI 依赖闭合
`.gitea/workflows/project-ci.yml``Native shell tests` 在运行原生壳门禁前,必须使用 `cargo fetch --locked` 预取 `server-rs/Cargo.toml`、桌面壳和 AGC 壳三份依赖。AGC 壳检查还会运行 `platform-llm``shared-contracts` 的 server-rs workspace 测试,这些命令以及 AGC 壳测试必须带 `--locked`,避免在测试阶段重新解析 registry index;锁文件发生变化时应先更新受信任 CI 镜像缓存,再重跑门禁。
`.gitea/workflows/project-ci.yml``Native shell tests` 在运行原生壳门禁前,必须使用 `cargo fetch --locked` 预取 `server-rs/Cargo.toml`、桌面壳和 AGC 壳三份依赖。Backend host workspace tests 使用 `cargo test --locked --workspace --exclude spacetime-module --no-fail-fast`,避免 `spacetime-module``spacetime-types` feature 统一污染普通领域 crate 的 host 测试;随后单独执行 `cargo test --locked -p spacetime-module --no-fail-fast`,由 `spacetime-module/src/active.rs` 在 host 测试构建期间提供仅测试期的 SpacetimeDB ABI 链接支持,使该 crate 的纯单元测试也纳入 Backend 门禁。`spacetime-module` 的 reducer / procedure 运行时行为仍必须通过真实 SpacetimeDB runtime/integration harness 验证,host 链接支持不得被当作运行时替身。Backend 另外执行 `cargo check --locked -p spacetime-module` 验证模块源码。AGC 壳检查还会运行 `platform-llm``shared-contracts` 的 server-rs workspace 测试,这些命令以及 AGC 壳测试必须带 `--locked`,避免在测试阶段重新解析 registry index;锁文件发生变化时应先更新受信任 CI 镜像缓存,再重跑门禁。
@@ -1,6 +1,6 @@
# 任务交接模板
> 用途:当一名开发者把任务交给另一名开发者,或让 Hermes 接续上下文时,复制本模板并填写。
> 用途:当一名开发者把任务交给另一名开发者,或让 Codex 接续上下文时,复制本模板并填写。
## 基本信息
+40 -11
View File
@@ -2,6 +2,27 @@
> 当前口径:本文件保留可复用的排障经验;历史条目的旧路由、旧版本和已删除文档仅作根因背景,不得据此恢复退役入口。当前命令、路由和 schema 以代码与 `docs/README.md` 为准。
## 2026-08-27 Provider 成功 handoff 失败时需要保留本地私有原始响应
- **现象**Provider 已返回响应,但 tool-plan handoff 因绝对路径或其它内容安全校验失败,Runtime 只留下 `failureKind`、哈希和被压平的 JSON pointer;排障时无法确认实际工具名和完整 arguments。
- **处理**:项目 `.agent`、Agent DB 和公共 event 继续只写安全摘要;额外在应用私有配置目录的 `diagnostics/provider-reconciliation/<projectHash>/<requestHash>.json` 保存本次响应、tool calls 和校验错误,供本机人工排障。该文件不参与恢复/重试、不复制到项目、不进入 Git,单文件限制 1 MiB,写入失败不改变 reconciliation 语义。
- **排查顺序**:先读 Runtime 状态里的 `localDiagnostic` 相对引用,再在应用私有目录读取诊断,核对 requestId、requestSlot、tool name 和失败 pointer;不要为了取得原文而放宽 handoff 的安全门。
## 2026-08-27 阶段判定不能在持锁的 Provider builder 中再次获取项目锁
- **现象**:GDD 修订取证阶段新增后,重新启动策划时前两步表面成功,但父 Supervisor 在收到 `project-planning` 回执、生成下一轮工具计划时失败:`项目正在被其他写操作占用:$PROJECT_ROOT\\.agent\\project.lock`
- **原因**`provider_tool_plan` 在构建请求前已持有 `.agent/project.lock``plan_root_supervisor_stage_at` 又调用会自行取锁的 Acceptance Evidence 包装入口。同一进程的文件锁不可重入,持锁调用被误判为外部竞争,等待约 10 秒后失败。问题与 Provider、代理端口或 GDD 内容无关。
- **处理**:所有需要一致快照的状态读取保留在项目锁内;阶段判定提供明确的 `*_locked` 内部入口,外层入口仅供未持锁调用方取得一次锁。Provider builder 显式接收并校验当前锁后调用 locked 阶段判定,不引入可重入锁,也不移除 Acceptance Evidence 门禁。
- **排查顺序**:先看失败 Run 的事件顺序是否为 `delegate receipt ready → 生成工具计划 → 阶段判定项目锁失败`,再检查调用方是否已持有 Provider plan project lock;不要因为错误文案包含“其他写操作”就先扩大锁等待或放宽 Provider usage。
- **验证**`cargo check``cargo fmt --check`、planning submit 68 passed、Provider request builder 17 passed;阶段测试同时覆盖未持锁包装入口和持锁 locked 入口。
## 2026-08-26 GDD 新版本提交后不能沿用“已有委派”工具面
- **现象**`plan_root_supervisor_stage_at` 只按是否存在 delivery 判定 `Delegated`。用户修订产生的新 GDD 仍未完成当前根 Run 的 `file.read → agent.acceptance_update` 取证时,模型会看到 `agent.delegate`,可能重复派发同一条策划链。
- **原因**:自然语言 playbook 已规定“证据不足先取证、用户修改后才返工”,但阶段工具白名单没有把这条 durable 状态固化。
- **处理**:阶段判定复用现有 acceptance gate 的 GDD/session/delivery/graph identity 检查,增加无副作用的 `AwaitingAcceptanceEvidence` 阶段;`PLAN_PROVIDER_USAGE_DEFERRED` 保持 fail-closed,不通过放宽 Provider 使用量门禁解决。
- **排查顺序**:先看最新 `gdd.vN.json``session.latestSubmittedRef`、delivery 是否 `ClaimedByParent`,再看 Acceptance Graph 是否 `NeedsEvidence`;若仍可见 `agent.delegate`,优先检查 plan root 阶段快照,而不是修改 acceptance gate 或 Provider 门禁。
## 2026-08-15 把校验往链路前面挪,改的不是严格程度而是作用域
- 现象:CI 全量 5 条失败,看上去毫不相干(两条 Goal 续跑停在 `needs-reconciliation`、一条交接用例断言错误文案、一条恢复用例把不可读 state 的错误抛了出来、一条 Linux-only 用例错误码对不上),实际只有 3 个根因,且三者是**同一个形状**:新增或既有的检查被放在了链路更靠前的位置,于是它的语义作用域被悄悄放大或提前,而不是「变严」。
@@ -527,6 +548,8 @@
## 后台素材查询不要用 SQL 直查 editor_asset
- 后台审核与素材查询的图片预览若要显示像素化原图,应由后台 read model 在 `sourceResourceId` 关联的项目资源上预先透传原图媒体引用,再复用管理员换签;不要让 admin-web 直接查询私有 `editor_project_resource`
- 现象:后台“素材查询”报 `HTTP 400no such table: editor_asset. If the table exists, it may be marked private.`
- 原因:`editor_asset` 是私有 SpacetimeDB 表,后台 SQL / schema HTTP 查询面看不到私有表;即使 api-server 有后台身份,也不能把私有表当 Dashboard SQL 表直接查。
- 处理:后台素材查询走 `spacetime-module` 内的 `admin_list_editor_assets_and_return` procedure,由 `spacetime-client` typed facade 调用后再在 `api-server` 映射作者展示名和陶泥号。新增类似后台只读能力时,优先补窄 procedure / read model,不要复用 `fetch_admin_dashboard_rows` 直查私有源表。
@@ -1251,7 +1274,7 @@
- 原因:邀请码流程迁移后仍按新用户窗口保留 `canShowReferralRedeemShortcut` 次级入口;但当前页面口径已经固定为五项常用功能宫格,邀请码填写应由邀请链接 query 或明确引导打开弹窗。
- 处理:移除常驻 `次级入口` / `填邀请码` 渲染,不删除 `ProfileReferralModal``redeem` 面板,也不破坏 `?inviteCode=` / `?invite_code=` 自动打开填写弹窗。
- 验证:新用户账号打开“我的”页时没有 `次级入口``填邀请码` 按钮;带 `?inviteCode=spring-2026` 的登录用户仍自动打开邀请码弹窗并预填 `SPRING2026`
- 关联:`src/components/rpg-entry/RpgEntryHomeView.tsx``.hermes/skills/genarrative-profile-invite-flow/SKILL.md`
- 关联:`src/components/rpg-entry/RpgEntryHomeView.tsx``.codex/skills/genarrative-profile-invite-flow/SKILL.md`
## 创作卡片点击要直达已有入口表单,别再保留空白入口页
@@ -1914,13 +1937,13 @@
- 验证:`npm run test -- src/components/match3d-result/Match3DResultView.test.tsx``npm run typecheck`
- 关联:`src/components/match3d-result/Match3DResultView.tsx``src/components/match3d-result/Match3DResultView.test.tsx``docs/technical/MATCH3D_DRAFT_ASSET_GENERATION_PIPELINE_2026-05-10.md`
## `.hermes` 只放共享内容,不放个人 Hermes 配置
## `.codex` 只放项目工具,不放个人 Codex 配置
- 现象:团队成员误把个人 Hermes 配置、会话或密钥复制进仓库。
- 原因:仓库 `.hermes/` 与个人 `~/.hermes/` 名称相似。
- 处理:仓库 `.hermes/` 只放 Markdown 共享记忆、计划和可公开 skills不提交 `.env``config.yaml``sessions/``auth.json`
- 验证:提交前检查 `git diff -- .hermes`,确认没有密钥、会话记录或个人路径敏感信息。
- 关联:`.hermes/README.md`
- 现象:团队成员误把个人 Codex 配置、会话或密钥复制进仓库。
- 原因:仓库 `.codex/` 与个人 `~/.codex/` 名称相似。
- 处理:仓库 `.codex/` 只放可公开 skills、插件资源、hooks 和配置模板;长期项目知识写入 `docs/project-memory/`不提交 `.env``config.toml``sessions/``auth.json`
- 验证:提交前检查 `git diff -- .codex`,确认没有密钥、会话记录或个人路径敏感信息。
- 关联:`.codex/README.md`
## 儿童动作 Demo 卡在摄像头不可用或挥手不推进先查 mocap 消费链路
@@ -3306,7 +3329,7 @@
- 原因:Vite 可能来自当前 worktree,但代理目标的 `api-server` 仍是另一个 worktree 的旧进程,或者 `api-server` 连到旧 SpacetimeDB 模块;此时 `/api/creation-entry/config` 会返回旧入口配置。
- 处理:先用 `Get-NetTCPConnection -State Listen -LocalPort 3000,8083,3103` 结合 `Get-CimInstance Win32_Process` 确认端口进程路径;停止串线的旧 `api-server`,再用当前 worktree 的 `npm run dev:spacetime -- --spacetime-port <port> --database <database>``npm run dev:api-server -- --api-port <port> --spacetime-port <port> --database <database>` 拉起同一套服务。
- 验证:`GET /api/creation-entry/config` 应包含目标入口,且监听端口的命令行都指向同一个 worktree;浏览器创作 Tab 对应分类应显示入口卡。
- 关联:`scripts/dev.mjs``.hermes/skills/genarrative-dev-stack-port-routing/SKILL.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
- 关联:`scripts/dev.mjs``.codex/skills/genarrative-dev-stack-port-routing/SKILL.md``docs/【玩法创作】平台入口与玩法链路-2026-05-15.md`
## Windows junction 工作区下 dev.mjs 直接执行入口要用 realpath 判断
@@ -3683,8 +3706,8 @@
- 现象:命令看似使用隔离 HOME / TMP、离线包管理器和不可达代理,仍能直接读取宿主用户文件、用原始 socket 联网,或由 `project.verify` 的平行 npm spawn 绕开 `command.exec` 限制。
- 原因:环境变量和 argv 白名单只约束主动配合的程序,进程组 / Job Object 主要解决生命周期;它们不建立 mount / network namespace,也不能保护 `.agent` Runtime 控制面。只包 `command.exec` 而漏掉 `command.start``project.verify` 同样属于 fail-open。
- 处理:Linux 三个入口统一使用受信任系统 bubblewrap;项目根 rw`.git / .agents / .codex / .hermes` ro`.agent` 以 000 空 mount 隐藏,项目外普通用户路径不挂载,network namespace 默认隔离,嵌套 userns 禁用。全局 namespace canary 与项目 mount preflight 都必须在 revision / processId / 目标 program 前成功;任何失败都不回退宿主执行。Windows 在等价 restricted process / AppContainer 落地前继续标记为固定命令 legacy 边界。
- 验证:不能只断言 bwrap argv。必须运行真实目标和子进程,分别检查工作区写入、宿主 sentinel、个控制目录、原始 socket、PTY stdin / graceful terminate、Runner SIGKILL 后宿主 `/proc` 无项目 cwd 进程,以及 unavailable 时 marker 为零。
- 处理:Linux 三个入口统一使用受信任系统 bubblewrap;项目根 rw`.git / .agents / .codex` ro`.agent` 以 000 空 mount 隐藏,项目外普通用户路径不挂载,network namespace 默认隔离,嵌套 userns 禁用。全局 namespace canary 与项目 mount preflight 都必须在 revision / processId / 目标 program 前成功;任何失败都不回退宿主执行。Windows 在等价 restricted process / AppContainer 落地前继续标记为固定命令 legacy 边界。
- 验证:不能只断言 bwrap argv。必须运行真实目标和子进程,分别检查工作区写入、宿主 sentinel、个控制目录、原始 socket、PTY stdin / graceful terminate、Runner SIGKILL 后宿主 `/proc` 无项目 cwd 进程,以及 unavailable 时 marker 为零。
- 关联:`apps/ai-game-creator-shell/src-tauri/src/command_sandbox.rs``command_exec.rs``process_session.rs``project.rs``docs/technical/【技术方案】AI游戏创作Agent Runtime V1.1-2026-07-12.md`
## 工具链环境根不能把整个用户目录挂进命令沙箱
@@ -4232,7 +4255,7 @@
- 原因:两个进程角色共享同一 crate、target 和可执行文件,却被错误地当成两个互不相关的 dev service。更危险的是先启动 `GENARRATIVE_PROCESS_ROLE=all` 的 API:它会立即消费外部生成队列,可能在内部 BgFilter worker 尚未 ready 时领取任务。
- 处理:`npm run dev``npm run dev:api-server` 只创建一套 Rust watcher,并把两个进程作为组合重启单元:先停止 API 与 BgFilter worker,再只让 worker 的 `cargo run` 完成必要构建,等待 worker `/readyz`,最后启动并验活 API。交互 `rs api-server``rs bgfilter-worker` 在完整栈内也必须走同一组合重启。`ProcessRole::All` 永远不内嵌 BgFilter listener;父子进程共享解析后的内部 base URL / TokenLinux 第五端口固定为端口段 `start + 4`,Windows 把第五端口纳入统一探测和漂移。
- 验证:定向测试断言组合重启顺序为“stop API → stop worker → start/ready worker → start/ready API”,`dev:api-server` 自动带起同 runner worker,端口解析得到五个互不冲突的端口;再运行 `node --check scripts/dev.mjs`、dev-stack 定向测试和编码检查。
- 关联:`scripts/dev.mjs``scripts/dev-stack-port-utils.mjs``.hermes/skills/genarrative-dev-stack-port-routing/SKILL.md``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
- 关联:`scripts/dev.mjs``scripts/dev-stack-port-utils.mjs``.codex/skills/genarrative-dev-stack-port-routing/SKILL.md``docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`
## 固定 digest 不等于每个 CI job 都要强制拉镜像
@@ -4940,6 +4963,12 @@
- 部分旧包补充:rollback 的规范图/背景图必须保存旧字节与旧 manifest entry,不能把这两项缺失隐式当成空内容;显式 `regenerate` 因此只在这两项可信可回滚时开放。历史主图集、私有回执、公开清单或 canonical 切片可以缺失,但八个严格路径与受管顶层 asset identity 必须逐项冻结其真实 `Present/Some``Missing/None` 状态,补偿也必须恢复相同存在性。不要因为旧美术包缺切片而阻断重生成,也不要把本轮新建的严格文件误记成旧文件。
- 对话扫描与 claim 补充:历史中出现 `User A / User B / Assistant B` 时,B 已回答不代表 A 已回答,扫描必须继续寻找 A。成功 Direct 回复在 Rust 返回前已经落盘,前端冗余 append 失败不能据此重跑;普通错误回复的显式落盘失败时,恢复 claim 要保持到 React fallback writer 的同一 messageId append 明确收敛。writer 成功或明确失败后才释放;失败路径要停止该消息的自动迟到重试,再由显式 `/history` 复用原 stable turn。终态后及时删除 claim,避免 Set 无界增长。
## GDD 历史审批回执误触发当前恢复提示(2026-08-27)
- 现象:修改 GDD 后新版本标题和内容已正确落盘,但审批卡一直显示“审批状态正在恢复”。
- 原因:`approval pending` 是当前 lineage 最新 GDD 的单例投影;恢复扫描却让每个历史 receipt 都拿它做 identity 比对。旧 receipt 与新 pending 不同并不表示损坏。
- 处理:历史 receipt 只修复自身投影;只有最新 GDD 的 receipt 才能校验、更新或清理当前 approval pending。不要在前端隐藏 `recoveryPending`,也不要取消最新版本的 identity fail-closed 检查。
## Native shell CI 不能在测试阶段重新解析 Cargo registry2026-08-26
- 现象:原生壳 job 的依赖预取成功后,AGC 检查仍在 `platform-llm` 测试阶段重新更新 registry index,并因 `symphonia` 下载的 TLS EOF 失败。
@@ -35,7 +35,7 @@ Genarrative / 陶泥儿当前主站聚焦图片画布创作、编辑器项目与
server-rs + Axum + SpacetimeDB
```
SpacetimeDB crate、SDK、CLI / standalone 与生成 bindings 按 `2.7.0` 对齐;官方发行包和容器镜像使用 `v2.7.0-hotfix3` 资产标签,二进制仍报告 `2.7.0`
SpacetimeDB crate、SDK、CLI / standalone 与生成 bindings 按 `2.8.3` 对齐;CLI / standalone commit 固定核对为 `8e410d2842147bd8e5a32a9589cc00c19f7478e2`,官方发行包和容器镜像使用 `v2.8.3` 标签
职责边界:
@@ -51,6 +51,7 @@ SpacetimeDB crate、SDK、CLI / standalone 与生成 bindings 按 `2.7.0` 对齐
## AGC DirectProject 与 UI workflow
- 通用 Agent Rust 分层为 `agent-runtime-core`catalog、执行生命周期、ToolHost/spawn/all-join/Provider 契约)、`agent-runtime-orchestration`(动态无环任务图、ready、依赖波次、返工下游闭包和受限自主扩图提案)与 `platform-agent` 游戏适配器;循环返工通过新 pass / epoch 表达,不在单张依赖图中建立回边。LLM 可经宿主结构化 function call 提出新增节点/边,编排层只生成经校验的新候选图,epoch 与持久化仍由宿主掌控。
- DirectProject 只连接客户端内置的 `agc_tools` STDIO MCP。它负责审核引用读取、标准美术准备、已登记资源有界查询、视频 / 角色动画 / 音效 / BGM 的 create-or-derive、已登记图片去背景、desktop/mobile 浏览器试玩和受控 `agc_web_search`;付费资源调用由客户端绑定回合、幂等账本、请求上限和投影权威。
- DirectProject 的 Codex 原生文件、搜索、命令、图片查看和 Skill 仅在真实 `game/` cwd 与 `workspaceWrite(writableRoots=[game])` 内可用;原生命令网络保持关闭。多 Agent、Apps、插件、hooks、图片生成、Goals、Workspace Dependencies、Tool Suggestion 和原生浏览器/电脑控制保持关闭。app-server 使用隔离 `CODEX_HOME`provider 凭据只由 AGC 客户端代理持有,不能进入模型上下文或 shell 环境。
- `ui-prototype`(设计图片)与 UI 编辑器 `UI` JSON 是不同资源。白名单 `ui.workflow.run` 按页面执行 `prepare → recognize → status → finalize`,由 provider-backed 识别、合并和组件绑定持久化 State/revision,并把 `reference-ready → structure-ready → merge-ready → binding-ready → application-ready → completed` 投影到 manifest。Provider 缺失、请求失败、工具缺失、结果不匹配或仍有待审节点时保留真实阶段并返回 blocker,不得用 deterministic seed 伪造完成。
@@ -4,7 +4,7 @@
- 3 名开发人员在各自环境使用本地 Agent,通过同一 Git 仓库同步代码和项目知识。
- 每个任务保持分支、工作树和修改范围清晰;多人或多 Agent 并行修改前先划分不重叠的文件边界。
- 项目知识进入 `docs/``docs/project-memory/`;个人 `~/.hermes`、Agent 会话和本地配置不共享。
- 项目知识进入 `docs/``docs/project-memory/`;个人 `~/.codex`、Agent 会话和本地配置不共享。
## 开发前
@@ -556,7 +556,7 @@ V1.11 把命令安全边界从“固定 program + argv 规则 + 隔离环境变
- `command.exec``command.start` 必须继续共用唯一 `ProjectCommandLaunchSpec``project.verify` 必须调用同一 sandbox launcher。真实 executable / argv 在该层包装为受信任系统 bubblewrap;一次性 Tokio child、PTY child wrapper、npm 验证脚本和全部后代不能有绕过该包装的生产 spawn 路径。
- bubblewrap 只允许从固定系统候选路径解析,文件必须是普通可执行文件且不能被当前普通用户写入。缺失、权限异常、namespace setup 失败或挂载失败都返回 `sandbox-unavailable` / preflight 失败;不得尝试裸 `unshare`、代理断网或无沙箱宿主执行作为 fallback。
- sandbox 使用独立 user / mount / pid / ipc / uts / cgroup / network namespace,禁用嵌套 user namespace,并启用 parent-death 收束。系统 executable / dynamic runtime 和明确工具链缓存只读挂载;规范项目根以原绝对路径读写挂载,cwd 仍必须是无 symlink / reparse point 的项目内目录。
- 项目根挂载后覆盖控制目录:`.git / .agents / .codex / .hermes` 存在时按原路径只读挂载;`.agent` 使用不可读写的空 mount 覆盖,命令不能看到 Runtime sidecar、会话、审计或配置。项目内指向外部的 symlink 因目标未挂载而不可访问。
- 项目根挂载后覆盖控制目录:`.git / .agents / .codex` 存在时按原路径只读挂载;`.agent` 使用不可读写的空 mount 覆盖,命令不能看到 Runtime sidecar、会话、审计或配置。项目内指向外部的 symlink 因目标未挂载而不可访问。
- HOME / USERPROFILE / TMP / Cargo / npm cache 使用 sandbox 内私有临时目录。允许只读复用不含凭据的工具链 source cache,但外部工具链环境根必须 canonicalize 后再次校验为与变量类型匹配的窄叶目录;`RUSTUP_HOME=$HOME``.rustup -> $HOME` 和其它宽用户目录必须失败关闭。不得挂载整个用户 HOME、AppData、SSH、云凭据、Cookie 或 Runtime 配置目录。
- 网络 namespace 默认无外部网络,HTTP(S) / ALL proxy 与离线包管理器变量只作为纵深防御。`networkAccess` 首版固定 `disabled`,模型输入不能开启;需要联网必须作为未来独立 approval escalation 设计,不能复用普通 confirm 偷渡。
@@ -572,7 +572,7 @@ V1.11 把命令安全边界从“固定 program + argv 规则 + 隔离环境变
- namespace canary 与项目 mount preflight 失败时,必须在 revision / processId 推进前返回稳定的 sandbox unavailable / setup 错误并保持项目命令未执行。当前 preflight 与随后真实 bwrap launch 是两次独立启动:真实 launch 若在目标 exec 前发生第二次 setup 失败,目标程序不会绕过沙箱执行,但尚无可信 exec-ready 握手证明失败阶段,revision 可能已经推进并按普通命令失败收束。这是 V1.11 已知残余,后续必须用 launcher 握手把“沙箱已建立且目标已 exec”与“仅准备采用沙箱”分开,不能把当前行为描述为原子保证。
- command log、terminal receipt、Agent DB 和 process record 至少记录固定 `sandboxMode=workspace-write / networkAccess=disabled / sandboxBackend=bubblewrap / sandboxProfileVersion=workspace-v1` 安全元数据,不记录 host mount source、用户 HOME、bwrap 完整 argv 或本地工具链路径。process record 使用 schema v2 持久化 launch 当时的四项元数据,poll / stdin / terminate 和旧 boot reconciliation 必须从 record / live session 读取,不能按当前平台静态猜测;旧 v1 record 只能迁移为 `legacy-unknown`。纯 preflight 失败记录 `unavailable / not-established`,不得谎报 bubblewrap 已建立。
- 确定性真实进程测试必须证明:项目内构建 / 测试 / Git 读取成功;项目外普通文件读取与写入失败;`.git / .agent / .agents / .codex / .hermes` 写入失败;网络默认不可达;shell 子进程继承同一边界;bwrap 不可用时项目命令零执行且失败关闭。`command.start` 还必须让 PTY 后代实际执行 `setsid + chdir` 后的项目外读取、控制目录写入和原始 socket 负例,并断言 process record 与每段专用审计的四项 sandbox metadata。
- 确定性真实进程测试必须证明:项目内构建 / 测试 / Git 读取成功;项目外普通文件读取与写入失败;`.git / .agent / .agents / .codex` 写入失败;网络默认不可达;shell 子进程继承同一边界;bwrap 不可用时项目命令零执行且失败关闭。`command.start` 还必须让 PTY 后代实际执行 `setsid + chdir` 后的项目外读取、控制目录写入和原始 socket 负例,并断言 process record 与每段专用审计的四项 sandbox metadata。
- deb / rpm 发布包声明 `bubblewrap` 宿主依赖;AppImage 不携带 bubblewrap sidecar,发布页和安装检查必须明确要求受支持版本的系统 `/usr/bin/bwrap``/bin/bwrap`。缺失时命令工具安全失败关闭,但该 AppImage 不算具备可用的通用开发能力。
- 真实 Provider disposable E2E 不给固定 program、文件名或工具顺序,要求模型自行发现项目技术栈,运行构建、测试和 Git 检查,并用结构化审计证明所有命令都在 workspace-write / network-disabled 下执行。上述门禁通过前不得宣称 V1.11 完成。
@@ -986,7 +986,7 @@ V1.24 修正仓库启动上下文把 `AGENTS.md` 与 README/CONTEXT 一律描述
V1.25 在 V1.24 仓库启动上下文上增加项目内 Skill catalog,但不把 Skill 正文预加载到每轮 prompt。目标是对齐 Codex 的 progressive disclosure:模型始终只看到用于触发判断的 `name / description / entryPath / contentSha256`,任务真实命中后再通过现有 `file.read` 获取 `SKILL.md` 正文,并只按正文导航读取必要 reference。Skill 是项目工作流知识,不是新工具、权限包或可执行插件。
- 发现根固定为项目内 `.codex/skills/<skill-name>/SKILL.md` 与兼容目录 `.agents/skills/<skill-name>/SKILL.md`,只接受这两个根下的直接子目录入口,不递归把 reference 中的其它 `SKILL.md` 当独立 Skill。本仓库既有规范以 `.codex/skills` 为准;同名且两处都合法时 `.codex` 胜出,删除高优先级入口后 `.agents` 才可接管。V1.25 不扫描 AppData、用户主目录、全局 Codex/Hermes 安装目录、Git submodule 外部路径或网络 marketplace。
- 发现根固定为项目内 `.codex/skills/<skill-name>/SKILL.md` 与兼容目录 `.agents/skills/<skill-name>/SKILL.md`,只接受这两个根下的直接子目录入口,不递归把 reference 中的其它 `SKILL.md` 当独立 Skill。本仓库既有规范以 `.codex/skills` 为准;同名且两处都合法时 `.codex` 胜出,删除高优先级入口后 `.agents` 才可接管。V1.25 不扫描 AppData、用户主目录、全局 Codex 安装目录、Git submodule 外部路径或网络 marketplace。
- `skill-name` 必须与目录名和 YAML frontmatter `name` 完全一致,使用 1-64 个 ASCII 小写字母、数字或单连字符,首尾必须是字母或数字;frontmatter 必须位于文件开头并提供非空字符串 `name / description`。YAML 使用结构化 parser;未知字段不产生 Runtime 能力。描述清洗凭据和绝对路径、折叠为单行并限制 2048 bytes。
- 单个 `SKILL.md` 最大 128 KiBcatalog 最多 64 项,prompt 中 Skill metadata section 最大 4 KiB。超限、解析失败、符号链接、路径不规范或读取失败的入口不进入 catalog;预算或读取导致的省略必须使 repository context 标记 `truncated=true`,不能把部分 YAML 当有效 metadata。
- 仓库启动上下文升级为 `repository-startup-context-v3`,新增有界 `skills` 列表。fingerprint 覆盖 active Skill 的规范入口路径、来源根、清洗后 name/description、清洗后完整文件 SHA-256 和截断状态;Skill 正文、metadata、优先级或入口增删发生变化时,任何受 repository context gate 保护的旧 pending action 都必须先形成 drift blocker,再在同一 run 重规划。shadowed 的低优先级同名入口不影响 active 语义。
@@ -1482,6 +1482,8 @@ npm run ai-game-creator-shell:agent-runtime:supervisor-swarm-final-reply-transie
V1.43 不放宽 V1.41 的文本型 `game-creator-provider-handoff.v1`,而是为 `requestKind=tool-plan` 增加独立私有账本 `.agent/runtime/tool-plan-handoffs/<agentKey>/<runKey>.json`schema 固定为 `game-creator-tool-plan-handoff.v1`。同一 Agent/run 账本按 `(loopIteration, repairAttempt)` 单调保存已成功的 `repair-0..N` Provider 响应,每条绑定完整 retry identity、实际物理 `providerRequestId`、真实 request slot/attempt、Provider/model、去除 thinking 后的响应、thinking 归一化哈希/计数、完整 function call envelope、usage、响应指纹和创建时间。账本使用既有 `0600`、原子替换、父目录同步、`.previous` 恢复和写后完整回读;未知字段、乱序/缺口、重复 slot 冲突、超限、危险可执行路径、密钥或配置痕迹一律失败关闭。
当成功响应因 handoff 校验失败而进入 `needs-reconciliation` 时,Runtime 额外在应用私有数据目录的 `diagnostics/provider-reconciliation/<projectHash>/<requestHash>.json` 写入一次本地诊断。该诊断只服务人工排障,不参与恢复、重试或业务状态判断,可保留本次 Provider 响应、tool call arguments 和原始校验错误;项目 `.agent`、Agent DB、公共 event、CLI 与报告只保留安全摘要及该私有诊断的相对引用。诊断文件限制为 1 MiB,使用原子写入;应用配置目录不可用或诊断写入失败时,不改变既有 fail-closed reconciliation 语义。
### 提交、重放与所有权
- 每个 tool-plan 物理请求的顺序固定为:Provider 成功 -> tool-plan handoff 追加并回读 -> 同一实际 requestId lifecycle `completed` -> 解析/格式修复或动作预检。function arguments 只存在于私有 handoff 与后续 pending/action batch。protocol/repair 公共审计共同保存 `agentId/taskId/sessionId/runId/source/loopIteration/repairAttempt/requestSlot/responseFingerprint/providerRequestIdSha256/protocol`protocol 只额外保存 `functionCallCount/callIdSha256s/functionNames/responseIdSha256/responseIdChars` 和既有 normalization 字段,其中 function names 必须由 catalog 绑定;repair 只额外保存 attempt/maxAttempts、协议错误/preview 哈希与字符数及 `callIdSha256/functionNameSha256`。公共 task、event、Agent DB、CLI 和报告不得保存原始 callId/callIds/responseId/providerRequestId。两类审计都在 Agent DB append 锁内按完整 Agent/task/Session/run/source/slot 身份做全历史 compare-and-append,不能以受限尾部读取替代幂等。
@@ -1649,6 +1651,58 @@ V1.53 把根 Project Supervisor 的 same-run steer 从“收到消息立即中
- LLM 判定、解析或持久化失败时写入关联的非终态 fallback 回复,保持当前任务运行,并在下一安全边界应用已排队 steer;失败不能退回“默认中断”。判定与回复按 `agentId / runId / steerId` 幂等,冲突终态失败关闭。
- 验收必须覆盖判定 LLM 的 `true / false` 协议、公开回复幂等、入队本身不中断、`runtime.steer` 有活动 Provider 时仍不中断、缺失 decision 拒绝条件中断、`false` decision 不中断、`true` decision 只中断旧 cursor,以及判定失败后同一 run 继续。
## V1.54 通用多 Agent DAG 编排 crate
V1.48-V1.50 已把 catalog、执行生命周期与 Provider 契约收进 `agent-runtime-core`,但动态任务图的 ready 选择、依赖波次和返工下游闭包仍编译在 `platform-agent::game_creation`。V1.54 新增独立 `server-rs/crates/agent-runtime-orchestration`package name `agent-runtime-orchestration`),作为 `agent-runtime-core` 上方的纯 Rust 编排层;它不复制 Runtime store、Runner、Provider、ToolHost、delegation journal、权限或产品持久文件。
### 图模型与无环合同
- 公共层只保存任务 ID、执行 Agent ID、通用状态和依赖边,不保存游戏组别、角色文案、产物路径、Evaluator Markdown 或中文关键词。任务在运行时注册,因此“动态 DAG”表示宿主可以按目标或 pass 动态构图与重规划,不表示依赖边可以形成环。
- 构图一次性失败关闭:拒绝空或非法 ID、重复任务、重复依赖、未知依赖、自依赖和任意有向环,并保持任务注册顺序作为所有确定性输出的稳定顺序。环内没有可证明的首个 ready 节点,也无法给 completion、重放和下游失效定义单调顺序;需要迭代时由宿主建立新的 pass / epoch,并显式携带上一轮结果,不在同一依赖图里回边。
- 编排层提供 pending ready 选择、active/satisfied 依赖波次、指定任务的下游影响闭包和全量/返工选择计划。active 任务依赖的非 active 节点必须显式位于 satisfied 集合;缺失前置不能按“图外即完成”静默放行。
- 每个任务携带 `agentId`,并可对 V1.48 `AgentCatalog` 做引用校验;未知 Agent 在创建任何 run 或调用宿主前失败关闭。crate 依赖方向固定为 `agent-runtime-orchestration -> agent-runtime-core`,依赖闭包只使用标准库与 `serde / serde_json`,不得反向依赖 AGC、Tauri、`platform-agent``platform-llm`
### AGC 生产适配与兼容
- `platform-agent` 继续拥有 16 个游戏任务、六组枚举、标题/角色/产物/验收条件、Evaluator Markdown 解析和游戏关键词路由;它把现有 `GameCreationTaskGraph` 映射为公共任务图,并由公共层计算 ready、dependency waves 和 repair downstream closure。
- `GameCreationTaskGraph``GameCreationAgentPassPlan` 的 serde 字段、种子任务、有效 DAG 的顺序与现役 `.agent/passes/pass-N/task-graph.json` 输出保持不变。构图或计划函数改为显式返回错误,非法环、未知依赖或不完整 partition 不再合并成一个伪 wave。
- AGC 的现役 Agent catalog 构造同时用公共编排层校验 16 个任务的 Agent 引用,证明新 crate 已进入生产组合根。isolated child 的项目路径、write scope、证据和深度限制仍是 AGC 工具/策略合同;通用 spawn/all-join 继续由 `agent-runtime-core` 执行,本轮不再造第二套委派协议。
### V1.54 验收
- 新 crate 的非游戏 conformance fixture 在运行时构造并行分支与汇合节点,覆盖稳定 ready 集合、依赖波次、返工下游闭包、AgentCatalog 引用,以及重复/未知/自依赖/有环/缺失 satisfied 的失败关闭;fixture 不得出现游戏任务名、AGC 路径或 Tauri 类型。
- `platform-agent` 回归锁定 16 任务种子图、首轮全量波次、结构化返工和下游扩展的现有顺序,并增加非法游戏图不会进入计划的负向用例;AGC adapter 回归锁定 catalog 与任务图一致。
- 根脚本增加 `agent-runtime-orchestration:check`,并纳入 `ai-game-creator-shell:check`。完成后至少运行新 crate、`platform-agent`、AGC adapter/生成编排定向测试、Tauri `cargo check --tests`、依赖树、`npm run check:encoding``git diff --check`;独立 crate 产生的本地 `Cargo.lock/target` 不进入提交。
### V1.54 本轮验证记录(2026-08-26
- 已通过:`agent-runtime-core` 20 项、`agent-runtime-orchestration` 5 项、`platform-agent` 19 项;新 crate 依赖树仅引入 `agent-runtime-core``serde`(测试专用 `serde_json`),`cargo fmt --check``npm run check:encoding``git diff --check` 均通过。
- 已通过:AGC 任务图与注入 `AgentCatalog` 的一致性测试、非法环失败关闭、反序列化重复依赖失败关闭;测试产生的独立 crate `Cargo.lock/target` 已清理。
- 未完成:Tauri `cargo check --tests` 已编译到 AGC 自定义 `build.rs`,随后因仓库四个候选路径均缺少内置 Codex CLI vendor 资源而退出(`build.rs:77`);本轮未执行 `npm ci`,因此不能将 Tauri 组合根或完整 `ai-game-creator-shell:check` 记为通过。
- 未执行:当前 Rust 1.96 工具链未安装 `clippy` component;没有把该静态检查结果用其它门禁结果替代。
## V1.55 运行中自主扩图提案
V1.54 的公共编排层可以在运行前构造动态 DAG,但 LLM 在执行过程中发现缺少步骤时还没有一个通用、受限的扩图入口。V1.55 在同一 `agent-runtime-orchestration` crate 增加结构化 `GraphProposal`,让宿主能够把 LLM 的 function-call arguments 解析为候选节点和边,并在不改变 `agent-runtime-core` 执行职责的前提下生成下一张图。
### 提案 DTO 与宿主边界
- `GraphProposal` 只包含 `nodes``edges`。节点使用 `{ id, agentId }`,边使用 `{ from, to }``from` 是前置任务,`to` 是依赖它的任务。DTO 使用 `camelCase` 且拒绝未知字段,节点和边的稳定标识沿用公共图模型约束。
- `TaskGraph::apply_proposal` / `expand_with_proposal` 是纯校验与候选构造 API:不调用 LLM、Provider、ToolHost、Runner 或持久化。宿主负责声明 function tool、把 arguments 反序列化为 `GraphProposal`,并在成功后把返回的候选图写入自己的新 epoch。
- 新节点统一以 `Pending` 加入,并保留现有任务状态和注册顺序。提案边必须指向本次新增节点;不允许在运行中的旧任务上原地追加前置依赖。若业务确实要改旧边,宿主应构造完整候选图并按自己的 CAS/epoch 合同一次替换。
### 原子校验与预算
- 候选图只有在所有检查通过后才返回;未知 Agent、未知端点、重复节点/边、自依赖、有向环和已有节点依赖修改都会失败,原图保持不变。
- `GraphLimits` 同时限制完整候选图的 `maxTasks``maxEdges``maxDepth`(根层计 1)和 `maxOutDegree`(一个前置任务的直接下游数)。默认值为 `128 / 512 / 32 / 32`;超限不截断、不部分提交。
- 成功扩图后,宿主必须把它视为新的 graph/epoch,重新计算 ready task 与 dependency waves,并在自己的持久层记录提案身份、基图版本和幂等结果。crate 不把 epoch、proposal ID 或执行事实写入图,也不自动重放 Provider。
### V1.55 验收
- 非游戏 conformance 覆盖有效新增节点/边、全部新节点 `Pending`、ready/wave 重算、未知 Agent、未知端点、重复边、已有任务修改、环、节点/边/深度/扇出预算和失败原子性。
- 覆盖 `GraphProposal``GraphEdge``GraphLimits``TaskGraph` 的严格 JSON round-trip;未知字段、非法标识和零预算均失败关闭。
- 真实 LLM 接入仍由宿主后续提供;本切片证明了宿主可在一个结构化 function call 回合中安全生成候选新图,但不把 provider 请求或持久化当作 crate 的事实源。
## 验收命令
- `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml structured_plan_ -- --nocapture`
@@ -1,5 +1,11 @@
# AI 游戏创作智能体 App 实施计划
## 2026-08-26 运行中自主扩图提案
- `agent-runtime-orchestration` 提供严格 serde 的 `GraphProposal``TaskProposal``GraphEdge``GraphLimits`。宿主可把 LLM function-call arguments 解析后交给 `TaskGraph::apply_proposal`,在内存中得到新的、完整校验过的候选 DAG。
- 新节点默认 `Pending`;边使用 `from`(前置)→ `to`(依赖方),且新增边只能指向本次新增节点。未知 Agent/端点、重复节点/边、自依赖、有向环和节点/边/深度/扇出预算超限整次失败,旧图不变。
- crate 不调用 Provider、Runner、ToolHost 或持久化;宿主负责 function tool 暴露、基图/epoch CAS、proposal 幂等、落盘和重新调度 ready/dependency waves。修改既有任务依赖时必须由宿主构造完整候选图并切换新 epoch。
## 2026-08-25 账户 / 项目画布 / 本地素材导入
- 素材读取区分三类来源:`asset.list` / `agc_list_registered_assets` 是当前项目本地 manifest`agc_list_project_files` / `file.list` 只发现项目目录中实际存在但可能未登记的文件,`asset.library.list` 是当前登录账号素材库,项目画布资源读取是当前网页项目/画布的完整图片清单;账户素材库不能替代项目画布清单。
@@ -50,7 +56,7 @@ Runtime 确认卡与普通聊天确认卡必须共用“信息区 + 固定操作
此 seam 的纯测试覆盖嵌套 context、offset 反算、同树重挂载、子节点页面位置保持与 Inspector anchor preset 保位;几何修复应在此 Module 局部验证后由三个 adapter 复用。
左侧 `UI Tree` 与预览画布复用同一个节点右键菜单组件和条目模型,顺序固定为“新增子节点 → 新增同级节点 → 删除节点及子节点”。页面根仅显示“新增子节点”;虚拟超级根不提供菜单。预览仅在“编辑叠加”模式中响应已渲染节点的鼠标右键,右键会选中该节点并阻止嵌套节点事件冒泡;“最终预览”以及画布空白处保留原有行为,空白处不接管浏览器原生菜单
左侧 `UI Tree` 与预览画布复用同一个节点右键菜单组件和条目模型,顺序固定为“新增子节点 → 新增同级节点 → 删除节点及子节点”。页面根仅显示“新增子节点”;虚拟超级根不提供菜单。预览仅在“编辑叠加”模式中响应已渲染节点的鼠标右键,右键会选中该节点并阻止嵌套节点事件冒泡;“最终预览”以及画布空白处不新增业务菜单。debug/dev 构建保留浏览器默认网页上下文菜单,release 客户端关闭 WebView 的默认网页菜单,但仍派发 `contextmenu` 事件给业务组件,不以停止事件传播的方式屏蔽右键交互
菜单由页面级 portal 呈现,使用屏幕坐标且在视口边缘内收,避免受预览画布缩放和容器裁切影响。点击菜单外、按 Escape、窗口失焦、滚动或调整窗口大小均关闭菜单。全局 `controller.editor.isLocked` 时,节点仍可选中和查看菜单,但所有结构修改项禁用;状态层的 mutation 校验继续作为最终防线。点击可用项先关闭菜单再执行现有 controller 动作,不改变既有新增或删除后的选择策略。
@@ -142,6 +148,7 @@ Supervisor 认领该回执后,由父 run 自己为每个原 delivery 逐一创
## 技术选择
- 桌面壳:新建 `apps/ai-game-creator-shell`,与现有 `apps/desktop-shell` 分离,避免把游戏创作本地能力塞进主站宿主壳;启动时先检查平台登录态,未登录只展示登录页,登录后进入单窗口客户端首页;正式用户窗口常驻左侧栏和顶部栏,并在首页、项目组、指南 / 反馈和项目开发页之间切换。发布和 debug 启动都只登记并打开 `client` 用户窗口;`index.html?agent-chat` 仅保留为显式前端调试路由,不是 Tauri 自动启动入口。
- 窗口外壳:`client`、动态 `main` / `launcher` / `supervisor-chat` 窗口统一关闭原生 decorations,由前端 `WindowChrome` 绘制陶泥儿品牌 Logo、当前页面 / 项目标题和最小化 / 最大化 / 关闭控制。标题栏不重复展示项目列表或本地工作区入口:首页及非项目页面的居中标题固定为“创作工作台”,打开项目后切换为当前项目名;泥点账户入口通过标题栏右侧插槽渲染,标题文本使用独立的窗口几何居中层,不参与左右入口宽度分配,项目名过长时仅在可用宽度内省略。标题栏只复用 `packages/shared/src/theme.css` 的暖陶土变量与现有产品 IP,不引入另一套主题;浏览器预览或非 Tauri 宿主中窗口控制安全降级,不能阻断页面渲染。
- 平台后端:继续使用 `server-rs + Axum + SpacetimeDB`;本地开发启动独立客户端时,`agc` / Tauri dev 会先启动或复用配套 SpacetimeDB 与 `api-server`,再启动固定端口 Vite,并通过 `/api` 代理访问实际后端端口。
- 本地能力:使用 Tauri Rust command;正式用户 App 在项目运行工作台内承载 `127.0.0.1` 本地 HTTP preview,不再调用系统外部浏览器。运行容器只接受当前授权项目由 `PreviewRegistry` 返回的 loopback URLrelease / dev CSP 都只为 `http://127.0.0.1:*` 开放 `frame-src`,并使用受限 iframe sandbox 隔离游戏脚本;远程 URL、`file://` 和任意手填地址均不得进入该容器。
- Agent Runtime:扩展 `server-rs/crates/platform-agent`,不引入 LangChain、AutoGen、Microsoft Agent Framework 或 OpenAI Agents SDK sidecar 作为核心。
@@ -196,6 +203,7 @@ Supervisor 认领该回执后,由父 run 自己为每个原 delivery 逐一创
- 模式合同:客户端 AppData 配置新增全局 `agentMode`,只接受 `codex_cli / provider`。缺省和新安装默认使用 `codex_cli`,原有 HTTP LLM Provider 路径完整保留并可显式切回 `provider`;切换只影响下一次节点请求,不新增 Runner、任务图、会话库、配置库或业务事实源。
- 调度边界:正式 DAG、manifest、Agent task/session/run 身份、队列、锁、委派、all-join、完成门、Provider lifecycle、持久 retry/handoff 与 `needs-reconciliation` 继续由现有 AGC Runtime 掌控。每个被调度节点在 `codex_cli` 模式下直接启动一次非交互 `codex exec` 充当该节点的推理 AgentCodex 返回当前 Runtime 广告函数的结构化调用,Runtime 仍是唯一 ToolHost,不允许 CLI 自己写项目、执行命令、调用 MCP 或形成第二套 revision / verification 真相。
- 安装包侧车:Windows x64 release 固定随 Tauri resource 打包 `@openai/codex@0.147.0` 的原生 `codex.exe`Rust build script 从 AGC 子包锁定依赖 stage 到 resource,并写入版本与 SHA-256 清单。Windows 侧车映射只写入 `tauri.windows.conf.json`,通用 `tauri.conf.json` 不得让 Linux / macOS 构建依赖未生成的 Windows 二进制。运行时只在文件摘要和 `codex-cli` 版本同时匹配清单时优先选内置侧车;缺失、损坏或版本漂移时跳过它,按既有 npm 安装、PATH 顺序回退。安装包同时携带 Apache-2.0 第三方声明;API Key、`auth.json`、Cookie、Token、用户 `CODEX_HOME`、用户配置和项目数据绝不打包。
- Windows x64 release 安装包只生成 NSIS,不生成 MSI:`tauri.windows.conf.json``bundle.targets` 固定为 `["nsis"]`,通用配置继续保留其它平台的默认打包目标。
- CLI 安全边界:CLI 固定使用 argv 启动,禁止 shell 拼接;工作目录使用本次请求专用的空临时目录,不把游戏项目绝对路径写入 prompt、stdout、stderr 或持久记录。调用固定使用 ephemeral、忽略用户配置和 exec rules、read-only sandbox、never approval,并关闭 Codex shell tool;只继承 CLI 运行和认证所需的最小环境,显式移除宿主 `CODEX_API_KEY`。用户级 Codex 登录态继续由本机 Codex 自己读取,API Key、auth 文件、Cookie、Token、`CODEX_HOME` 私有内容不得复制到项目配置、Runtime sidecar、Agent DB、conversation 或日志;stdout / stderr 无换行时也受硬上限约束,stderr 诊断只记录固定分类、字节数和 SHA-256。
- 协议边界:Runtime 把既有 `LlmRunRequest` 的消息和当前函数目录编码为有界 prompt,并从同一函数 JSON Schema 生成 Codex structured-output schema。CLI 输出转换为现有 `LlmRunResponse / LlmToolCall` 后,继续经过 native tool / MCP 参数校验、动作上限、权限、pending、receipt、验证与格式修复链;最终回复仍走现有脱敏和唯一提交路径,不新增平行响应协议。
- 取消与恢复:Codex 子进程绑定当前 Provider request lifecycle,取消、暂停、Runner draining 或 GUI owner 丢失时终止并回收当前进程;started 后没有可信终态仍沿现有 Provider reconciliation 处理。`agentMode`、CLI 可执行身份和影响输出的 Codex 参数进入 `providerConfigFingerprint`,模式切换不得消费另一模式遗留的 retry/handoff。
@@ -208,6 +216,7 @@ Supervisor 认领该回执后,由父 run 自己为每个原 delivery 逐一创
- 进程与节点:External Runner 按“有效 Agent LLM 凭据/Responses 路由 + `projectId/agentId/sessionId/runId`”隔离长期 `codex app-server --stdio`,即每个权威节点 run 直接持有自己的 Codex CLI 子进程与 ephemeral thread,每次完整权威请求映射 turn。同一节点 turn 串行,节点之间进程级隔离;单节点连接失败不得使其它节点同时失去终态。Codex thread 不写 durable recovery;节点完成、重启、retry、handoff 和 finalization 仍只认 AGC 账本。
- LLM 配置:`apiKind` 始终只接受 `openai_responses`;非空 Key 转换为 app-server model providerbase URL 生效,Key 仅走专用环境变量;空 Key 只桥接用户 Codex `auth.json`,不继承环境 `CODEX_API_KEY`。设置面板在 app-server 模式继续显示并保存 model、effort、stream、全局/逐 Agent Key 与路由配置;`openai_chat / anthropic` 明确提示切 `provider`,不得悄悄忽略。`stream=true` 接入 app-server 文本 delta`webSearchEnabled=true` 只允许 DirectProject 经客户端审核的 `agc_web_search` 使用,不得启用 Codex 原生 webSearch 或任意网络。
- 安全与取消:临时 cwd、隔离 `CODEX_HOME` 与 OS HOME、read-only、network off、never approval,并在启动前关闭 web/multi-agent/shell/browser/plugin/image 等原生能力;取消从 turn-start pending 阶段就跟踪且只 interrupt 当前 turn。已发送 turn 后连接断开或终态丢失进入 reconciliation,只关闭当前节点进程且不重放同一 request slot;明确 failed/interrupted 不按 transport 重试。
- remote-control 认证边界:没有 ChatGPT `auth.json` 的 API Key / provider-proxy app-server 在启动时设置 Codex 内部环境变量 `CODEX_INTERNAL_APP_SERVER_REMOTE_CONTROL_DISABLED=1`,让 remote-control 以 `desired_state=Disabled` 启动,避免上游进入 1Hz 认证重试;不再依赖需要 ChatGPT 登录态的 `remoteControl/disable` RPC。只有实际桥接 ChatGPT 登录态的 AuthBridge 保持 remote-control 可用。API Key 子进程同时使用 `RUST_LOG=warn` 收敛剩余预期噪音,不伪造 `auth.json` 或静默继续。
- 资源与退出:app-server pool 按实际凭据快照/base URL/API kind/CLI 版本和节点 run 身份隔离并做有界 LRU;空 AppData Key 必须读取同一份有界 `auth.json` 字节来生成池指纹并桥接隔离登录态,继承的 `CODEX_API_KEY` 始终移除,node thread 也只淘汰 inactive LRU。Runner 正常、强制和 watchdog 退出都显式关池,Linux child 绑定 parent-death signal,防止强杀 Runner 后遗留带凭据孤儿进程。stdout NDJSON 与 stderr 无换行记录均有硬上限;stderr 原文不写入诊断,只记录固定分类、总字节数、SHA-256 和可取得的退出状态。
- 旧配置迁移:既有 AppData 若没有 `agentMode`,只有全局和逐 Agent 路由均为 `openai_responses` 时迁移到 `codex_app_server`;存在 `openai_chat / anthropic` 时显式保留 `provider`,避免打开项目自动恢复时把所有节点批量写成 `invalid-config`。用户确认端点支持 Responses 后,可在设置中显式切换并保留原 model/base URL/API Key。
- 验收:fake JSON-RPC fixture、三态 UI/config、配置指纹、unknown-terminal 零重放、旧两种模式回归和显式 ignored 真实 smoke 全部通过后,才可视为模式切换完成。
@@ -219,7 +228,7 @@ Supervisor 认领该回执后,由父 run 自己为每个原 delivery 逐一创
- 状态询问、解释和不冲突补充默认继续当前 Provider;明确停止、改向或会让在途方案过期时才允许请求中断。判定失败时继续任务,并在下一安全边界消费消息,不得把失败等同于需要中断。
- UI 通过持久 conversation 展示关联回复,刷新后仍可见;返回的 `assistantReply / interruptDecision / decisionReason` 只用于本次命令结果与诊断,不形成第二个会话或第二个 Run。
V1.11 的受保护仓库控制目录同时包含 `.git / .agent / .agents / .codex / .hermes`;其中 `.agent` 对项目命令隐藏,其余控制目录只读。
V1.11 的受保护仓库控制目录同时包含 `.git / .agent / .agents / .codex`;其中 `.agent` 对项目命令隐藏,其余控制目录只读。
2026-08-04 起,Runtime 的公共工具规划指令、Supervisor 协作编排 playbook、条件 overlay 和编译期静态 Agent 节点目录统一由版本化 Prompt Bundle 驱动,位于 `apps/ai-game-creator-shell/src-tauri/prompts/runtime/``manifest.json` 是 section 路径、组合顺序、平台 / Editor 变体、role overlay、Provider 协作 fragment,以及 Supervisor 与六组专业 Agent 静态目录的单一来源;role overlay 只允许 `rootSourceKind` 强类型语义 selector,构建期拒绝未知 kind,运行期把权威 source 常量映射为生成 kind。`build.rs` 同时监听 Bundle 每一级目录、manifest 和已登记 section,保证任意嵌套目录新增孤立 Markdown 都会触发增量构建,并以失败关闭方式校验 schema、引用、路径 / symlink、孤立 Markdown、selector、节点身份、旧 alias 和生成标识符,再生成 `'static + Copy` Rust 定义并编译进发布二进制。公共 runtime system header 保持身份中立;生成的 Supervisor planning composition 必须复用 `supervisorChat.identity`。每个 section 只能属于 runtime composition、Supervisor composition、chat 字段、platform variant、visual variant、role overlay 或 Provider fragment 中一个语义所有者;唯一例外是同一 identity section 由 Supervisor planning 与 `supervisorChat.identity` 显式复用,从而同时阻断 Supervisor 指令外泄和动态 variant 与静态 composition 的重复注入。专业节点 taskId / group / role 还必须在构建期与 `shared-contracts::new_game_creation_app_seed_tasks()` 强一致,防止身份合同、静态目录和正式 seed DAG 漂移。Bundle 承载公共指令、隔离 Agent 合同、平台差异、角色选择、并行委派、all-join、视觉返工、claim gateSupervisor 共享核心身份、interaction / final-reply 专属合同及其组合,以及首批协作、delivery 收敛、manifest wait、试玩后续委派等 repair 自然语言合同;background planning 在 system composition 复用核心身份,所有 user context 都不再重复注入 Supervisor 身份合同正文。`agent_runtime_native_executable_tools()` 仍是原生可执行工具的权威源列表,同时供 Prompt 工具目录与 native capability registry 使用,MCP 工具只从当前请求的动态 catalog 暴露。最终 Provider 请求必须通过生成的 section、composition、overlay 与 provider fragment API 构建,禁止恢复直接 `include_str!("prompts/runtime/...")`、在 Provider 或 `prompt.rs` 源码中复制协作 graph 文案,或依赖自然语言精确 `.replace()` 注入工具合同、平台规则或角色规则。Bundle 不是完整可执行 graph:正式 DAG 依赖边、权限、沙箱、委派容量、持久 all-join 状态机、完成门和身份校验仍由 Rust、`shared-contracts` 与经校验的 `.agent/collaboration-policy.json` 强制执行,不允许通过 Skill、外部配置或任意运行时 Prompt 覆盖绕过。
@@ -237,7 +246,7 @@ Prompt 静态门禁必须断言上述 Bundle section 当前定义的权威语义
2026-07-14 V1.10 真实 `gpt-5.5` 验收:`process-session` 在无工具配方任务中完成 start / 3 次连续 cursor poll / stdin / terminate41 条 task、75 条 event、63 条 Agent DB、8 条 receipt、4 套确认生命周期和唯一 completed / assistantfixture launch 为 1,终态 PID / 端口、重放、重复与公共正文 / 密钥 / 诱饵泄漏均为 0。独立 Runner 强杀套件形成 21 条 task、34 条 event、36 条 Agent DB,新 boot 保持原 run / session,只产生 1 条 reconciliationlaunch 仍为 1、PID reconnect / final / assistant / 重放 / 泄漏均为 0;两个 disposable 项目均已清理。
2026-07-14 起,同一文档的“V1.11 OS 强制工作区沙箱与通用项目命令”替代 V1.2 / V1.10 在 Linux 上的固定 program / 严格 argv 白名单边界。`command.exec / command.start` 继续接受结构化 `program + args + cwd`、沿用 confirm policy、durable action、revision、verification、输出和进程会话协议;`project.verify` 也必须复用同一 launcher,不能保留平行的宿主 npm spawn。Linux 只在受信任系统 bubblewrap 创建的 workspace-write sandbox 内启动真实命令:项目根可写,`.git / .agents / .codex / .hermes` 只读,`.agent` 不可见且不可写,项目外普通用户文件不挂载,网络 namespace 默认隔离,所有后代继承相同边界。program 只接受无路径分隔符的裸可执行名并从受信任 PATH 解析,argv 只保留数量、长度和控制字符硬限制;允许 `bash -lc`、Git、构建器、测试器和项目脚本在沙箱内自行工作。外部工具链环境根必须 canonicalize 后校验为窄工具链目录,禁止把整个 HOME 或其符号链接目标挂入沙箱。bubblewrap 缺失、不可执行或 setup 失败必须在项目命令执行前失败关闭,不允许退回宿主全权限。process record v2 与命令审计持久化真实 launch metadata,失败不能按平台静态冒充已建立沙箱。共享 `os-workspace-sandbox` capability 只标记 LinuxWindows 首版继续使用原固定白名单、隔离环境和 Job Object,不能宣称已达到同等 OS sandbox。deb / rpm 声明 bubblewrap 依赖,AppImage 依赖宿主预装且缺失时功能失败关闭;approval 与 sandbox 仍是两层独立门禁。
2026-07-14 起,同一文档的“V1.11 OS 强制工作区沙箱与通用项目命令”替代 V1.2 / V1.10 在 Linux 上的固定 program / 严格 argv 白名单边界。`command.exec / command.start` 继续接受结构化 `program + args + cwd`、沿用 confirm policy、durable action、revision、verification、输出和进程会话协议;`project.verify` 也必须复用同一 launcher,不能保留平行的宿主 npm spawn。Linux 只在受信任系统 bubblewrap 创建的 workspace-write sandbox 内启动真实命令:项目根可写,`.git / .agents / .codex` 只读,`.agent` 不可见且不可写,项目外普通用户文件不挂载,网络 namespace 默认隔离,所有后代继承相同边界。program 只接受无路径分隔符的裸可执行名并从受信任 PATH 解析,argv 只保留数量、长度和控制字符硬限制;允许 `bash -lc`、Git、构建器、测试器和项目脚本在沙箱内自行工作。外部工具链环境根必须 canonicalize 后校验为窄工具链目录,禁止把整个 HOME 或其符号链接目标挂入沙箱。bubblewrap 缺失、不可执行或 setup 失败必须在项目命令执行前失败关闭,不允许退回宿主全权限。process record v2 与命令审计持久化真实 launch metadata,失败不能按平台静态冒充已建立沙箱。共享 `os-workspace-sandbox` capability 只标记 LinuxWindows 首版继续使用原固定白名单、隔离环境和 Job Object,不能宣称已达到同等 OS sandbox。deb / rpm 声明 bubblewrap 依赖,AppImage 依赖宿主预装且缺失时功能失败关闭;approval 与 sandbox 仍是两层独立门禁。
2026-07-14 V1.11.1 第一切片:`command.exec / project.verify` 已共用受信任 trampoline launcher。bwrap 的 `child-pid` 只推进 child-created`--block-fd` 放行后仍须收到 `SANDBOX_READY`Runtime 完成 revision / verification durable callback 后才发送 `COMMIT_EXEC`,收到 `EXEC_ESTABLISHED` 后才计算业务 timeout。当前不把这套 stdin 私有控制通道用于 PTY;`command.start` 与 process record v3 仍是下一切片,相关链路完成前 V1.11.1 保持进行中。
@@ -1175,9 +1184,9 @@ game-project/
## 2026-08-20 Direct Codex 审核 Skill Pack 与受控工具内核
- 普通项目对话只由一个 project-bound Codex app-server thread 执行。客户端系统提示词只放最小工程合同、当前游戏源码有界快照、项目 prompts 和审核 Skill 索引;不再批量读取项目 `.codex/.agents/.hermes` Skill 正文,也不恢复 Supervisor、专业 Agent 或 harness。
- 普通项目对话只由一个 project-bound Codex app-server thread 执行。客户端系统提示词只放最小工程合同、当前游戏源码有界快照、项目 prompts 和审核 Skill 索引;不再批量读取项目 `.codex/.agents` Skill 正文,也不恢复 Supervisor、专业 Agent 或 harness。
- 首页恢复“做游戏 / 做素材 / 做方案”三个创作类型,默认“做游戏”。该选择与设置页的 Agent Runtime 模式无关;每次首页提交仍只自动创建一个新项目并进入项目工作台。用户正文原样进入项目对话,`game|art|doc` 仅作为受限结构化首轮上下文传给同一 Codex thread,不拼接“初始意图”文案、不产生首页对话、不切换 Provider 或恢复旧 Runtime 编排。
- `agc-skill-pack.v1` 只包含项目结构、陶泥儿美术、Web 游戏实现、真实浏览器试玩、客户端资源投影五项 Skill。清单记录用途、触发条件、所需工具、版本和内容 SHA-256;审核文本按 UTF-8 读取并将 CRLF 规范为 LF 后计算指纹和安装,避免混合换行造成 Windows / Linux 构建结果漂移,语义内容变化时必须同步重算对应清单指纹并提升版本。客户端把审核文件安装到隔离目录后通过 app-server `skills/extraRoots/set + skills/list` 注册并复核,完整正文由 Codex 原生 Skill 机制按意图加载,一层引用只能经 `agc_read_skill_resource` 读取清单内 Markdown。引用路径按平台无关规则拒绝反斜杠、盘符、UNC、绝对路径和 `..`,不能依赖当前宿主的 `std::path` 语义判断其它平台路径。
- `agc-skill-pack.v1` 只包含项目结构、陶泥儿美术、Web 游戏实现、真实浏览器试玩、客户端资源投影五项 Skill。清单记录用途、触发条件、所需工具、版本和内容 SHA-256;审核文本按 UTF-8 读取并将 CRLF 规范为 LF 后计算指纹和安装,避免混合换行造成 Windows / Linux 构建结果漂移,语义内容变化时必须同步重算对应清单指纹并提升版本。同步统一运行 `npm run agc:skill-pack:sync`,只读校验由 AGC `typecheck` 和 release build 自动执行,发现漂移时直接列出 Skill 与实际摘要,不让失配内容进入构建产物。客户端把审核文件安装到隔离目录后通过 app-server `skills/extraRoots/set + skills/list` 注册并复核,完整正文由 Codex 原生 Skill 机制按意图加载,一层引用只能经 `agc_read_skill_resource` 读取清单内 Markdown。引用路径按平台无关规则拒绝反斜杠、盘符、UNC、绝对路径和 `..`,不能依赖当前宿主的 `std::path` 语义判断其它平台路径。
- DirectProject 只连接客户端内置的 `agc_tools` STDIO MCP,工具固定为审核引用读取、标准陶泥儿美术准备、已登记资源有界查询、视频 / 角色动画 / 音效 / BGM 的 create-or-derive 语义生成、已登记图片去背景和 desktop/mobile 浏览器试玩。MCP 进程只做协议;真实浏览器与付费 External v1 调用通过随机 loopback 地址回到客户端主进程,因此不复制 GUI 登录态、开发者 Key、项目路径、revision、operation 或幂等键到模型上下文。已登记工具固定自动批准,但付费资源工具仍由客户端绑定稳定回合身份、限制单回合请求数、串行执行并优先恢复匹配账本;通用 shell、Codex 原生 webSearch、任意网络、多 Agent、插件和外部 MCP 继续关闭。`codex_app_server` 模式要求 `llm.webSearchEnabled=false`
- 陶泥儿生成继续复用持久幂等账本、operation 恢复、来源/下载/PNG 解码和 manifest 登记;普通客户端优先使用当前 AGC 登录会话及账号路由,只有受控的 ExternalDeveloper 发布模式才在客户端内部使用按服务器 origin 隔离的私有 Key。用户和模型都不需要提供或配置 API Key;凭据失效、来源不明或结果未知时失败关闭,不能自动换 Key 或重新扣费。
- 自定义 LLM API Key 路由只在 DirectHome/DirectProject 经 loopback `/responses` 流式代理转发。代理不注入 Key,只要求请求自带 Bearer,并剥离开发网关错误携带的 `X-Codex-*` ChatGPT 账户额度头,防止隔离 app-server 把 API Provider 误判为余额 0;旧 ToolHost 保持原 Provider 行为。
@@ -1231,7 +1240,7 @@ game-project/
- 恢复扫描必须把 `resetting``compensating` 和仍带替换锚点的 `in-progress` 识别为可恢复状态,并在 Direct app-server 启动前持有同一专用执行锁完成阶段清理、补偿和中性化。补偿只恢复旧文件并清除本地 replacement CAS 锚点;已 `prepared / accepted` 的阶段账本、原 `Idempotency-Key``operationId` 必须保留,同冻结意图续跑复用原请求身份,未知账本在文件 mutation 前失败关闭。冻结意图一致但进程 invocation 已变化时允许安全接管本轮;`completed` 则以外层原始 `clientTurnId` 为权威,忽略模型重采样 brief 并等值回放。客户端必须在启动 Direct Codex 前幂等落盘原始 User 消息与稳定回合 ID;最终 assistant 回复必须在 Tauri 成功返回和 `completed` 事件前,以同一稳定回合 ID 幂等写入项目主对话,重启后项目对话只续跑真正未回答的原始回合,不能生成新身份或重复应用已完成代码修改。
- workflow 在调用严格图集事务前必须先持久化 `strictSpritesheetPending`,并冻结严格事务覆盖的九项旧合同身份:`.agent/manifest.json` 中受管 asset identity、客户端私有回执、公开 `assets/manifest.art.json`、主图集、四张 canonical 切片和公开切片清单;旧路径允许按真实状态冻结为缺失。异步 Provider 返回终态后,客户端必须先把脱敏且可恢复的完成结果绑定到原 retained stage ledger,再允许本地严格事务提交。恢复在同一项目写锁内完成底层严格事务对账与 workflow CAS;若九项新合同与当前规范图身份完整一致、规范图/背景图替换锚点属于本轮,且私有回执的 resource/asset/task identity 与本轮 retained spritesheet 完成结果一致,才保留整组新结果并补写 `completed`。若九项仍逐项精确等于冻结的旧合同,严格合同判定、写入 `compensating`、恢复规范图/背景图与登记、回读验证和清除锚点必须全部位于同一项目锁内;`compensating` 重启也必须重新验证旧合同。任一文件存在性、摘要、顶层 asset identity、retained result 或 CAS 处于第三种状态时进入本地 reconciliation,保留 workflow、阶段账本和文件现场,禁止制造新旧混合包或重新付费。恢复若只能证明完整新合同而无法重建中断前尚未持久化的阶段告警,完成结果必须追加明确恢复告警,不能用空 warning 集合伪装为原阶段没有告警。
- 工具完成结果同时返回主包 `assetPaths`、实际成功持久化的 `slicePaths`、安全身份投影 `resources`,并把普通 `warnings``sliceWarnings` 分开。每张本地切片都以真实 Canvas `resourceId / assetObjectId / taskId` 和源图集 `sourceResourceId` 登记为顶层 manifest asset;同路径替换保留本地 asset ID。严格图集事务继续覆盖主图、四张 canonical 切片、公开切片清单、私有回执和 `.agent/manifest.json`,失败时整组恢复。旧项目缺顶层切片登记时只能由客户端私有回执授权补登记;可编辑的公开切片清单不能单独成为 `.agent` Canvas 身份来源。
- `regenerate` 授权只取当前请求中最新一条原始 `role=User` 消息,并绑定外层稳定 `clientTurnId`;引号或代码中的按钮文案/示例、历史消息、模型自行填写的 `mode`、MCP 自动批准和缺失 clientTurnId 均不能形成付费替换授权。授权判定先对完整原文做 Unicode NFKC 与常见撇号规范化,随后整串必须完整匹配审核过的独立立即执行指令,只允许句号/感叹号收尾;不得剥离引号、方括号或代码片段,动作前后也不得携带 brief、条件、否定、选择、确认、费用、延迟或任意其它文本。复杂风格需求必须先在非付费消息中描述,再由下一条独立“请重新生成美术”确认消息签发授权;不能靠开放式 deny 词表猜测当前付费同意。工具桥只保留授权判定和摘要,不保存或回传用户原文。同一进程重复水合相同 `clientTurnId` 时,“回合仍在运行”只属于瞬时占用状态,前端不得以稳定 assistant messageId 将其写成终态;原执行的成功回复仍由 Tauri 在返回前持久化。DirectProject app-server 的 cwd、sandbox writable root 和文件变更批准根统一收窄到经 canonical 校验且非 symlink/reparse point 的真实 `game/`canonical 项目根的原生 OS 路径字节与权威 manifest `projectId` 通过域标签和各自长度前缀编码后共同进入 Direct 连接池和 thread 身份,稳定符号链接改指其它项目、同路径重建项目、不同非 UTF-8 路径或内嵌 NUL 的项目 ID 都不能复用旧连接。项目根、`assets/``.agent/` 不可写,网络关闭,命令执行、MCP 扩权和额外权限申请一律拒绝。受控 `agc_tools` 子进程只能从同一真实 `game/` cwd 经相同权限校验反查 canonical 项目根供客户端内部桥使用,不能把该根加入 Codex writable roots。`resources` 只返回本地 asset/path/kind/media type、Canvas project/resource/asset/task ID 与 reference resource IDs,不返回 prompt、model、provider route、绝对路径、URL、Token、Cookie 或 API Key。
- `regenerate` 授权只取当前请求中最新一条原始 `role=User` 消息,并绑定外层稳定 `clientTurnId`;引号或代码中的按钮文案/示例、历史消息、模型自行填写的 `mode`、MCP 自动批准和缺失 clientTurnId 均不能形成付费替换授权。授权判定先对完整原文做 Unicode NFKC 与常见撇号规范化,随后整串必须完整匹配审核过的独立立即执行指令,只允许句号/感叹号收尾;不得剥离引号、方括号或代码片段,动作前后也不得携带 brief、条件、否定、选择、确认、费用、延迟或任意其它文本。复杂风格需求必须先在非付费消息中描述,再由下一条独立“请重新生成美术”确认消息签发授权;不能靠开放式 deny 词表猜测当前付费同意。工具桥只保留授权判定和摘要,不保存或回传用户原文。同一进程重复水合相同 `clientTurnId` 时,“回合仍在运行”只属于瞬时占用状态,前端不得以稳定 assistant messageId 将其写成终态;原执行的成功回复仍由 Tauri 在返回前持久化。DirectProject app-server 的 cwd、sandbox writable root 和文件变更批准根统一为用户选择的整个项目根canonical 项目根的原生 OS 路径字节与权威 manifest `projectId` 通过域标签和各自长度前缀编码后共同进入 Direct 连接池和 thread 身份,稳定符号链接改指其它项目、同路径重建项目、不同非 UTF-8 路径或内嵌 NUL 的项目 ID 都不能复用旧连接。`assets/``game/` 与其它项目文件可写,`.agent/``.git/`、密钥文件和 Runtime 控制面由项目文件层拒绝,网络关闭,命令执行、MCP 扩权和额外权限申请一律拒绝。受控 `agc_tools` 子进程从同一项目根 cwd 经相同权限校验反查 canonical 项目根供客户端内部桥使用,不能把该根加入其它 Codex writable roots。`resources` 只返回本地 asset/path/kind/media type、Canvas project/resource/asset/task ID 与 reference resource IDs,不返回 prompt、model、provider route、绝对路径、URL、Token、Cookie 或 API Key。客户端付费资源生成(图片、视频、角色动画、音效、背景音乐)统一调用站内 `/api/editor/...` 路由并复用平台登录态,不走 External v1External v1 只保留给外部开发者模式和历史账本重放兼容。
- 成功响应中的 `warnings / sliceWarnings` 与错误响应采用同一脱敏边界:逐条移除宿主绝对路径、凭据与 URL,并设置固定长度上限;非阻断告警不成为绕开错误分支隐私保护的旁路。
- Direct 同进程重复水合若收到“同一 stable turn 仍在运行”,必须释放当前 App 实例的恢复 claim;该结果不落 assistant 终态,后续显式刷新对话可按原 `clientTurnId` 再次读取已落盘回复或续跑,不要求重载整个 WebView,也不启动无界自动轮询。
- 对话恢复从新到旧扫描全部合法 Direct User 回合;较新的 User 已有稳定 assistant 时必须继续寻找更早未回答回合,不能提前结束扫描。普通成功回复或普通错误回复若终态 assistant 持久化失败,同样必须释放当前 App 实例的恢复 claim,使后续显式 `/history` 能以原稳定 `clientTurnId` 重试;claim 只表示当前实例内正在恢复,不能成为磁盘终态的替代品。
@@ -1246,3 +1255,9 @@ DirectProject 使用 `approvalPolicy=never`,避免每次原生调用再经过
## 2026-08-24 AGC UI 原型桥接与自主 UI workflow
- 2026-08-24 起,`ui-prototype` 与 UI 编辑器的 `UI` JSON 资源明确分离。设计图生成后必须由白名单 `ui.workflow.run` 按页面执行 `prepare → recognize → status → finalize`:为每个功能页面创建并关联 `UI` JSON,载入页面设计图和已登记图片/图标/字体,调用 UI Editor 的 provider-backed 结构识别、多树合并与分批组件绑定,持久化 State/revision,写入 `game/` 应用标记,并把 `reference-ready → structure-ready → merge-ready → binding-ready → application-ready → completed` 各阶段的 `generationKind` 和 manifest revision 投影给客户端。Provider 未配置、请求失败、工具调用缺失、结果不匹配、未知字体引用、未产出可渲染组件或仍有待审节点时保留最近真实阶段并返回 blocker,不得使用 deterministic seed 冒充完成。工作台点击 `ui-prototype` 时通过 `ensure_ui_design_resource_for_prototype` 幂等补齐关联资源;工作流完成后自动打开首个页面的 UI 编辑器 `visual-binding` 最终阶段,交给用户检查和手动调整。只生成图片、登记空 JSON 或进入普通图片画布均不构成 UI 工作流完成,详见 [`【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md`](../【技术方案】UI工作流资源桥接与Runtime执行-2026-08-24.md)。
## 2026-08-28 AGC 自主构建 relaxed 编排覆盖
- `autonomous-game-build` 运行档位采用自主并行编排:manifest `dependencies` 仅作为上下文提示,不参与 ready 判定;代码、设计、美术、音频和发布 child 可以按调度器可用性并行启动。child 不要求固定 task ID、owner、parent-child lineage、run ID 或回执顺序,完成投影按同一项目事实幂等收束。
- 该档位不把最终验收条件提前成启动条件,也不把平台画布、preview、static smoke、发布包或其它平台产物检查作为 child 或根 Supervisor 的完成门。缺少平台产物不会把已完成任务重置为 `Pending`;根 run 只等待任务图进入终态并交回结果。
- 代码可先按约定的项目路径落地并完成自己的工作;后续任务状态变化只负责唤醒同一根 run 继续收束,不因 `art-polish``art-asset-plan` 等非代码任务失败而阻塞代码启动。平台产物和可玩性检查若需要,属于后续独立验收,不是本档位的运行前置条件。
@@ -173,7 +173,7 @@ D9/D10 描述的「manifest ready-task 调度器在 Supervisor 下游启动策
| hydrate read-model schema | `plan-gdd-state-view.v1` |
| GDD 状态 | `draft \| ready_for_approval \| revision_requested \| approved \| rejected \| superseded` |
| 单项决定状态 | `confirmed \| default_pending \| prototype_pending` |
| 回答来源 | `user_option \| user_freeform \| default` |
| 回答来源 | `user_option \| user_freeform \| user_revision \| default` |
| 审计 recordType | `agent.runtime.plan.gdd_decided` |
| planning typed 指纹文本 | `sha256-serde-json-v2:<64 位小写十六进制>` |
| 现役 action/profile binding digest | `<64 位小写十六进制>`,无前缀 |
@@ -402,7 +402,7 @@ Runtime 注入并强校验以下精确结构:
- **轮次计数与上限**:本轮是第几轮由委派链上的 `clarification_round` 派生值决定(沿 `repair_of_delegation_id` 上溯推断,见第 23.5 节),上限 3;不再由 session 自行累加 `roundsUsed`。session 仍是 decisions 数组与 GDD 草稿内容的权威,但**不再是轮次状态机的权威**。
> **随之而来的合同影响 —— 2026-08-13 已全部收口。** 第 3 节注册表的 `plan-decision-checkpoint.v1` 与 request kind、第 8.6 节 `plan-session.v1``activeQuestion` / `roundsUsed` / `supersededCheckpointHandoffs`、第 9 节的 checkpoint domain 与 `supersededCheckpointProviderRequestIds`、第 12 节的 checkpoint stale 状态机、第 14 节与 activeQuestion 相关的恢复行,均已随本节重写一并删除或改写;第 9.1 节 golden vector 已按新 identity 重新生成(3857 bytes`a59856de7e…`)。
- 用户明确输入优先于 Agent 默认;默认建议必须标为 `default_pending`,手感、节奏、镜头、可读性或重玩差异等需要验证的结论标为 `prototype_pending`
- 用户明确输入优先于 Agent 默认;默认建议必须标为 `default_pending`,手感、节奏、镜头、可读性或重玩差异等需要验证的结论标为 `prototype_pending`审批阶段的用户修改意见使用 `answerSource=user_revision``round=0`Runtime 仅在 session 带 revise/reject 的 `lastDecisionRef` 时接受该来源。
- session revision 1 由 Runtime 先写入固定 `initial-request` 决定:topic=`初始需求`、state=`confirmed`、answerSource=`user_freeform`、round=0、answerSummary 精确等于规范化后的 1400 scalar 初始用户需求。Provider 不能改写或省略这条来源记录;超过上限的初始输入先要求用户收束,不能截断。
### 5.2 决策卡
@@ -663,7 +663,7 @@ Provider 只能提交设计内容,不能提交或覆盖任何 Runtime 身份
该 input 及所有嵌套类型都使用 `deny_unknown_fields``game.platformFacts`、任意 `basis``projectId/gddId/version/submissionId/approvalRequestId`、action/run/session identity、时间与任何 fingerprint 一旦出现在 Provider input 中即返回 `PLAN_INVALID_REQUEST`。Runtime 在发出本轮 Provider request 前把当前 `sessionRevision/sessionFingerprint` 绑定进内部执行上下文,在项目锁内验证该 CAS 后,才把 project、GDD、版本、durable action、source/profile、session/run、时间、固定 `platformFacts`、全部 `basis:null` 与 fingerprint 注入 `plan-gdd.v1`。字段数量和文本限制按第 8.3 节对应 durable 字段执行。
input 中必须逐项包含并精确等于 source session 的全部 `decisionsSummary``prototypeValidationItems`,不得改变决定的 id/topic/state/answerSource/round/answerSummary,也不得改变原型项正文或顺序;每个已提问决定因此具有可验证的 1~3 轮来源。额外 decision 只允许是未提问默认:`default_pending + default + round=0`,且不能为它伪造 prototype item。唯一允许`confirmed + user_freeform + round=0` 是 Runtime 创建的固定 `initial-request`,其 answerSummary 精确等于初始用户需求。直接出稿因此可以合法使用 `roundsUsed=0`,但仍至少提交该初始 decision
input 是当前 GDD 的完整快照,不要求与 source session 的 `decisionsSummary``prototypeValidationItems` 逐项相等。审批修订可用 `user_revision + round=0` 修改、删除或新增决定;未涉及内容由 Agent 以当前 GDD 为基线保持不变。Runtime 仍校验决定结构、原型项双射、`initial-request` 首项、身份和 CAS。payload 出现 `answerSource=user_revision` 时,当前 session 的 `lastDecisionRef.action` 必须是 `revise``reject`;首次提交、澄清续跑和没有待处理用户修订的普通质量返工返回 `PLAN_INVALID_REQUEST`。用户修订周期内的质量返工可以继续携带 `user_revision`,但其 planning child 必须直接继承当前 session 的 `latestDelegationId`,不得从旧 delivery 另起分支。该闸只作用于新版本 create,同 `submissionId` replay 不重判。唯一固定`confirmed + user_freeform + round=0` 是 Runtime 创建的 `initial-request`
### 8.3 `plan-gdd.v1`
@@ -1152,15 +1152,7 @@ GDD handler 只能从已验证 batch binding 复制 `sourceSessionRevision/sourc
4. Provider transient failure/物理中断但 session、context 和 request slot 未变时,才沿用同一 base ID 的 attempt 派生规则。已知 retryable transport/upstream failure 先把旧 attempt durable 闭合为 `failed`Runner/进程恢复只有在 boot/owner/lease 证据证明旧物理请求不再存活且无 handoff/batch 时,才闭合为 `interrupted`。旧终态写入、同步并回读成功后,才能创建 attempt N+1 的新 `started`;不能原地复用同一 providerRequestId,也不能让两个 started attempt 并存。无法证明旧请求已终止时进入 recovery required,不自动重发。每个 attempt 始终有独立 `started → completed|failed|interrupted` lifecycle。
5. 除第 12 项明确允许的同 binding `started + ready batch` 崩溃组合,以及上文 delivery 问题落盘/答案绑定的已消费证明外,binding 缺失/损坏、lifecycle 与 batch 不一致、同 revision 下 requestContextFingerprint 漂移、session 不是合法 successor,或 batch 已进入执行/等待状态时返回 `PLAN_NEEDS_RECONCILIATION`。此路径不自动删除、不补默认 binding、不重绑、不重试。
严格 submit input 被 Runtime 以 `PLAN_INVALID_REQUEST``PLAN_SESSION_DECISIONS_MISMATCH`2026-08-21 补,见下)或由该输入导出的候选 GDD `PLAN_SIZE_LIMIT` 拒绝时,当前策划子 run 最多产生 **5 次** `plan.submit_gdd / rejected` observation:前 4 次关闭原 sole-action batch 后可在同一 run 续跑,让 Provider 根据最后一条 observation 修正;第 5 次仍须先完整落盘 rejected observation,再把该 run 终态失败,**不得**请求第 6 次 Provider tool-plan。该分类只针对本次 Provider input / 候选 GDD;读取既有不可变 GDD 或 receipt 时出现同名大小上限、既有 lineage 已达版本上限,或任何其它 durable authority 异常,一律是 `PLAN_NEEDS_RECONCILIATION`,不得消耗 Provider 重试额度。计数是 Runtime state 的 durable、每个 child run 独立的字段,进程重启不能清零;只有新建的策划 child run 才从 0 开始。它不依赖前端、Prompt 文字或 Provider 自报,且普通工具 observation 不计入。
**2026-08-21)台账逐项比对失败从 `PLAN_SESSION_CAS_CONFLICT` 拆出为 `PLAN_SESSION_DECISIONS_MISMATCH`,并纳入上述可重试分类。** 第 8.2 节「input 必须逐项包含并精确等于 source session 的 `decisionsSummary``prototypeValidationItems`」这条校验(实现为 `planning_submit.rs``session_decisions_match_input`)原先与三条真 CAS 判据(`sessionRevision` 溢出、session 已被其它动作推进、Runtime source revision/fingerprint 无效)共用一个错误码,因此被 `plan_submit_error_is_business_rejection` 漏掉,一次不匹配即 `needs-reconciliation` 硬阻断整个策划子 Agent。
两者性质本就不同,按本节自己的判据即可区分:真 CAS 说明 **durable 权威**已变或已坏,重交同一份 input 不可能成功;台账不匹配时权威完好,错的是**本次 Provider input**——策划子 Agent 把决策摘要抄漏、抄错,或多追加了一条非 `default_pending` 决定。后者正是本节划归「本次 Provider input / 候选 GDD」的那一类。
**不变量未放松**:不匹配照样拒绝、照样不产生任何事实,只是拒绝的后果从「叫人核对」变成「回灌 rejected observation 让 Provider 改稿」,仍受同一个 5 次 durable 预算约束,第 5 次照常终态失败。伪造用户确认(追加 `confirmed + user_option`)等第 8.2 节禁止的写法一条都没有变得可行。
**触发这次拆分的实测**:策划子 Agent 连续三次 submit 撞形状层(`PLAN_INVALID_REQUEST`),每次都按回灌的理由改对一部分——机制运转正常;第四次形状终于合法,随即撞上台账比对这一支,直接 `needs-reconciliation`,整条链路零产物收场。即**越接近提交成功越容易撞上不给重试的门**,这与「5 次预算让 Provider 自行收敛」的设计意图直接冲突。
严格 submit input 被 Runtime 以 `PLAN_INVALID_REQUEST` 或由该输入导出的候选 GDD `PLAN_SIZE_LIMIT` 拒绝时,当前策划子 run 最多产生 **5 次** `plan.submit_gdd / rejected` observation:前 4 次关闭原 sole-action batch 后可在同一 run 续跑,让 Provider 根据最后一条 observation 修正;第 5 次仍须先完整落盘 rejected observation,再把该 run 终态失败,**不得**请求第 6 次 Provider tool-plan。该分类只针对本次 Provider input / 候选 GDD;读取既有不可变 GDD 或 receipt 时出现同名大小上限、既有 lineage 已达版本上限,或任何其它 durable authority 异常,一律是 `PLAN_NEEDS_RECONCILIATION`,不得消耗 Provider 重试额度。计数是 Runtime state 的 durable、每个 child run 独立的字段,进程重启不能清零;只有新建的策划 child run 才从 0 开始。它不依赖前端、Prompt 文字或 Provider 自报,且普通工具 observation 不计入。
第 2 项的自动前滚必须与 session successor、batch supersede/cleanup 和 replacement request 的 started 写入都在项目锁内按幂等步骤恢复;任一断点重启后只能继续相同步骤。这样合法 steer 能确定性替换旧输出,而身份污染不会被“自动恢复”掩盖。
@@ -1169,7 +1161,7 @@ GDD handler 只能从已验证 batch binding 复制 `sourceSessionRevision/sourc
main loop 不能把 submit 当成普通 action dispatch:在 durable action identity 建立后、生成普通 command ID 或进入 action executor 前,必须进入 `plan.submit_gdd` 专用分支。该分支重验 exact plan identity,执行下列提交与投影。**2026-08-14 按 M1B-2 实现边界收口)** 本包只负责校验、定版、写不可变 GDD、重建 index、渲染 `game/fast_gdd.md`、安装 session successor 并终止策划子 run**不创建 `.agent/planning/pending.json` / `gdd-approval` planning pending,不创建审批卡,也不把 Supervisor 或策划子 run 投影为审批等待**。`gdd-approval` pending 与 Supervisor 等待态属于 `M1C-1`,还要受第 13.0 节 `M1C-2a` 验收取证门约束。原 submit 在进入专用分支前已经建立的 generic `game-creator-pending-action.v5` standalone pending 与 `game-creator-provider-action-batch.v4` action batch 必须原样保留,作为后续 receipt/terminal observation 的同 action 恢复锚点;GDD create 成功不等于该 action 已 observed。
1. 解析第 8.2 节 strict input;在项目锁内重读 project identity、策划子 run 与委派根身份、Provider request 所绑定的 session CAS、canonical GDD 链及原 submit 的 generic v5 standalone pending / v4 batch anchors。不信任 Provider payload 中不存在也不允许出现的版本、时间、平台事实或身份;M1B-2 不读取或创建尚未实现的 approval receipt / planning pending。
2. 验证文本上限、轮次、决定状态和 prototype item 一一对应;`decisions` 必须先逐项等于 source session 的完整决定前缀,前缀之后只允许追加 `state=default_pending + answerSource=default + round=0` 的未提问默认决定,任何伪造为用户已确认的额外决定都按 session CAS 冲突拒绝。Runtime 注入固定 platformFacts 和所有 `basis:null`,以当前 durable actionId/裸 action fingerprint 作为 submission identity。
2. 验证文本上限、轮次、决定状态和 prototype item 一一对应;`decisions` 按本次完整 GDD 快照校验,不与旧 session 内容逐项比较。`round=0` 的非首项决定只能是 `answerSource=default`(默认建议)或 `answerSource=user_revision`(审批修改),分别对应允许的状态集合。`user_revision` 还要求当前 session 已有 `lastDecisionRef.action ∈ {revise, reject}`;没有该引用时不得把未确认项标成审批修改。已有 session 创建新的 planning child 时,`repairOfDelegationId` 必须精确等于旧 session 的 `latestDelegationId`;这条 continuation 游标约束在 Provider 请求前生效,防止旧 delivery 重新成为当前分支。Runtime 注入固定 platformFacts 和所有 `basis:null`,以当前 durable actionId/裸 action fingerprint 作为 submission identity。
3. M1B-2 尚无 receipt writer:只要已有任一 GDD,新的不同 submissionId 就返回 `PLAN_PENDING_GDD_EXISTS`;同 submissionId 只允许按历史 binding replay。`M1C-1` 接入有效 approve/revise/reject receipt 后,才把边界扩为“最新版本已有 receipt 才允许下一版本”。
4. 当前 M1B-2 的首次版本固定为 1;未来版本仍只能取最后一个连续有效版本加一,范围 1~128,不允许缺号或扫描任意文件补号。
5. 新提交由 Runtime 生成并冻结 `approvalRequestId/createdAtUtc`,填充全部 durable identity、source session binding 和时间,计算 GDD fingerprint,以第 10.1 节算法 create-only 发布 `gdd.v{N}.json`。同 submissionId replay 必须先找到并严格读取既有 GDD,复用其中 Runtime 生成的版本、request/time 与 identity 后再比较,不能用新时间制造假冲突。
@@ -1449,7 +1441,6 @@ type PlanGddError = {
| 'PLAN_UNSUPPORTED_KNOWLEDGE_BASIS'
| 'PLAN_CORRUPT_AUTHORITY'
| 'PLAN_SESSION_CAS_CONFLICT'
| 'PLAN_SESSION_DECISIONS_MISMATCH'
| 'PLAN_SESSION_RECOVERY_REQUIRED'
| 'PLAN_NEEDS_RECONCILIATION'
| 'PLAN_DURABILITY_FAILED'
@@ -1,8 +1,8 @@
# 【技术说明】AGC 接第三方 Provider 的兼容性缺陷
- 首次记录:2026-08-19
- 最新核对:2026-08-25,当前实现仍保留本文所述 Provider 分发约束
- 结论:**这不是单一策划链路的问题**。各创作流程共用同一套 Provider 分发;第三方端点必须满足当前 `agentMode``apiKind` 和工具调用协议约束。缺陷 4 已修复其余限制仍按本文处理。
- 最新核对:2026-08-27,当前实现仍保留本文所述 Provider 分发约束
- 结论:**这不是单一策划链路的问题**。各创作流程共用同一套 Provider 分发;第三方端点必须满足当前 `agentMode``apiKind` 和工具调用协议约束。缺陷 4 已修复`llm.stream=true` 时 Provider tool-plan 现在按配置发送流式请求并在后端聚合完整响应,前端展示合同不变。其余限制仍按本文处理。
---
@@ -14,6 +14,7 @@
| 2 | `codex_app_server` 模式把第三方端点喂给 codex | apiKind≠openai_responses 时秒挂;否则 413 + 工具误用,180 秒超时后留下待核对的孤儿请求 | 模式前提未被约束 |
| 3 | `provider` 模式下 `tool_choice=required` 与 DeepSeek 思考模式互斥 | 首个 tool-plan 请求 400,整个 runtime 起不来 | 参数空间缺一个值 |
| 4 | 普通 action 批次带 plan update 时,两条预检规则互斥 | 「更新计划 + 委派专业 Agent」同一轮返回就报「批次成员身份或顺序不匹配」 | **本分支回归**(已修) |
| 5 | `llm.stream` 只记录配置,不驱动 Provider tool-plan 传输 | 要求 `stream=true` 的网关第一发 tool-plan 得到 HTTP 400,整轮不可用 | 传输配置失效(已修) |
缺陷 1~3 叠加的结果:**当前代码里没有任何一组配置能让 DeepSeek 跑起来**。缺陷 4 与 provider 无关,换成 `gpt-5.6-terra` 打通 LLM 链路后才暴露出来。
@@ -291,3 +292,26 @@ let expected_member_plan_update = batch
- DeepSeek 网关 413 的具体阈值,以及 `provider` 模式下 AGC 自组的请求体是否也会触顶。
---
## 9. 缺陷 5`llm.stream` 未作用于 Provider tool-plan(已修)
### 现象
`agentMode=provider``llm.stream=true` 时,审计与重试指纹记录 `stream=true`,但首个 tool-plan 仍调用 `LlmClient::run()`,请求体实际为 `stream=false`。只接受流式请求的 OpenAI 兼容网关返回 HTTP 400 `Stream must be set to true`;由于这是本地请求构造错误,重试同一请求无法恢复。
### 修复边界
Provider 的持久化重试分发与常规重试分发统一按 `llm.stream` 选择 `stream_run()` / `run()``stream_run()` 负责聚合文本、工具调用与终态,tool-plan 仍在响应完整后按现有协议解析、校验和交接;不把半截 tool-call 参数发布给前端,也不改变最终回复的 response-stream 合同。
### 回归
- `response_stream_uses_distinct_streamed_final_reply_for_responses_and_chat`:覆盖 Responses / Chat 两种 wire 的 tool-plan 与 final-reply 请求均发送 `stream=true`
- `response_stream_disabled_keeps_direct_planning_reply_to_one_request`:覆盖 `llm.stream=false` 时 tool-plan 仍发送 `stream=false` 且保持单请求直接收束。
- `background_agent_runtime_executes_streamed_native_function_tool_plan`:覆盖 Anthropic tool-use 分片在 Shell Runtime 中聚合为原生工具动作,并完成 tool-plan 协议审计与动作执行。
- `platform-llm` 既有 Chat / Responses 流式工具调用聚合用例继续覆盖分片工具参数装配。
### 升级边界
升级前遗留的 durable retry sidecar 若是在旧实现(审计记录 `stream=true`、实际发送 `stream=false`)期间创建,升级恢复后会按当前配置真实发送流式请求。该行为修正了配置与 wire 行为的一致性,但不保证与升级前已发出的失败请求字节一致;排查跨版本恢复时以 raw failure log 的请求快照为准。
---
@@ -24,7 +24,7 @@
- `docs/`:当前 PRD、架构、开发运维、设计和测试口径。
- `docs/project-memory/shared-memory/`:长期团队记忆、决策、流程和踩坑摘要。
- `.hermes/`Hermes 工具资源,不作为项目知识库。
- `.codex/`Codex 工具资源,不作为项目知识库。
- `.codex/skills/`:Codex 可复用技能;只在任务命中时读取。
- `scripts/rag/`:Agent 本地检索入口,只提供候选上下文。
@@ -73,11 +73,11 @@ RAG 默认不安装运行时依赖,也不把 LanceDB、Transformers.js 或本
## SpacetimeDB 规则
涉及 SpacetimeDB 设计、实现、脚本、调试、发布、绑定生成、schema、reducer、procedure、view 或 Rust API 时,先读取对应 skill
涉及 SpacetimeDB 设计、实现、脚本、调试、发布、绑定生成、schema、reducer、procedure、view 或 API 时,先读取项目适配 skill
- `.codex/skills/spacetimedb-cli/SKILL.md`
- `.codex/skills/spacetimedb-rust/SKILL.md`
- `.codex/skills/spacetimedb-concepts/SKILL.md`
- `.codex/skills/genarrative-spacetimedb/SKILL.md`
该 skill 按任务范围路由到官方 SpacetimeDB 插件的 `spacetimedb:concepts``spacetimedb:rust-server``spacetimedb:cli``spacetimedb:typescript-client``spacetimedb:mcp` skill;项目边界覆盖插件通用示例。插件缺失时按项目 skill 中的安装命令补齐,个人插件配置、缓存和凭据不得进入仓库。
已有表新增字段时,字段必须放在 Rust 表结构体最后,并设置明确默认值。删除、改名、重排或改类型前必须先询问用户并确认迁移计划。
@@ -93,8 +93,8 @@ RAG 默认不安装运行时依赖,也不把 LanceDB、Transformers.js 或本
## 技能路由
- 新增、补齐、迁移或重构玩法入口、玩法类型、创作工作台、生成页、结果页、发布、运行态、作品架、广场或公开 read model:读取 `.codex/skills/genarrative-play-type-integration/SKILL.md`
- 本地 dev 端口、代理目标、端口漂移、SpacetimeDB publish server、api-server 环境变量、Vite 代理和后台 dev 串联:读取 `.hermes/skills/genarrative-dev-stack-port-routing/SKILL.md`
- 仓库级 Hermes skills/plugins:先读 `.hermes/README.md`,只把 `.hermes/` 当工具目录。
- 本地 dev 端口、代理目标、端口漂移、SpacetimeDB publish server、api-server 环境变量、Vite 代理和后台 dev 串联:读取 `.codex/skills/genarrative-dev-stack-port-routing/SKILL.md`
- 仓库级 Codex skills/plugins:先读 `.codex/README.md`,只把 `.codex/` 当工具目录。
## Issue 与提交
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -119,7 +119,7 @@ server-rs + Axum + SpacetimeDB
- Issue tracker 是自托管 Gitea。可用 Gitea UI/API 或 `tea` CLI;不要用 GitHub `gh` 或 GitLab `glab`
- 默认 triage labels`needs-triage``needs-info``ready-for-agent``ready-for-human``wontfix`
-`CONTEXT.md` 是当前领域语言入口;架构决策以本文档和 `docs/project-memory/shared-memory/decision-log.md` 的最新稳定摘要为准。
- `.hermes/` 只保存 Hermes 专用的仓库级工具资源,例如 skills、plugins 和启用说明;团队共享记忆、计划和 TODO 统一放在 `docs/project-memory/`,不提交个人 Hermes 配置、会话、密钥、Token 或本地私密路径。
- `.codex/` 只保存仓库级 Codex 工具资源,例如 skills、plugins、hooks 和配置模板;团队共享记忆、计划和 TODO 统一放在 `docs/project-memory/`,不提交个人 Codex 配置、会话、密钥、Token 或本地私密路径。
- 每次工程修改都应同步更新本目录当前文档;如果产生长期有效知识,再同步 `docs/project-memory/shared-memory/`
## 当前文档策略