--brief-file 容大段富化设计稿(避 argv 长度/引号坑;U3 Java shell-out 复用),design+saa 双模式生效。plan 已折叠两轮 Codex+Opus 双评审。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
20 KiB
topic, type, status, date, owner, origin, decisions, review
| topic | type | status | date | owner | origin | decisions | review | |||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| SAA 生成主线 → A-model · 执行版 v2(集成 C:复用 harness 生成内核 · shell-out 混合) | execution | draft v3(已折叠两轮 Codex+Opus 双评审 2026-06-21;待创始人收口批准 → 才进 Phase 1 实现) | 2026-06-21 | Mac 开发执行线 |
|
|
Codex+Opus 两轮对抗式双评审已折叠(§0 第一轮 / §0b 第二轮) |
SAA → A-model · 执行版 v2(集成 C)
0. 双评审折叠摘要(§6.8;gate 工作正常)
被验证的 = harness 的 agentic 生成内核(M3 read skill/api/范例→写多文件 src/→自 check/build,3/3 玩法实证);未被验证、属本期净新增的 = SAA↔harness 集成层(SAA-mode CLI / 产物落点 / boot 信封 / repair / Java runner / 预算)。v1 把后者措辞成"直接复用已验证 harness"——已纠正。
| # | 评审发现 | 严重 | 折叠处置 |
|---|---|---|---|
| B1 | harness 写 games/amgen-<id>/,SAA play/emit/giveup 硬读 games/_wg1-gen/<gameId>/(SaaGenNodes.java:476、SaaStudioNodes.java:1111/1162)→ 必挂 |
BLOCKER | §2:harness 在 amgen 工作(3-up,agent 友好)后stage 自包含产物到 _wg1-gen/<gameId>/(bundle/index/play-spec/sourceArtifact);src/ 留 amgen 供 repair。不改 SAA 读盘契约 |
| B2 | 不只全局名——SAA 页面调 __GameBundle.bootGameHost(),_template 导出 TemplateGame.bootGame();改全局名不够 |
BLOCKER | §2:SAA-mode entry 导出 bootGameHost(opts)(适配 bootGame)+ 全局 __GameBundle + __genBooted 标记 + SAA index 模板;validate 断言 __GameBundle.bootGameHost 存在 |
| B3 | Phase 3 先删 factory/gamedef + 收 saaSourceMode 为 amodel-only;Phase 4 又要"≥60% 才 cutover、可回 factory"——自相矛盾,无 fallback 与数据门冲突 | BLOCKER | §4 重排:Phase 3 不删任何不可逆物(只 dead-link/brand 预清 + amodel 硬化门);factory/gamedef 删除移到 Phase 4 数据门通过之后。回滚:删前=flag;删本身=revert tag(D1=A 无 flag 回退) |
| H1+H2 | 双重 play(harness 内已 play + SAA play 节点);spike 3/3 用 harness 弱判据(booted&&framesAdvanced)≠ SAA objective A–E 口径 → "Phase0 过→删 factory"逻辑断层 | HIGH | §2:生产 harness --no-play,SAA 九门 = 唯一权威门;§7:Phase 3 加前置硬门"amodel 产物过 SAA objective A–E + e2e trace generate→play→emit 无断裂",把"spike 3/3"硬化为"SAA-objective 达标" |
| H3 | 信封三方漂移:TemplateGame(harness)/ __GameBundle(SAA)/ __AModelGame(设计文档 §0.2!);牵动 4 harness 文件 + SAA emit |
HIGH | §2 + §10 TODO:先统一信封命名(杀掉设计文档的 __AModelGame);Phase 2 改 _template→SAA 变体(entry/index/tools.check/play/prompt 5 处)对齐 __GameBundle.bootGameHost |
| C-HIGH | Phase 3 删 contracts/agent-loop/ 会删掉 Phase 1 刚升级的活契约 source-project.schema.json |
HIGH | §4 Phase 3:删除精确到文件;保留 source-project/verdict/game-design schema + skeletons;只删 Dify workflow 死物 |
| C-HIGH | 现 runProcess redirectErrorStream(true) 合并 stdout/stderr,与"stdout 末行 JSON"契约冲突 |
HIGH | §5 + §10 TODO:为 gen.mjs 建专用 runner(分流 stdout/stderr,只解析 stdout 末行单行 JSON,stderr tail 回 repair) |
| C-HIGH | --repair 要在既有 game 上改,但 gen.mjs 每次 scaffold() 先 rmSync 删目录 |
HIGH | §2/§6:--repair 绕过 fresh scaffold,读既有 amgen/src + 注入 feedback,成功覆盖同目录并留失败证据 |
| C-HIGH | generate 600s = taskBudgetSeconds=600,deadline 未入图,validate/play/repair 无剩余预算 | HIGH | §6 + §10 TODO:deadline 入 graph state;generate 单步子预算(~400s),全链覆盖 |
| O-H4a | Phase 2 要改的 SaaGenNodes/SaaStudioNodes 带 @author 造梦AI → 一碰品牌门红 |
HIGH | §4 Phase 3:加"清被触碰文件的品牌残留" |
| O-H4b | escalate 是真 stage2 模型切换(SaaStudioNodes.java:696,739 + SaaStudioGraph 路由 503/508);M3-only 下"留壳"是真改动 | HIGH | §6 + §10 TODO:定 escalate 代码级处置(改节点体≈repair 保路由,或从三处条件边 Map 移除) |
| C-M / O-M | Phase 3 漏 Java 测试层(SaaFullGraphE2eTest/SaaAnthropicAssembleTest/SaaHistoryFidelityTest/gamedef briefs);透传壳=死代码;checkpoint/observation 在 shell-out 黑盒降级;并发撞端口 | MEDIUM | §4 加 Java 测试迁移清单;§2 validate/scaffold/build amodel 短路非透传;§9 承认 observation 降级;§6 端口/目录隔离规则 |
| nit | AGENTS 引用应为"§6 第10条/engineering-conventions §10";spike 证据未入仓;schema 非纯 additive(additionalProperties:false 需下沉) | NIT | 全文引用订正;§10 TODO 归档 spike 证据;§4 Phase1 标注 oneOf 重构 |
0b. 第二轮复评折叠(v2→v3;§6.8 第二轮)
两位评审用了不同镜头,先对账:Opus 评 spec 质量(折叠是否真落在文档 + 自洽)→ 判 11/14 真落地、B3/H2 真修(H2 更被加固:spike 的 boot 信封
__gameBooted与生产__GameBundle.bootGameHost/__genBooted物理不同 → spike"3/3 能跑"从未走生产 boot 路 → SAA-objective 重证是真证据缺口非洁癖)。Codex 评代码状态(修复是否已在码上)→ 多判"未修"——这是预期:本文件是计划,代码改动 = Phase 2 执行本身,现在码上当然未改。两镜头都对:spec 方案成立(Opus),实现待 Phase 2(Codex)。两轮均未推翻集成 C / 路径 stage / 阶段重排。
v3 真增量(两轮新发现,已折叠;下列处置点对应正文 §,且 supersede v2 相应行):
| 来源 | 发现 | v3 处置 |
|---|---|---|
| Opus HIGH-1 | --no-play 扔掉了 spike 本有的同进程廉价 boot 检(play.mjs:125+),使"generate 判成功"前移到 boot 之前 → boot-only 失败(运行期 throw / wiring 错 / 插件方法 undefined / bootGameHost adapter bug)穿透 validate(字符串检)+短路+asset,直到 SAA play(独立进程九门)才暴露,整轮算力不可回收 |
§2:--no-play 保留同进程 cheap smoke-boot(复用 play.mjs 的 boot+1 帧,丢九门/截图)作为 harness done 门一部分回吐 ok;boot 失败挡在 generate 节点内。SAA 九门仍是唯一质量/好玩权威门 |
| Opus MED-2 | budget 病因错置:无 taskBudgetSeconds,600 是 LLM_TIMEOUT_SECS(单次 LLM 读超时,SaaStudioNodes:173);真实约束=generate 整轮(13–22 步)墙钟无上限(仅 dispatcher watchdog 兜底) |
§6:整改改为"graph state 引入整轮 deadline + generate 自身墙钟上限",非"切 600s 子预算" |
| Opus MED-3 | harness 只落文本 run-log.txt,generate 内 13–22 步对 SAA observation 不可见 → 线上排障违 §6.5 可追溯 |
§9 RC5:harness 回吐结构化(机读)trace(每步 tool/check/build 结果 JSON)给 SAA,至少 generate 内结构化里程碑 |
| Codex 新 | stage 契约未闭合:play-spec.json 现由 SAA state 产(SaaGraphDispatcher:493),非 harness;无 sourceArtifact.json 消费链(消费的是 game_source_project/sourceProject) |
§2:stage 契约明确生产者/消费者——play-spec 仍 SAA 产(harness 不产);harness 多文件源映射既有 game_source_project(不新造 sourceArtifact.json 消费链) |
| Codex 新 | escalate 改节点体等价 repair 破坏救场阶梯:路由仍 escalate→generate(SaaStudioGraph:490),靠 modelTier=stage2 跳窗;只改节点体不同步 router/计数/事件 → 反复命中 escalate 或丢 giveup 阶梯 |
§6:escalate 处置纠正——不动节点角色/路由/计数/giveup 阶梯,仅把 escalate 的 stage2 模型解析在 M3-only 下回落到 M3 + thinking/温度升档,保 stage2 事件/计数/跳窗语义不变 |
| Opus | Phase 1 asset 抽取改源是唯一非加性风险 | §4 Phase1:asset 改动只走 amodel 分支,factory 路 asset 读取字节不变 |
| Codex 新 | Phase4 删除清单需机器可 grep 清单(prompt 历史路/skeleton/测试 flags/resources),非自然语言 | §10:Phase4 删除前产 rg 清单 + 迁移目标(收口前 TODO) |
| Opus/Codex | spike 证据未入仓(D1=A 押注闸不可审计);Phase3 硬门未标样本量;stage 非原子 + amgen 清理 | §6/§10:spike 证据前置 Phase2 前入仓;Phase3 硬门标样本量;stage 原子(写 tmp→rename) + emit 后 amgen 清理 |
1. 目标 + 范围边界
- 目标:SAA 生成产物 = A-model 多文件
src/工程;generate 复用 harness 的 agentic 生成内核(已验证),SAA-mode 集成层为本期净新增;保留 SAA play 客观九门(A–E)/ player / nreview / emit / checkpoint / repair;A-model 证明达标后退役 factory + gamedef(D1=A 终态无 fallback);切 stagingdispatcher=saa(D6=A)。 - 范围内:
game-cloud/.../saa/(generate/validate/repair amodel 分支 + 专用 runner + deadline + properties flag)·game-runtime/tools/amodel-gen/(harness 加 SAA-mode + 信封对齐 + stage + repair)·contracts/agent-loop/source-project.schema.json(oneOf 升级)· 删除(Phase 4 后)· staging cutover。 - 范围外(零改):
__GameBundleiife 产物契约 · emit→GamePackage→落库→回调/HMAC ·build.mjs·boot-game-host.js核心 · 下游 studio/feed。
2. 集成架构(C,已据 B1/B2/H1/H3/M2 重定)
render → classify → design(玩法设计 + 插件清单 + assetSpec)
→ generate[amodel]:专用 runner → `node gen.mjs --mode saa --game-id <gameId> --brief <json>`
harness:scaffold amgen-<gameId>/(3-up,agent 友好)→ ReAct(M3,自 check/build,**--no-play 但保留同进程 cheap smoke-boot**:boot+1 帧验起来、丢九门/截图,回吐 done 门)
→ **stage 自包含产物到 games/_wg1-gen/<gameId>/**:bundle.iife.js + SAA-index.html(**play-spec.json 仍由 SAA 产、非 harness**;harness 多文件源 → 既有 `game_source_project`,不新造 sourceArtifact 消费链)
→ stdout 末行 JSON {ok, gameId, fail?}
→ validate[amodel]:轻断言(_wg1-gen/<gameId>/bundle.iife.js 存在 + **__GameBundle.bootGameHost 存在** + sourceArtifact 合 schema 2.0)
→ (scaffold/build:amodel 路**拓扑短路**,generate 直连 asset;不留透传死壳)
→ asset:从 design assetSpec 抽取(无资产走程序化兜底)
→ play:**SAA 九门 A–E 客观门复用,唯一权威 play**(读 _wg1-gen/<gameId>/,因 harness 已 stage → 不再断裂)
→ player / nreview → emit(读 _wg1-gen/<gameId>/bundle.iife.js → __GameBundle → GamePackage,零改)
↑ repair[amodel]:play/validate fail → `gen.mjs --mode saa --repair --game-id <gameId> --feedback <guards摘要>`
(**绕过 fresh scaffold**,读既有 amgen-<gameId>/src + 注入 feedback 再 ReAct,重 stage)
↑ escalate:见 §6(M3-only 处置)
boot 信封(B2/H3):SAA-mode entry 导出 bootGameHost(opts)(内部适配现 bootGame)+ 打包 --global-name=__GameBundle + 置 __genBooted/__genBootError/__gameState 标记 + 用 SAA index.template.html(调 __GameBundle.bootGameHost)。与 spike 的 TemplateGame/bootGame/__gameBooted 信封并存但物理隔离(SAA-mode 专一套)。
产物落点(B1):harness 在 amgen-<gameId>/ 生成+构建(保 3-up,agent import 与 catch-fruit 范例一致),再把自包含 iife + SAA-index 原子(写 tmp→rename) stage 到 _wg1-gen/<gameId>/(SAA play/emit 既有读盘契约,零改 Java 读路径;play-spec.json 仍 SAA 产)。src/ 多文件留 amgen 供 repair + 序列化进既有 game_source_project;emit 成功后清 amgen-(防磁盘累积)。
3. 前置
- Phase 0 spike 已过(✓ commit
6e388d9b)——但仅证生成内核,集成层未证(见 §0)。 - SAA 部署 app 宿主有 node22 + game-runtime + new-api 可达(D6 已验 mini)。
- new-api key:SAA 进程 env(
AigcExecutorProperties.apiKey)透传给 gen.mjs。
4. 阶段执行(已据 B3 重排:不可逆删除后置到数据门后)
Phase 1 · 契约先行(治 M1 + C-HIGH 活契约 + N3)
contracts/agent-loop/source-project.schema.json顶层改 oneOf 判别式(非纯 additive:现additionalProperties:false+ 顶层 required 须下沉到 1.0 分支):1.0=gamedef legacy 冻结只读 /2.0=A-model{schemaVersion,files:{<relpath>:<content>},entry,globalName:"__GameBundle",plugins[]}。按 schemaVersion 分支,不破 1.0 读者。- asset 抽取改从 design assetSpec(不依赖 gameDefinition 子树)——只走 amodel 分支,factory 路 asset 读取字节不变(Opus 实证:这是 Phase 1 唯一非加性风险点,必须隔离)。
- 保留 agent-loop 活契约(source-project/verdict/game-design + skeletons);不在此期删任何 contracts。
Phase 2 · 接 harness(flag saaSourceMode=amodel 真分支;factory 仍默认)
harness(game-runtime/tools/amodel-gen/):① --mode saa(--no-play + stage 到 _wg1-gen + stdout 末行 JSON);② 信封对齐(SAA-mode entry 出 bootGameHost/__GameBundle/__genBooted + SAA index);③ --repair(绕 scaffold,既有 src + feedback);④ 产 sourceArtifact schema 2.0;⑤ 信封命名统一(消除设计文档 __AModelGame,见 §10)。
SAA(game-cloud/.../saa/):AigcExecutorProperties.saaSourceMode 加 amodel(Codex②:配真分支防 fall-through);generate amodel 分支用专用 runner(分流 stdout/stderr,解析末行 JSON;deadline 子预算 ~400s)→ shell gen.mjs;validate amodel 轻断言;repair amodel→ shell --repair;design 产 brief+插件清单+assetSpec;dispatcher 组装 brief。scaffold/build amodel 路拓扑短路。
Phase 3 · 预清理 + amodel 硬化门(无不可逆删除;治 B3/H2/H4a)
- 不删 factory/gamedef(留默认 + 回退锚)。
- dead-link 预清 + 清被 Phase 2 触碰文件的
@author 造梦AI品牌残留(SaaGenNodes/SaaStudioNodes)。 - 前置硬门(把 spike 口径升级到生产口径):amodel 产物经 SAA 九门 objective A–E 达标 + e2e trace generate→play→emit 全程无断裂(验 B1/B2 落点+信封真通)。不过此门 → 不进 Phase 4。
Phase 4 · cutover + 删除(数据门控;治 B3)
- amodel 灰度 objective A–E ≥ 60%(同 factory 口径,SAA play 测) → ① 切 staging
dispatcher=saa+ smoke ② flip 默认到 amodel ③ 此后才删 factory/gamedef:gd-runtime.js/build-from-source.mjs(+test)/GAMEDEF_SYSTEM/buildGameDefMessages/factorySYSTEM/buildRegenerateMessages/SaaSkeletons/sourceMode 旧枚举 + Java 测试迁移(SaaFullGraphE2eTest/SaaAnthropicAssembleTest/SaaHistoryFidelityTest 改 amodel 口径 / gamedef briefs 退役)+ Python worker(D6)+ Dify 死契约 + 防死链门。删前打 tag。 - 不达标不 cutover、不删。
5. 接口 / 数据契约(均标"现状")
| 契约 | 定义 | 现状 |
|---|---|---|
| SAA↔harness CLI | gen.mjs --mode saa --game-id <id> --brief <jsonOrFile> [--repair --feedback <text>] [--max-steps N];env NEWAPI_KEY;stdout 末行单行 JSON {ok, gameId, fail?} + exit code |
spike 不含,Phase 2 净新增 |
| 专用 runner | Java 侧分流 stdout/stderr,只取 stdout 末行 JSON,stderr tail 回 repair(不复用 redirectErrorStream 合并 runner) | Phase 2 新建(跨文档 §10) |
| boot 信封 | __GameBundle.bootGameHost(opts) + __genBooted/__genBootError/__gameState |
spike 是 TemplateGame/bootGame/__gameBooted;Phase 2 ② 出 SAA 变体 |
| 产物落点 | harness stage _wg1-gen/<gameId>/{bundle.iife.js,index.html,play-spec.json,sourceArtifact.json} |
Phase 2 新增 stage 步 |
| 源工件 schema 2.0 | game_source_project 存多文件 A-model 工件 |
Phase 1 定义 |
| 产物契约(零改) | __GameBundle iife → emit → GamePackage → 落库/回调 |
不变 |
6. 边界 / 失败路径
- harness shell 失败(exit≠0/超时/stdout 无合法末行 JSON)→ generate fail → repair(stderr tail 摘要)→ 耗尽 → giveup(dump)。
- repair 绕 scaffold:读既有 amgen-/src + play guards feedback → ReAct 定向修 → 重 stage;保失败版证据。
- deadline(病因已纠:无
taskBudgetSeconds;600 = 单次 LLM 读超时LLM_TIMEOUT_SECS):真实约束 = generate 整轮(13–22 步)墙钟无上限(仅 watchdog 兜底)。整改 = graph state 引入整轮 deadline + generate 自身墙钟上限(进 generate/repair/play 前检剩余),非"切 600s 子预算"。 - escalate(M3-only;纠 v2 naive):不动节点角色/路由/计数/giveup 阶梯(改语义会破坏救场阶梯,Codex 实证 SaaStudioGraph:490);仅把 escalate 的 stage2 模型解析在 M3-only 下回落到 M3 + thinking/温度升档,保 stage2 事件/计数/跳窗语义不变。
- 端口/目录隔离(M1):amodel harness
--no-play不占 CDP 端口;run 目录amgen-<gameId>(gameId 唯一);saaConcurrency保持 1 直到隔离方案(port=base+hash)落地。
7. 验证 + 完成条件
- Phase 1:schema oneOf,1.0 读者全绿;契约门通过。
- Phase 2:
SaaFullGraphE2eTest(saaSourceMode=amodel)在 mini 产多文件 + e2e trace generate→stage→play→emit 全通(验 B1/B2);validate 红线拦非法(非默认导出/引擎 import/插件键名/无 __GameBundle.bootGameHost);repair 可在 play-fail 后定向修复再过。 - Phase 3 前置硬门:amodel 过 SAA objective A–E(非 harness 弱判据)+ trace 无断裂。这是 D1=A 不可逆删除的真实放行证据(取代"spike 3/3")。
- Phase 4:amodel 灰度 A–E ≥60% → 切 staging + flip 默认 → 删除后全套件绿 + 品牌/canonical/兑现/死链门全绿 +
rg "gd-runtime|build-from-source|GAMEDEF_SYSTEM"活层零命中。 - 全程:
__GameBundle产物契约 + emit/回调链零回归。
8. 回滚
- Phase 2/3:
saaSourceMode=amodel关 flag 即回 factory(零数据迁移;factory 仍在)。 - Phase 4 删除前打 tag
pre-gamedef-factory-retire;删除本身不可逆 → 回滚 = revert commit/tag(D1=A 终态无 flag 回退)。 - cutover(切 dispatcher / flip 默认)配置级各自可回。
9. Blast radius · 风险
纠正(§0):已验证 = harness agentic 生成内核;集成层(CLI/落点/信封/runner/repair/预算)= 净新增,非"直接复用"。
| 风险 | 级别 | 缓解 |
|---|---|---|
| RC1 shell-out 耦合(CLI/JSON/超时) | 中 | §5 专用 runner + 末行 JSON + exit code + stderr 回 repair |
| RC2 双/三信封对齐工作量 | 中-高 | §2 SAA 变体 + §10 命名统一;Phase 2 ② 含 5 文件清单 |
| RC3 部署 app 宿主依赖 node+game-runtime+new-api | 中 | §3 前置 + cutover smoke |
| RC4 harness 内 check/build 自纠 vs SAA repair/play 职责 | 中 | 分层:harness 管编译期;SAA play=唯一真玩门;repair 管 play-fail 再生 |
| RC5 checkpoint/observation 在 generate 黑盒降级 | 中 | 承认:generate 内 13–22 步对 SAA observation 不可见(落 harness evidence/run-log.txt);checkpoint 续跑粒度=generate 节点边界(内部步整轮重试);排障入口=harness evidence,非 SAA trace |
| RC6 源工件 schema 2.0 落库新形态 | 中 | Phase 1 oneOf 先行 + 读者按 schemaVersion 分支 |
| (沿用 review §5)R1-R7 | — | spike 已证伪 R1/R2/R4 的生成内核部分 |
10. 收口 TODO(跨文档;需另开任务)
- 信封命名三方统一:杀掉设计文档 §0.2 的
__AModelGame,统一为__GameBundle.bootGameHost(改 design + skill + harness)。 - 专用 Java runner(分流 stdout/stderr)实现(game-cloud)。
- deadline 入 graph state + generate 子预算(game-cloud)。
- escalate 代码级处置最终定(改节点体等价 repair vs 改 SaaStudioGraph 路由 Map)。
- spike 证据归档入仓(3 run 的 run-summary + 截图 → close-out/evidence),使 D1=A 押注闸可追溯(N2)。
- AGENTS 引用订正(本 spec 已用"§6 第10条/engineering-conventions §10")。
- "好玩"量度 rubric(沿用 review open#2)。