受计费 e2e 在 mini-desktop 隔离实例(:48090 + worker :9502,不碰 live)跑通: - 三件硬证据全坐实:① 三断言/modifyManifest 落库(ROUND_MS 30000→18000 found / behavior changed+untouchedStable) ② D12 计费(regenerate cost.totalRmb=0.307 / deterministic 零LLM cost=0,均经配额门) ③ 血缘(game_source_project v93145→v93146/47/48 base_version_id=93145) - 判意图分类正确(config/deterministic vs behavior/regenerate-module)、两档执行九门全过 - 抓修 1 阻断性真 seam bug(gameId int→str,a40823b1) 切片三 A11:设计 → 双评审 → M1-M5 执行 → 受计费真后端 e2e,端到端闭环。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
44 KiB
title, status, date, topic, canonical, 承接, 关联代码, 图清单
| title | status | date | topic | canonical | 承接 | 关联代码 | 图清单 | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| A11 对话式调整回路(试玩后纠错)细化执行 plan | 切片三全闭环 ✅ —— M1–M5 代码完成 + 本机逐段验证 + 受计费真后端 e2e 跑通(2026-06-29 · 隔离实例 · 抓修 1 阻断 seam bug) | 2026-06-28 | studio-A11-调整回路 | false |
|
|
|
A11 对话式调整回路(试玩后纠错)细化执行 plan
本档覆盖 plan① 切片三 A11 的完整交付定义,过 §6.8 双评审 + 创始人批后展开 TDD 实施。真跑(chrome 九门、真后端 e2e)只在 mini-desktop。
Summary(结论先行)
用户试玩生成的游戏后,会用自然语言回头提调整("主角颜色太暗""加快下落""把它做成赛车游戏")。这条回路缺位,产品阶段三承诺的对话式创作出口就是个无入口的孤儿——首次生成成了终点。A11 给它工程承接。
逐文件核完代码,A11 的图景与"切片三要从零建调整机制"的预期相反:契约、后端 /modify 执行编排、源工程落库表、修改血缘列、配额门都已落地,可直接复用。缺口集中在切片三所坐的便宜档 Python 线(cheap-worker)——它完全不认 modify:后端 job 里带了 modify 字段,worker 读都不读,会把一次调整静默做成整局重新生成。
调整回路的形态由创始人(2026-06-28)定死:A11 是 LLM 驱动的纠错回路、不是零-LLM 静态覆写。流程是"用户提改 → LLM 判意图 → 确认修改范围与用户输入 → 分类执行(替换资产 / 调整数值 / 大改动反问用户)",改动过大或危险操作要回问用户确认、不擅自重写。
可改性的根基是生成出来的工程本身规范——资产统一管理、数值集中,使一次修改落到一处(一个变量 / 一个文件 / 一个 CDN 地址)。便宜档现状已大体具备:资产由 assets.js 统一管理、核心数值集中在 core.js,二者都是可写文件,A11 判意图后把改落到这一处即可。这是生成质量、不是 A11 的静态门(判意图仍 LLM 驱动)。复杂档同此要求——设计跨档,实现随 tier2 go 跟进(创始人 2026-06-28 定 A)。
这条流程怎么落进系统,是本档评审收敛出的关键架构(创始人定 A 两段式):判意图与执行分离成两次请求。第一段是新增的判意图入口——收用户原话 + baseVersionId,由便宜档 worker 取 base 源、LLM 判出建议的结构化改动 + 风险等级,返回前端。前端展示建议供用户确认或编辑(危险/大改必须确认),确认后才调用已落地的结构化 /modify 执行。HITL 落在两次调用之间的前端确认,不动 aigc 内部状态机。这绕开了"NL 进不了已结构化的 /modify 入口"和"input-required 暂停态无承载"两处阻断;A2A 原生 input-required 暂停态留后期。
五个里程碑:M1 打前置基座(补 derive_profile 让源工程带回传 + 后端注入 base 源到 job + 回调落源回填 base_version_id,无源可改则一切免谈);M2 立判意图入口与前端确认(新端点 + 风险分级 + 危险回问);M3、M4 落两类执行(确定性类:换资产/调数值改规范工程那一处;模块重生成:有界单文件重写改玩法);M5 合验收闭环(三结构断言 + 接配额 + 跑通一次受计费的真实调整任务)。整体重设计、便宜档 extend 落点均留后期,不计入本切片。
Problem Frame(问题框定)
flowchart TB
user["用户试玩后提改<br/>自然语言原话"] --> plan_ep["判意图入口<br/>【本切片新建】"]
plan_ep --> confirm["前端展示建议 + 风险<br/>用户确认/编辑【本切片】"]
confirm --> modify["studio /modify 执行入口<br/>已结构化【已落地·复用】"]
modify --> orch["取 base 源 → submitGenerate<br/>带 modify 字段 → 过 D12 配额门<br/>【已落地·复用】"]
orch --> route{"D3 dispatcher<br/>便宜档路由"}
route -->|"SAA Java 路"| saa["SAA modify 节点:regenerate 可达<br/>deterministic 因 build 未闭合 fail-loud<br/>【非完整复用证据】"]
route -->|"便宜档 Python 路<br/>(切片三所坐)"| cheap["cheap-worker<br/>❌ 不认 modify<br/>❌ derive_profile 恒 None→源不带回传<br/>❌ 无判意图/分类执行"]
cheap -.->|"本切片补"| fix["认 modify job + 读 job.base 源<br/>分类执行 + 改动清单回传<br/>三结构断言"]
classDef built fill:#dcfce7,stroke:#16a34a,color:#0f172a;
classDef gap fill:#fee2e2,stroke:#dc2626,color:#0f172a;
classDef todo fill:#ede9fe,stroke:#7c3aed,color:#0f172a;
class modify,orch built;
class saa,cheap gap;
class plan_ep,confirm,fix todo;
绿块(结构化 /modify 编排 + 配额)已建、复用;红块(便宜档不认 modify、SAA deterministic 未闭合)是缺口;紫块(判意图入口 + 前端确认 + 便宜档分类执行)本切片建。
起点与边界
起点(已落地、复用、不重建) —— 数字代码事实核验(双评审逐文件确认):
- 执行契约全有:
studio.yaml的StudioModifyReqVO{baseVersionId, mode, target, payload}(required + 枚举),mode×target.kind锁定映射(deterministic ⇔ {asset,config,level} + value / regenerate-module ⇔ behavior + intent),违例 1-112-003-*** 拒;反映在 Java VO。这是执行入口,入参已结构化。 - 后端执行编排全有:
AppStudioControllerPOST/modify;StudioServiceImpl.modify()(方法体 308-333:校验锁定映射 → 取 base 源归属校验 → 建会话 + 落任务链 →aigcApi.submitGenerate带 modify 字段)。 - 生成路落库与透传:
AigcTaskDO持久化modify_mode/base_version_id/modify_patch(V19);AigcGenerateExecutortick 认领时把这三个字段放进 job——但当前不放 base 源(执行器明确不带 sourceProject)。 - 源工程落库表与血缘列:
game_source_project(V18 + V20 uk)存sourceJson/sourceHash/status/base_version_id;回调落源landSourceQuietly是通用写入路径(入口只看 sourceProject 非空、与来源无关),便宜档 HTTP 回调只要带 sourceProject 就会落库——但当前不回填 base_version_id。 - 源回传管道大体已通:
result_out.build_source_project已实现、build_result_out已支持 sourceProject 字段、process_job已接线;唯一断点是derive_profile恒返 None,导致 sourceProject 永不被带上。 - 产物工程规范性大体具备:便宜档产物的资产已统一管理(
assets.js的IMAGE_FILES一处声明、按键间接引用、baseUrl可指 CDN),核心数值集中在core.js(ROUND_MS/COLOR_PALETTE等);二者都是可写 L3(不在_L1_FIXED)。换资产/调数值落到这一处即可,差最后的数值集中纪律(M3 轻量收紧)。 - 配额门现成:D12
enqueueWithControlPlane(per-creator×level 日配额 + 并发 + 背压 + fail-closed),modify 走 submitGenerate 自动过门——"一次调整 = 一次受计费受配额任务"是现成语义。 - 九门 + 三层校验链现成:
cheap_run的 scaffold/stage/smoke/ensure_play_spec/play(九门)+ check(静态门 + 形状门)+ build(esbuild),可复用。
SAA Java 路的准确状态(评审纠正):SAA 有 modify 节点、regenerate-module 路径可达;但 deterministic modify 因 sourceProject→build 未闭合而 fail-loud(显式失败)。所以 SAA 路不能当作"A11 便宜档 deterministic 执行已有实现"的复用证据——deterministic 执行在两条线上都需本切片建。
做(in scope):
- 判意图入口(新端点):收用户 NL 原话 + baseVersionId,worker 取 base 源 + LLM 判出建议 {mode, target, payload} + 风险等级,返回前端。
- 前端范围确认:展示建议供用户确认或编辑;危险或改动过大必须用户确认,可取消。
- 便宜档 worker 认 modify job:读 job 里的 modify 字段 + base 源(后端注入),分类执行。
- 源回传落库补全:补
derive_profile让 sourceProject 带上回传;后端注入 base 源到便宜档 job;回调落源回填 base_version_id。 - 分类执行两档:① 确定性类纠错(换资产 = 改
assets.js资产清单那一处 /baseUrl指 CDN;调数值 = 改core.js集中常量那一处;改关卡 = 改对应布局处);② 模块重生成(改玩法 = 有界单文件 LLM 重写,复用 resume + 三层校验)。 - 轻量收紧便宜档生成纪律:可调数值都进 core.js(让"改一处"可靠),落 _template + 生成 prompt + soft check。
- 三结构断言验收(含改动清单语义校验)+ 跑通一次受计费的真实调整任务 e2e。
不做(out of scope):
- 不重建已落地的
/modify执行编排 / 契约 / 任务链 / 血缘表 / 配额门(复用)。 - 不交付 A2A 原生 input-required 暂停态(创始人定 A 两段式;HITL 走前端两次调用之间的确认,aigc 内部状态机不动;A2A 原生暂停留后期想要 agent 多轮交互时再补)。
- 不固定强结构化 config seam 当 A11 的静态门(创始人定:规范性靠生成产出规范工程、不靠工具层加门;详见 KTD2)。
- 不做整体重设计档(plan① 明定留后期)。
- 不接便宜档 extend 路(契约/StudioServiceImpl/SAA 已落 extend,但便宜档同样不认;A11 只接 deterministic + regenerate-module 两档,extend 便宜档落点留后期/另议,避免又一个悬空)。
- 复杂档 tier2 A11 的实现不在本切片(随切片二 tier2 go 后用同一回路跟进);但设计跨档——工程规范性(资产统一 + 数值集中)对 tier2 产物(
tier2-source-project.schema.json)同样要求,已写进本档(创始人 2026-06-28 定 A)。 - 不在工具层做经济 / 数值平衡静态判断(切片二教训:数值平衡是 agent 玩法职责)。
- 不真存二进制资产;资产替换 = 改资产清单(
assets.js)的一处地址(后期 CDN 挂载游戏资产即替换它,创始人 2026-06-28)。
执行决策(创始人 2026-06-28)
- A11 = LLM 驱动纠错、并非零-LLM 静态覆写:流程"用户提改 → 判意图 → 确认修改范围与用户输入 → 分类执行",不需要完全静态的编码替换。
- 分类执行三类:替换游戏资产(改资产清单的一处地址,后期 CDN 挂载即替换它)/ 调整数值(改集中数值的一处常量)/ 需要大改动(反问用户:改动过大需重写、危险操作需确认)。
- 工程规范性是关键、跨档:A11 的可改性建立在生成出来的工程本身规范上——游戏资产统一管理、数值集中,使一次修改落到一处(一个变量 / 一个文件 / 一个 CDN 地址)。这是生成质量、不是 A11 的静态门(判意图仍 LLM 驱动);便宜档与复杂档同此要求。
- 不固定 config seam:不在工具层把覆写靶点硬约束成静态校验门;规范性靠生成产出规范工程,不靠工具层加门。
- 链路架构 = A 两段式(评审收敛、创始人 2026-06-28 定):判意图与执行分离成两次请求,HITL 走前端确认,不上 A2A 原生暂停态。
- 范围 = 便宜档优先、设计跨档、复杂档随 tier2(创始人 2026-06-28 定):本切片实现便宜档 A11;设计文档把工程规范性写成跨档要求;复杂档 A11 用同一回路、等切片二 tier2 go 后跟进。
Key Technical Decisions
- KTD1(判意图独立于执行 · 在 /modify 之前):契约
/modify入参已结构化,校验在前;故"NL → {mode,target,payload}"必发生在调/modify之前。判意图做成独立的前置入口(收 NL 原话 → worker 取 base 源 + LLM 判建议结构化改动 + 风险),与执行解耦;前端确认后才走现成的结构化/modify。取舍:相较把判意图塞进 worker 执行内部(与已结构化契约倒置、且要改契约放宽必填),两段式弥合了 NL 与结构化执行入口的缝。 - KTD2(执行落到规范工程的一处 · 资产统一管理 + 数值集中 · 跨档 · 创始人 2026-06-28):A11 的可改性建立在生成侧工程规范性上——资产统一管理、数值集中,使一次修改落到一处,而非 LLM 在散落代码里定位。便宜档现状已大体具备:资产由
assets.js统一管理(IMAGE_FILES键→文件名一处声明、按键间接引用、baseUrl可指 CDN,且 assets.js 是可写 L3),换资产 = 改那一处;核心数值在core.js(ROUND_MS/COLOR_PALETTE等,可写 L3),调数值 = 改那个常量,差最后的纪律(个别数值散在别处)。本切片轻量收紧"可调数值都进 core.js"的生成纪律。这不是给 A11 加静态覆写门(那个不做、判意图仍 LLM 驱动),而是要求生成产出规范工程;规范性在生成侧,A11 判意图后把改落到规范工程的那一处。跨档:复杂档 tier2 产物(tier2-source-project.schema.json)同样要求资产统一 + 数值集中,A11 复杂档用同一回路、随 tier2 go 跟进。残余误伤由 M5 改动清单语义校验兜底(见 KTD6)。 - KTD3(危险/大改走前端确认 · 创始人定 · A 两段式):判意图评出风险高或改动过大时,前端必须让用户确认或编辑后才提交执行,不擅自重写;用户可取消。HITL 落在判意图与执行两次请求之间,不需 aigc 暂停态。取舍:相较 A2A 原生 input-required 任务内暂停(要补等待态 + 超时 + 回问落库 + confirm/resume API + worker→后端暂停通道,两评审都点名 P0 级工作量),两段式以前端持有建议态换掉整套暂停机制。
- KTD4(模块重生成起步 = 文件级):便宜档产物只有文件级写边界(game-logic.js 等 L3 文件),无语义 behavior 拆分。模块重生成把契约
target.kind=behavior在便宜档映射到玩法逻辑文件整文件有界重写,不动 core/render/assets/host-config。取舍:先复用现有边界落地,behavior 细粒度留后期。 - KTD5(源回传落库是硬前置 · 钉死注入路径):modify 一切建立在"能按 base 版本取回源工程"上。便宜档 worker 是 Python、无 DB 访问,不主动反查;路径钉死为后端派发前经
SourceProjectApi.fetchByVersionId注入 base 源到 job,worker 只消费job.sourceProject。改result_out回传契约时按切片一 M3b 同款 parity 护栏防回退。 - KTD6(三断言①升级为改动清单语义校验):纯文件 diff 验不出"LLM 改对了那个值/那个位置"——目标文件本就允许变、文件内顺手改坏抓不到。故要求 worker 回传结构化"改动清单"(改了哪些位置/常量、改成什么),断言①校验清单真实命中目标且不溢出非目标;调数值类再叠一次改后行为采样(如改下落速度 → smoke 抓到的速度量真变)。取舍:在不固定 config seam 的前提下,用改动清单 + 行为采样替代结构锚点来兜误伤。
High-Level Design(里程碑与依赖)
flowchart LR
M1["M1 前置基座<br/>derive_profile + 后端注入base源 + 血缘回填"] --> M2["M2 判意图入口 + 前端确认<br/>NL→建议结构化+风险 · 危险回问"]
M2 --> M3["M3 确定性类纠错<br/>换资产/调数值改规范工程一处 · 改动清单"]
M2 --> M4["M4 模块重生成<br/>有界单文件重写改玩法"]
M3 --> M5["M5 验收闭环<br/>三结构断言 + 受计费 e2e"]
M4 --> M5
classDef m fill:#eff6ff,stroke:#2563eb,color:#0f172a;
class M1,M2,M3,M4,M5 m;
两段式回路时序(一次调整请求的端到端走向):
sequenceDiagram
participant U as 用户(试玩后)
participant F as 前端
participant PE as 判意图入口【本切片新建】
participant W as cheap-worker
participant S as studio /modify【已落·复用】
participant A as aigc submitGenerate + D12门【已落】
participant P as game_source_project
U->>F: 自然语言改话
F->>PE: 第一段:判意图(rawText + baseVersionId)
PE->>W: 取 base 源 + LLM 判意图
W->>P: 读 base 源工程
W-->>PE: 建议{mode,target,payload} + 风险等级
PE-->>F: 返回建议 + 风险
F-->>U: 展示建议(危险/大改 高亮需确认)
U->>F: 确认 / 编辑 / 取消
F->>S: 第二段:/modify(已结构化, 用户确认后, 受计费)
S->>A: 取 base 源 + 提交 modify 任务(过配额门)
A->>W: dispatch job(modify 字段 + 后端注入的 base 源)
W->>W: 分类执行(换资产/调数值改规范工程一处 / 模块重生成) + 出改动清单
W->>W: esbuild 重建 → 九门 + 三层校验 + 三结构断言
W->>P: 回传新源工程(新 sourceHash, base_version_id=被改版)
W-->>S: 新预览版(走发布审核, 不动 currentVersion)
执行任务态机(判意图是独立请求-响应、不入任务态机;只有第二段 /modify 执行是任务):
stateDiagram-v2
[*] --> 初始: 用户确认后提交 /modify
初始 --> 生成中: worker 认领(读 job.base源 + modify 字段)
生成中 --> 完成: 九门+三层校验+三断言全过(回填新 version_id + base_version_id 血缘)
生成中 --> 失败: 任一门挂(不建新版·base 不动)
完成 --> [*]
失败 --> [*]
M1 · 前置基座:源回传补全 + worker 认 modify job
交付物:① 补 derive_profile(派生 profile 三枚举),让便宜档每次生成把源工程带上回传、落 game_source_project(回传/落库链已通,只接这一个断点);② 后端派发到便宜档 job 时注入 base 源(经 SourceProjectApi.fetchByVersionId),worker 只消费 job.sourceProject、不主动反查;③ 回调落源 landSourceQuietly 从 AigcTaskDO.baseVersionId 回填 SourceProjectLandReqDTO.baseVersionId,让血缘列写上;④ worker parse_job 读 job 里的 modify 字段(modify_mode / modify_patch / base 源)。
接入点:cheap-worker/worker_service.py(derive_profile / parse_job)、game-cloud 侧 AigcGenerateExecutor(注入 base 源到 job)、DifyCallbackServiceImpl.landSourceQuietly(回填 base_version_id)。
验证:单测——便宜档生成产物经 derive_profile 后带 sourceProject;构造带 modify 字段 + base 源的 job,断言 worker 取全。真后端 e2e(mini-desktop)——便宜档生成一款后 game_source_project 有行、sourceHash 非空;一次 modify 回调后该版本 base_version_id 非空。
依赖:切片一便宜档线。
风险:① 改 result_out 回传契约牵动下游消费(参照切片一 M3b 翻车)——加 parity 护栏(回传前后过同一组形状断言)。② base 源是多文件全文 JSON,经 HTTP body 传便宜档 worker,体积/超时未评估——M1 先量体积上限,超标再议(worker 无 DB seam,凭 id 回拉更重,非首选)。
M2 · 判意图入口 + 前端范围确认(A11 主干)
交付物:① 新增判意图入口(收 rawText + baseVersionId),由便宜档 worker 取 base 源 + LLM 判出建议 {mode, target, payload} + 风险等级 + 是否需强制确认,返回前端——不执行、不落新版本;② 前端展示建议供用户确认或编辑,危险或改动过大强制确认,可取消;③ 确认后前端调用已落地的结构化 /modify 执行(受计费)。判意图入口是 contract-first 新增(additive,不动 /modify 既有契约)。
接入点:新判意图端点(studio 侧)+ worker 判意图职责(cheap-worker,复用其模型接入 + base 源消费);前端确认交互。
验证:单测——"把主角颜色调暗"判为 deterministic·asset·低风险·可直接确认;"把它做成 3D 赛车"判为大改·高风险·强制确认;分类与风险判据可单测(喂固定改话 + base 上下文,断言判出的 mode×target×risk)。e2e——判意图入口返回建议、前端确认后 /modify 收到结构化入参执行;判意图本身不产新版本、不计费(计费在执行段)。
依赖:M1(要有 base 源 + worker 认 job 才能判意图、才能执行)。
风险:判意图准确率(LLM 判错类型/风险)——缓解:风险存疑一律升级为强制确认(宁可多问);判据留可观测日志校准。
M3 · 确定性类纠错执行(换资产 / 调数值 / 改关卡)
交付物:执行段判为 deterministic(target.kind∈{asset,config,level})时,改动落到规范工程的一处——换资产 = 改 assets.js 的 IMAGE_FILES 那一项(或 baseUrl 指 CDN,后期 CDN 挂载即替换它);调数值 = 改 core.js 里那个常量;改关卡 = 改对应布局处;三者落点(assets.js / core.js / render 等)都是可写 L3,不撞 L1_FIXED 写禁。取 base 源 → 改那一处 → 产出改动清单(改了哪个文件的哪个键/常量、改成什么)→ esbuild 重建 → 过九门。不重生成玩法逻辑。配套轻量收紧生成纪律:可调数值都进 core.js(生成 prompt / _template + soft check),让"改一处"可靠。
接入点:worker 确定性类执行分支(取 base 源 → 改规范工程那一处 + 记清单 → cheap_run 的 build + stage + smoke + play 轻链);需一个"在既有产物上只重建 + 重过九门"的轻入口(现有 cheap_run 入口都假定整局 scaffold 起步);生成纪律收紧(数值归 core.js)落 _template + 生成 prompt。
验证:单测 + e2e——换 sprite 占位 → 产物引用确实变、改动清单命中该占位、九门过、非目标文件 hash 稳;调下落速度 → 对应数值变、清单命中、改后 smoke 抓到速度真变、九门过、非目标稳。
依赖:M1、M2。
风险:LLM 定位常量改错位置(改串/改溢出)——缓解:改动清单 + 行为采样(KTD6)抓"改对没";定位失败回退到强制确认或转模块重生成。
M4 · 模块重生成执行(改玩法)
交付物:执行段判为 regenerate-module(target.kind=behavior)时——把 behavior 在便宜档映射到玩法逻辑文件(game-logic.js),取 base 源 → 据用户意图有界重写该单文件 → 复用既有外层 resume 与三层校验 → 不动 core/render/assets/host-config → 过九门。
接入点:worker 模块重生成分支(复用 cheap_studio 的 ReAct 写单文件 + cheap_run resume + 三层校验);写边界收窄到玩法逻辑文件。
验证:e2e——"陨石下落改成会左右摇摆" → game-logic 文件变、core/render/assets hash 稳、九门过、改后仍能玩。
依赖:M1、M2。
风险:玩法文件与其他文件耦合导致单文件重写不自洽——缓解:复用切片一 resume 熔断 + 三层校验抓不自洽;牵连过深时由判意图升级为大改 → 强制确认。
M5 · 验收闭环 + 受计费 e2e
交付物:三结构断言机器门 + 接 D12 配额 + 跑通一次受计费的真实调整任务。三结构断言(plan① 线 154,结合 KTD6)——① 请求的结构化改动可断言真实生效:worker 改动清单命中目标且不溢出非目标(非纯文件 hash),调数值类叠改后行为采样;② 非目标模块的 hash / 白名单 diff 稳定(没顺手改坏别的模块);③ 新版本与 baseVersionId 血缘可查(复用 M1 回填的 game_source_project.base_version_id 反查链)。三断言 + 九门 + 三层校验全过才算"改成"。
接入点:三断言机器门(纯逻辑、可单测:清单命中校验 + 非目标 diff + 血缘字段链);血缘可查复用 M1 写上的 base_version_id(game_version 产物表无 parent 列,用源工程表 base_version_id 反查链;给版本产物表加 parent 列列为可选、非本切片必做,避免动 project 模块版本权威);受计费走现成 D12 enqueueWithControlPlane。
验证:真后端 e2e(mini-desktop)——判意图 → 前端确认 → /modify 执行 → 九门 + 三层校验 + 三断言全过 → 落新预览版(不动 currentVersion、走发布审核)→ 计费落账 → 血缘可查。
依赖:M1–M4。
风险:三断言只验"改了对的东西、没误伤",不直接证"改得好不好"(玩法质量归 agent / WU-B,非本门职责)——已知边界、不在工具层加码玩法质量门。
Verification(验证计划)
- 单测优先:判意图分类与风险判据、资产/数值一处改写、改动清单与三断言判据、parse_job modify 字段、derive_profile、parity 护栏、base_version_id 回填。
- 真后端 e2e(mini-desktop,绕系统代理直连内网):两段式全链路 + 前端确认 + 三断言 + 受计费落账 + 血缘可查。
- 九门 + 三层校验复用 cheap_run,不另造。
- 完成判据 = plan① 交付定义:两类执行落地、改后过九门 + 三结构断言、接 D12 配额、跑通一次受计费真实调整任务(整体重设计、便宜档 extend 不计入)。
风险与回滚
- 判意图错判:风险存疑升级强制确认兜底;判据留可观测日志校准。
- 模块重生成不收敛:复用切片一 resume 熔断 + 三层校验;牵连过深升级为大改强制确认。
- 源回传契约改动回退:parity 护栏(切片一 M3b 同款)。
- 回滚:里程碑独立可回退;modify 失败 = 不建新版、base 不动(契约已定,天然安全);M1 源回传若出问题可单独关闭、不影响首次生成线;判意图入口是 additive 新端点,不影响既有 /modify。
迁移对账(跨设计面归属 · 防越位/揽活)
- 复用(已建、不重建):StudioServiceImpl.modify 执行编排、taskchain 任务链、game_source_project V18 落库与血缘列、D12 配额门、cheap_run 九门 + 三层校验、源回传/落库管道(除 derive_profile 断点)。
- 自建(本切片 A11):判意图入口(新端点 + worker 判意图)、前端范围确认、便宜档 worker 的 modify 执行两档、derive_profile 补全、后端注入 base 源、base_version_id 血缘回填、改动清单 + 三结构断言机器门。
- 跨设计面(plan① 线 158):WU-B 的 A11 反馈回路(生成/玩法质量)、WU-C 5.4(覆写/重生成后的三层校验与九门)、WU-F 配额数值。本档不揽生成质量职责、不替 WU-F 定配额数值(占位待创始人拍)。
- 收口 TODO:
- ① 回写 plan① 切片三 行 148——"确定性覆写"不再是零-LLM、改为 LLM 判意图后改规范工程一处(本档 KTD2),守 canonical 唯一性,交横切一致性主人对账。
- ② 本 plan 兼充 A11 设计面(plan① 收口 TODO⑥:A11 在设计 SoT 仅协议表一行);评审通过后蒸馏回
docs/architecture/架构/生成引擎/与.agents/knowledge/。 - ③ 便宜档 extend 落点、A2A 原生 input-required 暂停态:均留后期,需要时另立切片/plan,避免悬空。
Sources(事实来源)
- plan① 切片三 A11(
docs/plans/2026-06-25-…-plan.md行 142-160、298)。 - 运行时 SoT §三 A3/A3.5/A4/A5/A11(
docs/architecture/架构/生成引擎/agentic运行时架构图说.md)。 - 契约
studio.yaml(StudioModifyReqVO + mode×kind 锁定映射)、source-project.schema.json(config 字段 / sourceHash 寻址)。 - 数字代码事实 digest + Codex/Opus 双评审逐文件核验(后端执行编排已落 + 便宜档缺口 + SAA deterministic fail-loud + 源回传管道断点 = derive_profile + 血缘回填漏接)。
双评审发现与处置
并行双评审(Codex codex-rescue + Opus 对抗式文档评审,互不通气);两评审在两条主干上咬合。逐条处置:
- P0-A 入口顺序倒置(两评审一致):/modify 入参已结构化,NL→结构化必在其之前,原稿把判意图放 worker 内部、与契约倒置。处置:改 A 两段式(创始人定)——新增判意图入口(/modify 之前),执行复用结构化 /modify;KTD1 重写、M2 重构、时序图改。已修。
- P0-B input-required 无承载(两评审一致):aigc 六态无暂停态、回调只认 succeeded/failed、无 resume API。处置:A 两段式绕开——HITL 走前端两次调用间确认,aigc 状态机不动;A2A 原生暂停态列收口 TODO③ 留后期。已修。
- P1 血缘写链漏接(Codex):landSourceQuietly 未从 AigcTaskDO.baseVersionId 回填,断言③会查空。**处置:M1 交付物③ 补回填 + 单测断言。**已纳。
- P1 M1 缺口高估 + 路径矛盾(两评审):回传/落库链已通,真缺口仅 derive_profile;"后端注入"与"worker 反查"措辞冲突。**处置:M1 缩到真缺口、KTD5 钉死后端注入·worker 只消费。**已修。
- P1 SAA modify 全通不准(Codex):SAA deterministic 实为 fail-loud、build 未闭合。**处置:起点段改正、不作复用证据。**已修。
- P1 三断言对改错位置盲区(Opus):纯文件 diff 验不出改对。**处置:KTD6 + M5 断言① 升级为改动清单语义校验 + 行为采样。**已修。
- P1 plan① 定义漂移(Opus):确定性覆写从零-LLM 改为 LLM 判意图后改规范工程一处,未回写 plan①。**处置:收口 TODO① 回写 plan① 行 148。**已列。
- P2(两评审):extend 悬空(→ 边界显式 scope-out + TODO③)、占位撞写禁(→ 已核
assets.js/core.js均可写 L3、不在_L1_FIXED,换资产/调数值落点干净)、HTTP body 体积(→ M1 风险②)、散文元叙述/"房式"笔误/"639 行"措辞/"modify 四件套"术语(→ 全文清理:删执行者须知元叙述、改"方法体 308-333"、统一"modify 字段 + base 源单独注入")。已处置。
评审后创始人追加指令(2026-06-28,已整合):① 链路架构定 A 两段式(解 P0-A/B:判意图入口在 /modify 之前、HITL 走前端确认、不上 A2A 暂停态);② 工程规范性是关键、跨档——资产统一管理 + 数值集中使"改一处",便宜档现状已大体具备(assets.js 统一资产、core.js 集中数值、均可写 L3),复杂档同此要求、实现随 tier2(定 A)。已落入执行决策 + KTD2 + M3 + 起点 + 边界 + Summary。
执行发现
M1 前置基座(执行中,2026-06-29)
- Python 侧(M1① derive_profile + M1④ parse_modify)完成、绿:
derive_profile兑现返便宜档基线{realtime, discrete-choice, metric}(tap-targets 本就这三维、非伪造),解锁build_source_project→ sourceProject 随 result-out 回传;parse_modify提取 modify 区(mode/baseVersionId/modifyPatch/sourceProject),无 modifyMode 返 None(create 路零副作用)。tests/test_a11_m1.py5/5 + 回归test_worker_service15/15 +test_result_out18/18,零回退。 - 对账与偏差:① 评审所言属实——源回传/落库管道已通,唯一断点是
derive_profile恒返 None;兑现它即打开全便宜档生成的 sourceProject 回传(每 gen 多带 src/ 全文,实测约 6 文件几 KB 量级,HTTP body 体积无虞,消解 M1 风险②的体积顾虑)。② 便宜档 base 源注入 job 的键名钉死为sourceProject(对齐 SAAK_SOURCE_PROJECT+ workerparse_modify读取侧)。 - Java 侧(M1② executor 注入 base 源 + M1③ 回调回填 base_version_id)完成、绿:
AigcGenerateExecutor.injectBaseSourceProject(据 baseVersionId 反查SourceProjectApi.fetchByVersionId→job.put("sourceProject", data.getSourceJson()),镜像SaaGraphDispatcher.resolveBaseSourceProject,best-effort 非阻断、create 路零变,经AigcExecutorConfiguration软注入 SourceProjectApi);DifyCallbackServiceImpl.landSourceQuietly补landReq.setBaseVersionId(task.getBaseVersionId())(落库服务SourceProjectServiceImpl.landL105 已持久化该列,无需改)。子代理本地 maven 全绿(98 测试:执行器/回调/SAA 回归/源服务);主会话独立复跑AigcGenerateExecutorTest+DifyCallbackServiceImplTest= 46/46 绿、BUILD SUCCESS(一手验证非口头)。 - M1 收口:源回传落库链端到端通——便宜档生成 → derive_profile 兑现 → sourceProject 回传 → landSourceQuietly 落库(带 base_version_id 血缘);modify 路 → executor 注入 base 源 → worker parse_modify 读到。改动未提交(在工作树)。
M2 判意图入口 + 前端确认(执行中,2026-06-29)
- Worker 侧(判意图 classify +
/classify端点)完成、绿:cheap_classify.py的build_classify_prompt(把 base 源可改面——assets.js 资产清单 / core.js 集中数值 / game-logic.js 玩法 + 用户原话喂进 prompt)+parse_classify_response(落 mode×category 锁定 + 风险/确认规则 + 坏 JSON 安全兜底);workerPOST /classify同步端点(注入式classify_fn,不入生成队列、不起 Chrome)。tests/test_a11_m2_classify.py9/9 + 回归test_worker_service15/15、test_a11_m15/5。 - 判意图契约:
{category(asset|config|level|behavior|big-change|unclear), mode(deterministic|regenerate-module|null), target, payload, riskLevel, needsConfirm, rationale, clarify}。可信边界 = LLM 给的 mode 不采信、一律按 category 落 mode;needsConfirm由 worker 定(只低风险确定性改免确认,改玩法/大改/意图不明/中高风险一律回问,兑现创始人"危险回问")。真 LLM 调用(_default_completeopenai 直调 M3 + 框架代理旁路)为集成路、M5 e2e 真验。 - Java 侧(studio
/modify/plan→ aigcclassifyModify→ worker/classify同步对接)完成、绿:契约先行(studio.yaml +/modify/plan+ ReqVO/RespVO);AppStudioController.planModify→StudioServiceImpl.planModify(validateCreator白名单门[核实与既有 createDraft/generate/modify L99/139/313 一致] +resolveBaseVersionGameWithOwnership归属校验防越权 + 委托 aigc + 兜底);AigcApi.classifyModify→WorkerClassifyClient(据 baseVersionId 反查 base 源 → NO_PROXY JDK HttpClient POST worker/classify→ best-effort 兜底 unclear+needsConfirm);软注入ObjectProvider<WorkerClassifyClient>(executor 关闭时 Bean 缺席→兜底、不致启动失败,镜像 WorkerDispatchClient)。子代理本地 maven 43 测试全绿;主会话独立复跑 WorkerClassifyClient/StudioServiceImpl/AigcApiImpl = 43/43 绿、BUILD SUCCESS。 - M2 收口:两段式第一段全链路通——前端 → studio
/modify/plan→ aigc 反查 base 源 + 同步 worker/classify→ 判意图建议 + 风险回前端;needsConfirm=true(危险/大改/改玩法/意图不明)待用户确认后调/modify(M3/M4 执行)。真连 worker 的判意图 e2e 待 M5(mini-desktop)。前端 Vue 确认 UI = 前端 lane(消费/modify/plan,本切片 backend 承接已就位、非孤儿)。worker URL 派生 =getWorkerUrl()尾段/generate→/classify;判意图同步 HTTP 超时 30s 常量(极端慢→兜底降级,MVP 可接受)。
M3 确定性类执行(完成、绿,2026-06-29)· 零 LLM
cheap_modify.py:apply_deterministic_modify(改规范工程那一处——config/level→core.js 等 L3 的export const NAME=值替换 / asset→assets.jsIMAGE_FILES键值或 baseUrl;no-op 检测=无任一条found 且 old≠new→ok=false,是 M5 断言①地基);materialize_source_project(系统级落盘全 files 含 L1、绕 write_file 的 L1 守卫);execute_deterministic_modify(apply→缺 plumbing 才 scaffold→materialize→cheap_runbuild/stage/smoke/play 九门,零另造)。- worker 接线:
process_job最前 modify 分流(_process_modify_job),deterministic 走执行 + manifest 进trace.modifyManifest+ best-effort 带新版 sourceProject(链式改);regenerate-module显式 failed 留 M4(不静默吞);create/生成路一字未动。 - 测试:
test_a11_m3_deterministic18/18 + 回归(a11_m1 5/5、a11_m2_classify 9/9、worker_service 15/15)全绿。 - 九门 smoke(主会话独立复跑,本机 Chrome 免 LLM):取
amgen-bake-click-score-0base 源 → config 改ROUND_MS 30000→19000→ status=succeeded、stage=play、verdictPass=true、manifest found=true、落盘 core.js=19000、运行时 remainMs=19000(改的那一处真在游戏里生效并过九门)。坐实"改规范工程一处→重建→过九门"全链路。 - M3 收口:确定性类执行端到端通(零 LLM);改动清单为 M5 断言①就位。
M4 模块重生成执行(完成、绿,2026-06-29)· 有界单文件 LLM 重写
- 复用机制(参数化、不复制 resume/熔断/收口):
cheap_studio.run_studio加 4 个默认 None 可选参(system_prompt/initial_kick/write_whitelist/prepare)切到 modify 态,create 路零行为变化(核 diff 确认 params=None 等价原逻辑、仅日志串变);cheap_toolkit.build_toolkit加 write_whitelist(非白名单 basename 写直接拒);cheap_roles.build_modify_system_prompt(复用 create 红线契约块)。 execute_regenerate_modify:取 intent(空→failed)→ materialize base 源 → 重写前后对非目标文件算 hash → 有界重写(写边界收窄到只game-logic.js,agent 可读其余取上下文)→ 九门;status=succeeded ⟺ 九门过 ∧ 非目标稳;manifest{file:game-logic.js, kind:behavior, intent, changed, untouchedStable}(断言②地基)。- worker 接线:
_process_regenerate_job(regen_fn),把 M3 的 regenerate-module 显式 failed 占位换成真执行;deterministic/create/生成路一字未动。 - 测试:
test_a11_m4_regenerate10/10(全注入桩零真 LLM,含"篡改非目标→断言②抓+判 failed")+ 全回归(m1/m2/m3/worker_service/toolkit/roles)主会话独立复跑 73 测试全绿。 - 一次真 LLM smoke(子代理单跑,本机 Chrome + new-api M3):base=
amgen-bake-click-score-0、intent="把命中加分从固定改成连击递增" → status=succeeded、untouchedStable=True、九门 verdict.pass=True、attempts=1、¥0.31、137s、无熔断;独立 diff 佐证 5 个非目标文件字节相同、仅 game-logic.js 变且真实现连击递增。M4 plumbing 通(重写发生 + 写边界守住 + 非目标稳 + 九门跑到 verdict);此次质量也恰好达标(质量归 agent 层、不在 M4 判据)。 - M4 收口:两档执行(deterministic + regenerate-module)全落地;断言②地基(非目标 hash 稳)就位。
M5 验收闭环 · 三断言机器门(完成、绿,2026-06-29)· 受计费 e2e 评估中
cheap_assert.py三结构断言:① change_applied(改动真生效非 no-op:deterministic=manifest 有 found 且 old≠new / regenerate=changed);② nontarget_stable(base→new 真比对算内容差,非目标文件变=误伤——不信执行器自报标记,防执行器 bug 自证,兑现 Opus P1-2);③ lineage_queryable(baseVersionId 在,worker 侧验必要条件,DB 真可查由后端 e2e + M1 回填)。three_assertions合并 verdict。test_a11_m5_assertions12/12。- 集成进 execute_*:两档执行加
base_version_id参 + 计算并附assertionsverdict + 收紧 status 判据(succeeded ⟺ 九门 ∧ ① ∧ ②;regenerate 原漏判 ①changed 已补,no-op 重写不再算成功);worker_process_*_job透传modify.baseVersionId。全 85 测试独立复跑全绿(含 M3/M4 注入桩接 kwarg 修)。 - 集成端到端 smoke(主会话独立、真九门):ROUND_MS 30000→19000 + base_version_id=4096 → status=succeeded、a1/a2/a3 全 true、allPass=true、落盘 core.js=19000。三断言真接进执行器、清洁改动全过。
- 受计费真后端 e2e(mini-desktop 隔离实例 :48090 + worker :9502,不碰 live)完成、绿(2026-06-29):A11 两段式经真后端端到端跑通——
/modify/plan判意图(deterministic 返 config/needsConfirm=false、behavior 返 regenerate-module/needsConfirm=true,分类与风险全对)→/modify执行 → executor 派发 → worker → 回调 → 新版本。三件硬证据:① 三断言/modifyManifest 落库可见(task194ROUND_MS 30000→18000 found=true、task195game-logic behavior changed=true untouchedStable=true);② D12 计费落账(regeneratecost.totalRmb=0.307、deterministic 零 LLM cost=0,均经enqueueWithControlPlane配额门);③ 血缘可查(game_source_projectv93145(base)→v93146/47/48base_version_id=93145)。base + 两档 modify 九门均 pass、failedGates=[]。- 抓修 1 个阻断性真 seam bug(e2e 的价值 · commit
a40823b1):后端 gameId 是 Java Long→JSON number→Python int,worker 直传 cheap_run 的 subprocess(要 str)→ TypeError → 静默归 llm_error → 便宜档经真后端 generate/modify 全失败。本机单测用 str gameId 没暴露、真后端 int 才触发。修 = 3 处 job 消费边界str(game_id)归一化。 - 接线命门 4 处(起隔离实例镜像 live 必覆盖,否则指向 live):dispatcher=http(env 默认 saa)、worker-url=:9502(默认 :9401)、callback-url=:48090(Java 默认 :48080=live)、
aigc.trace.enabled=true(默认 false,否则 trace 不落库)。竞态:live executor 也 tick 同一共享 DB,poll-interval=500ms 赢 CAS、4 任务全被隔离 worker 抢到、无一漏给 live。隔离实例已精确端口拆、live 未碰。
- 抓修 1 个阻断性真 seam bug(e2e 的价值 · commit
状态
双评审已过 → 创始人批(2026-06-29)→ M1–M5 顺序执行完毕,代码全完成、本机逐段一手验证(提交 fc782db0 / 938219d7 / 51230f13 / 14c79dbf / 9a6feddf):
| 里程碑 | 交付 | 验证 |
|---|---|---|
| M1 前置基座 | 源回传落库 + base 源注入 + 血缘回填 | Java 98 maven + Python 测,独立复跑 46/46 |
| M2 判意图入口 | studio /modify/plan → aigc → worker /classify(两段式第一段) |
Java 43 maven + Python 9,独立复跑 |
| M3 确定性类执行 | 改规范工程那一处(零 LLM)→ 重建 → 九门 + 改动清单 | Python 18 + 真九门 smoke 9/9(ROUND_MS 改值在游戏里生效) |
| M4 模块重生成 | 有界单文件重写 game-logic.js → 九门,写边界守住 | Python 10 + 真 LLM smoke 九门 pass、5 非目标文件字节相同 |
| M5 三断言门 | ①改动真生效 ②非目标稳 ③血缘可查 + 收紧 status | Python 12 + 集成 smoke a1/a2/a3 全 true |
切片三全闭环 ✅(2026-06-29):受计费真后端 e2e 已在 mini-desktop 隔离实例(:48090 + worker :9502,不碰 live)跑通——三断言/计费/血缘三件硬证据全坐实、判意图分类正确、两档执行九门全过,并抓修 1 个阻断性真 seam bug(gameId int→str,a40823b1)。A11 对话式调整回路从设计 → 双评审 → M1-M5 执行 → 受计费真后端 e2e,端到端闭环。
收口 TODO(迁移对账已列):① 回写 plan① 切片三 行 148 的确定性覆写定性(执行仍零 LLM,但经判意图两段式到达、非直接覆写)→ 交横切一致性主人;② A11 设计面蒸馏回 docs/architecture/架构/生成引擎/ + .agents/knowledge/;③ 便宜档 extend、A2A 原生 input-required 暂停态留后期。前端 Vue 确认 UI = 前端 lane(消费 /modify/plan)。