games-development-ai/docs/plans/2026-06-30-便宜档M3-生产cutover-plan.md
lili b0bfcabf8a
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
docs(cutover): §9 S6 负例四门真机证据(日额/背压/暂停+并发)+ 六门放行证据表(prod/lab 口径明标)+ 工单回写 a1/a2/e
- D12 五种拒绝行为全负例双证(HTTP 码+后端日志):并发/日额(当日已用=7 上限=0)/背压(门②全局在飞=0)/暂停(infra_config 热键)/unsafe
- 六门证据表集齐:9d trace/D11(86/90)/D9/firstPlay/GP9/D12 全 prod 口径;S5b 明标 lab;放行+S5a=创始人
- 工单:a1 (C6 族错配直指 f121bb01)/ a2 关闭(前提证伪:模板 targets 本就齐,是生成丢键)/ e (2a8d5e45)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 22:58:52 -07:00

493 lines
62 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: "feat: 便宜档 M3 生产 cutover — 对外开闸放量上线(路由已切 · 承接巩固)"
date: 2026-06-30
status: 已批准(创始人 2026-06-30:批准 · 决策点二选 B · 双评审收口)
topic: cheap-worker-M3-生产cutover-对外开闸放量
slice: 切片一 · M3 真上线(第三里程碑收口 · 承接 M3a/M3b)
origin: docs/plans/2026-06-25-生成引擎统一执行计划-AgentScope三档-plan.md
上级: docs/plans/2026-06-25-生成引擎统一执行计划-AgentScope三档-plan.md
predecessor:
- docs/plans/2026-06-27-002-feat-cheap-worker-M3a-python-route-seam-plan.md
- docs/plans/2026-06-28-001-feat-cheap-worker-M3b-create-feed-e2e-6gates-plan.md
关联:
- game-cloud .../service/executor/AigcExecutorProperties.java (dispatcher / saaSourceMode / worker-url flag)
- game-cloud huijing-server/.../application-staging.yaml:179 (worker-url 配置位 · 默认空)
- game-cloud .../service/callback/DifyCallbackTxService.java:101 (aigc.trace.enabled 默认 false)
- game-cloud .../framework/controlplane/config/AigcControlPlaneConfiguration.java (aigc.control-plane.enabled 条件装配)
- cheap-worker/worker_service.py (§6.1 HTTP worker @ :9501)
- cheap-worker/result_out.py (result-out 三字段 + 9d trace 七项)
- cheap-worker/bake_off.py (≥80% 按品类达标门)
- cheap-worker/auto_vs_golden.py:125 (retire_authorization 授权门)
- docs/architecture/架构/生成引擎/验收门.md (对外开闸 6 门 SoT · canonical)
- HEAD ≈ e6525aaa (便宜档 M1 富化重验 · 切片一 A/B)
图清单: [图1 三段定位总览, 图2 路由 flag 状态机, 图3 cutover 时序, 图4 回滚触发流]
---
# 便宜档 M3 生产 cutover · 对外开闸放量上线
## 0 一图看懂
便宜档生成默认路由从 Node 旧路切到 Python cheap-worker 这件事,M3b 已于 2026-06-28 在 live :48080 做完(jar 重部署 + `dispatcher=http`→worker:9501 + 开 `aigc.trace.enabled`,boot 日志坐实)。本 plan 不重做这一步,它承接其后真正没做完的部分:核实 live 当前真实拓扑、把 worker 对齐到含 M1 富化的最新代码、开 `aigc.control-plane.enabled` 让 D12/GP9 六门真生效、落几个还占位的配额与权重阈值、用生产真实 brief 分布把 ≥80% 达标复验一遍,最后由创始人按 6 门证据决定对外放量。
- **核心思想**:M3 的"真合闸"已成既成事实,缺的是"对外开闸放量"——开 control-plane、复验生产口径达标、放行决策。
- **边界**:生成线交付 = Python 生成核心 + 后端路由 flag / D12 接缝 + 生产口径 ≥80% 复验;`publish→feed→玩家真玩`(审核台 auth + REVIEWING)归产品轨,真扣退完整验证归 M4,16 周日历闸门(备案 / ICP / 渠道审核)归法务运营轨,均不在本里程碑。
- **怎么算成功**:live 跑 Python M3 路且 control-plane 六门实证生效,生产真实 prompt 分布按品类 ≥80% 达标复验通过,6 门给出生产证据,创始人放行放量;出问题能一键翻回 Node。
> §0 SVG 概览图后补(本轮 text + mermaid 优先,见 §8 收口 TODO)。
```mermaid
flowchart LR
subgraph DONE["已完成(M3a 机制 + M3b 路由 cutover)"]
A1["M3a 退役机制<br/>§6.1 HTTP worker + 全局 flag 翻转<br/>+ A2A 状态 + idempotencyKey + 授权门"]
A2["M3b trace parity + 6 门新路复验<br/>+ 2026-06-28 live cutover<br/>(dispatcher=http→worker:9501 + trace 开)"]
end
subgraph THIS["本 plan(对外开闸放量)"]
B0["S0 核实 live 真实拓扑"]
B1["S1 路由态对齐 + worker 更新到 M1 富化"]
B2["S2 开 control-plane:D12 四门 + GP9 + 待拍配额"]
B3["S3 trace/D11/D9 生产态 + 权重阈值起步值落定"]
B4["S4 端到端 e2e 生产复核"]
B5["S5 种子受控内测 → 生产 ≥80% 复验"]
B6["S6 6 门放行证据 + 放量决策"]
end
subgraph HANDOFF["移交(不在本里程碑)"]
C1["产品/审核台轨<br/>publish→feed→玩家真玩"]
C2["质量轨 WU-B/C/F<br/>生成质量 ≥80% 内核"]
C3["M4 真扣退<br/>(new-api UserId 阻塞)"]
C4["法务运营轨<br/>16 周日历闸门:备案/ICP/渠道"]
end
DONE --> THIS --> HANDOFF
```
## 1 意图与目标
### 1.1 意图
切片一的目标是便宜档"从一句话到可上线、可变现的轻量小游戏"端到端跑在生产上。M1 把本机/实验室口径的生成质量推到达标(本会话 richness 正路,富游戏三品类各 5/5 过九门;证据 `cheap-worker/results/bake-off-M1-rich.json`(`git show 产物在 cheap-worker 运行环境,未入仓`):`overallMeets=true`、click-score / whack-mole / shop-serve 各 `passRate=1.0`,`richnessByGenre` 三品类均分 click 3.4 / whack 2.4 / shop 4.2 佐证走 richness 正路、非已废 reskin,note 标 lab 代表样本口径、判定零 LLM),M2 的 `retire_authorization` 据它判出 Node 退役授权 `authorized=True`,M3a 造好退役机制,M3b 补齐 trace parity 并在 2026-06-28 把 live 的默认路由从 Node/gamedef 整体切到 Python cheap-worker。
切到 Python 路只是"机制上线",不等于"对外可放量"。当前 live 的 `aigc.control-plane.enabled` 仍是默认 false,意味着守护系统不被压垮的 D12 控制平面和拦截违规 prompt 的 GP9 合规先行两道硬阻塞门是旁路的;生产真实 prompt 分布下能不能稳定 ≥80% 达标,也还没在生产口径复验过(M1 是 lab 代表样本口径)。没有这两件,生成线就不能向真实创作者放开。本 plan 把"已切路由但未开闸"的 live 推进到"对外可放量上线"。
### 1.2 目标 / 交付定义
承接 plan① 切片一 M3 的交付定义(`2026-06-25 统一执行计划` §4 line 111),扣掉 M3b 已兑现的部分,本里程碑的交付定义是:
1. live :48080 跑 Python M3 路(dispatcher=http→cheap-worker)、worker 代码对齐到含 M1 富化的 dev/2.0.0,拓扑经只读核实确认。
2. `aigc.control-plane.enabled=true` 在 live 生效(重启后 Bean 装配经确认、非只改配置),D12 四门(降级 / 配额并发 / 背压 / GP9)+ GP9 fail-closed 实证拦截,占位配额阈值由创始人落定。
3. `aigc.trace.enabled` 确认开启,生产真实生成的 `trace_json` 七项齐、`readiness_score` 逐维真信号;D11 权重与 `BUDGET_RMB` 效率维阈值落定起步值 + 观察校准方案(真校准留质量轨)。
4. 经种子受控内测积累真实 brief 后,生产真实 prompt 分布按品类 ≥80% 达标复验通过(lab→prod 口径升级;种子内测前以 lab 样本复验并明标待回填)。
5. 对外开闸 6 门(独立 SoT [`验收门.md`](../architecture/架构/生成引擎/验收门.md))给出生产证据,创始人按 §6 放行决策开放量。
6. 全程具备一键翻回 Node 旧路的回滚能力,在途任务 restart-safe。
可量化锚点:生成成功率 ≥80%(AGENTS.md §2);GP9 负例 100% 阻断;D12 四门拒绝走业务码 HTTP200;灰测放量受备案红线约束(外测前 ≤2 万人、不接广告、报备删档)。
## 2 边界
### 2.1 本里程碑做(in scope)
- live 拓扑只读核实 + 路由态对齐(承接巩固 M3b 已切的 cutover,非重切)。
- worker 部署更新到含 M1 富化的最新 dev/2.0.0。
- 后端路由 flag 与 D12 控制平面接线:开 `aigc.control-plane.enabled`、落配额 / 背压 / 降级阈值、记账骨架接线。
- trace / D11 / D9 生产态确认 + 权重阈值起步值落定(真校准留质量轨)。
- 端到端 e2e 生产复核(创作页一句话 → 生成 → 九门 → 回调七步 → 落库 D11/D9/trace)。
- 生产真实分布 ≥80% 达标复验。
- 6 门生产证据汇总 + 回滚预案演练。
### 2.2 本里程碑不做(out of scope · 移交边界)
- **`publish→feed→玩家真玩`**:玩家 manifest 端点要求 runtime_package published(status=1),需经 `reviewProject(APPROVE)` 把预览包推进 feed。这条受 auth + 项目 REVIEWING 生命周期约束,M3b 收口时已划归**产品 / 审核台轨**,不在生成线。生成线交付到"可发布的预览包(version + status=0 包 + 真 engineBundle + D11 分)"为止。**接收方(消孤儿)**:① 16 周主计划 [`可行性方案16周-波次映射.md`](../mvp/可行性方案16周-波次映射.md) 阶段一 W3 轨(创作→审核→游戏流→真人试玩→数据回流)+ project 模块(发布编排,§5 模块表)承接日历侧;② 运营域审核台 SoT [`审核台运营.md`](../architecture/运营/审核台运营.md)(双层机审 + 人审 BPM + 处置联动)承接审核台 UI 与 α 自动发布策略;③ feed 内容侧落点 = MVP 作战清单 [`MVP作战清单.md`](../mvp/MVP作战清单.md) backlog "studio 链路③⑤ UI 走查闭合(重锚至 β 后)"+ "feed 内容回灌";④ generic 真出可玩的最终开闸验收挂 **W-G1**
- **生成质量 ≥80% 的内核**:生产复验若不达标,根因在生成侧,归**质量轨 WU-B/C/F**(WU-B 实例达验收 / WU-C 5.4 三层校验与 oracle 护栏 / WU-F 达标门)。本 plan 只负责"在生产口径把达标复验跑出来 + 不达标则不放量",不负责把生成质量从不达标修到达标。
- **D12 真扣退**:本 plan 接线 D12 配额 / 背压 / 降级 / GP9 四门 + 额度记账骨架(占位字段 + 日志);真实"按量扣费 / 失败退费"的完整验证留 **M4**——new-api 网关 `AddToken` 接口 UserId 硬编码、MVP 阶段无真支付(`验收门.md` §1.2)。
- **16 周日历闸门**:IP 授权 / 软著 / ICP / 备案 / 渠道审核归**法务运营轨**。发布门入 feed 受备案约束(外测前完成),是放量的外部前置、不是工程任务。
- **per-request 灰度分流框架**:D3 取全局整体翻转,不造按 key hash 的分流 seam(双评审已判此为 BLOCKER 级新增复杂度);若全局翻转运维风险被证不可接受再议。
```mermaid
flowchart TB
subgraph GEN["生成线(本 plan 主体)"]
G1["Python 生成核心 cheap-worker"]
G2["后端路由 flag + D12 接缝"]
G3["生产 ≥80% 达标复验"]
end
subgraph OUT["移交(本 plan 划清不揽)"]
O1["产品/审核台轨:publish→feed→真玩"]
O2["质量轨 WU-B/C/F:生成质量内核"]
O3["M4:真扣退/补偿"]
O4["法务运营轨:16 周日历闸门"]
end
GEN -.预览包就绪.-> O1
GEN -.不达标回流.-> O2
G2 -.记账骨架.-> O3
GEN -.受备案约束.-> O4
```
## 3 现状就绪盘点
### 3.1 头号事实 · 路由 cutover 已部分完成(与 brief 假设有出入)
派发本任务的口径(plan① §M3 line 133 + 个人 memory)把"生产 cutover"当作未做的待办。权威留痕显示并非如此:**M3b plan(`git show git show 8ea97234:docs/plans/2026-06-28-001-feat-cheap-worker-M3b-create-feed-e2e-6gates-plan.md`) 的 frontmatter status 与文末执行发现明确记录,dispatcher 路由 cutover 已于 2026-06-28 在 live :48080 完成。** 当时侦察发现 live :48080 原本跑的是 6-21 旧 gamedef jar(不是 M3 代码),cutover 实质是 jar 重部署:`fuser -k 48080/tcp` 端口精确替换为 6-28 M3 jar(dev/2.0.0)、配 `dispatcher=http`→worker:9501、开 `aigc.trace.enabled`,boot 日志"生成派发通道选定 dispatcher=http=WorkerDispatchClient"坐实 Node/gamedef 旧路在 live 退役、Python M3 路 go-live;同时拆掉 iso :48090 避免 live+iso 双 executor 同 DB 的 split-brain。最终拓扑 = live :48080(M3 路)+ worker :9501,同 DB 13306。
按 AGENTS.md「仓库才是权威源,memory 只是个人加速器」与 §11「横切一致性主人对账」,本 plan 据留痕重新定位:**M3 的"真合闸 + 真部署"已是既成事实,真正剩余是"对外开闸放量 + 生产口径达标复验"。** 这一矛盾连同"留痕已记完成、memory / plan SoT 仍当未做"的不一致,列入 §8 交创始人与双评审对账。
两个限定必须写清,否则会把"6-28 切过"误当"现在就绪":
- **不能假设 live 当前仍是 6-28 态。** 本 plan 不碰 live,无法直接验证;且 6-28 之后 M1 富化(commit e6525aaa,切片一 A/B)又改了 cheap-worker 生成代码,live worker 跑的可能是 cutover 当时的旧 worker。故 S0 第一步是只读核实 live 真实拓扑。
- **6-28 切的是路由,不是开闸。** M3b 文末明列:control-plane 六门放量"创始人定后单独开"(即 `aigc.control-plane.enabled` 仍 default false)、≥80% 生产达标未复验(U4 真 gen 那次没过九门,质量未到)、产品轨 `publish→feed` 未通。这三件正是本 plan 主体。
### 3.2 路由切换机制(M3a 已落 · 代码核实)
- **Python 新路** = `cheap-worker/worker_service.py`(§6.1 HTTP worker,默认 :9501,KTD4 内部有界串行队列吸收突发、队满 503),经后端默认派发通道 `WorkerDispatchClient`(`dispatcher=http`)接 job-in,生成后 HMAC 回调 `/admin-api/aigc/dify/callback-internal`
- **result-out 三字段语义分离**(`result_out.py`,M3a U1 + M3b 富化):`gameConfig`=最小占位 Map;`engineBundle`=`bundle.iife.js` 全文(含 `__GameBundle`)= 运行时承重产物;`sourceProject`=源工程 2.0 JSON,best-effort 可选源血缘。成功门 = verdict.pass ∧ engineBundle 含 `__GameBundle`。失败走七值 `failureReason` 枚举。9d trace 七项已补齐(M3b)。
- **切换 = 全局 flag 整体翻转**(创始人 D3,非 per-request 灰度):Python 态 `dispatcher=http` + `aigc.executor.worker-url`→cheap-worker;Node 回滚态 `dispatcher=saa` + `saaSourceMode=amodel``generationDispatcher``AigcGenerateExecutor` 构造期单选的 final 字段,翻转需应用重启生效(非热切)。`worker-url` 配置位在 `application-staging.yaml:179`(`${AIGC_WORKER_URL:}`,默认空)。
- **templateId 闸**:只有 `templateId==generic` 的任务进 dispatchGeneric 派发外置 worker;便宜档创作请求由 `submitGenerate` 缺省归一为 generic,恰好命中。这是 Python worker 收到便宜档流量的承重前提,M3a 守住、本 plan 别破坏。
- **A2A 状态**(M3a U3):`AigcTaskStatusEnum.toA2aStatus` 把内部六态映射成 `submitted/working/completed/failed/canceled`,additive `a2aStatus` 字段、保留数字 status,前端轮询不感知底层换实现。`input-required` 无生产源、不产出,交互回路待切片三 A11。
- **幂等**(M3a U4):消费 `idempotencyKey`(`userId+operation+idempotencyKey`),Flyway V26 加列 + 唯一索引(NULL 不去重),防重复提交双跑双扣。区别于 job 级 traceId 幂等(防回调重入)。
### 3.3 控制平面与 6 门(验收门.md · 代码核实)
- **D12 控制平面 + GP9 合规先行**(两道硬阻塞):已焊死在提交入口,门序"降级 → 配额并发 → 背压 → GP9(最贵放最后)";但整体受 `aigc.control-plane.enabled` 条件装配门控(`AigcControlPlaneConfiguration`,**默认 false = Bean 缺席 = 全部旁路 = 现行行为**)。GP9 fail-closed(独立 SafetyCheckClient,短超时 8s + 至多 1 重试)。错误码五码走 HTTP200 业务码。
- **9d trace + D11 就绪 + D9 反同质**(三道落库门,非阻断):worker 侧 M3b 已补齐(trace 七项 / D9 vendored dedup),后端 D11 三值判别坐实(失败 28 / 退化 45 / 成功 100,分数真随质量动)。`aigc.trace.enabled` 默认 false(`DifyCallbackTxService:101`),6-28 cutover 时已在 live 开启(需 S0 核实)。
- **首局体验门**:引擎无关九门 harness 内的 H 门 additive 超集,新路天然继承。
- **G0 / G1 开闸前置**:已 PASS(创作页核实 W-CLEAN 过渡态 + GP9 staging 10 负例 100% safe=false)。
### 3.4 达标门与授权门工具(cheap-worker · 代码核实)
- **`bake_off.py`**:按品类(click-score / whack-mole / shop-serve)各 n 款,`run_studio`(run_gates=True)→ 自动 spec 驱动九门 → 取 verdict.pass,逐品类 ≥0.8 判达标,任一品类缺样本报"覆盖不足"、任一 <0.8 整体未达标——绝不用总体平均掩盖卡死品类纯走确定性九门不调 LLM 当裁判conc15gameId 品类前缀隔离报告不覆盖注释明写"本机/实验室口径,生产真实分布达标在 M3 复验"—— plan S5 即复用它做生产复验
- **`auto_vs_golden.py:retire_authorization`**:三个硬前置全绿(M1 达标 002 等价 auto-vs-golden 不退化)才出 `authorized=True`M1 达标这一前置的证据 = `bake-off-M1-rich.json`(`git show 产物在 cheap-worker 运行环境,未入仓`)(`overallMeets=true`、三品类各 `passRate=1.0``richnessByGenre` 佐证 richness 正路,lab 代表样本口径, §1.1);M2 据此已判 `authorized=True`,是切换默认路由的授权门(S1 复用,不另立判据)。生产真实分布下的达标是另一道口径, S5 复验
### 3.5 部署目标(内网凭据与端点.md)
- live game-cloud :48080( DB 13306);cheap-worker §6.1 HTTP worker :9501;mini-desktop(root@100.64.0.7,代理绕过 = 直连 Tailscale IP)是权威构建 / e2e / 真玩门机;new-api 网关 `http://100.64.0.8:3000`(便宜档主力 MiniMax-M3)。起常驻服务用 `setsid … >log 2>&1 </dev/null &` 完全脱离 ssh 会话;真玩门(run_gates / chrome / esbuild)只在 mini-desktop
## 4 方案与步骤
整体路径是核实 对齐 开闸 复验 放行,每步带验证, live 的步骤标注授权前置control-plane 开闸 **创始人 2026-06-30 裁定 = 选 B:直接 live 开 flag + 回滚兜、不走 staging 先验**(决策点二;staging 重建 executor 会撞 split-brain,隔离不干净不硬上);≥80% 达标复验(S5)走离线 bake_off 取样真实 brief不是 staging 议题
### S0 · 授权与 live 真实拓扑核实(只读 · 不改 live)
创始人授权 + 部署窗口确认后,只读核实 live :48080 当前真实拓扑,不能假设它仍是 6-28 。「live 当前是否仍跑 6-28 Python M3 worker 是否需更新到含 M1 富化的最新代码属只读核实事实(创始人也无从凭记忆确认),不是 open decision,在此核实其结果决定 S1 "对齐更新"还是"重切"。核实项:
1. **拓扑与 flag**:dispatcher 实际值(boot 日志"生成派发通道选定")、worker :9501 健康(`/openapi.json` 或健康端点 200)、`aigc.control-plane.enabled` / `aigc.trace.enabled` 当前值jar 版本DB 指向有无残留 iso 进程V26(idempotencyKey + 唯一索引)是否已落
2. **worker 版本指纹**:取 worker 进程对应工作树的 `git rev-parse HEAD` + 启动日志里的版本/时间戳,与含 M1 富化的 dev/2.0.0(HEAD e6525aaa)逐一比对,坐实 live worker 是否已对齐 M1 富化代码——这是 S1 决定"滚动更新 worker"还是"维持"的依据,不靠假设
3. **GP9 旁路窗口审计**:6-28 cutover 至今 `aigc.control-plane.enabled` 若一直默认 false, GP9 合规先行门一直旁路只读核实这段窗口里 `game_aigc_task` 是否落进过未经 GP9 的真实用户任务是否有违规 prompt 暴露;有则登记 + S2 control-plane 前由审核台轨清零,不把脏数据带进生产口径
4. **live 负例隔离前置**:S2 的配额 / 背压 / GP9 负例验证会向 live 投触发性请求,核实阶段先约定隔离策略——用固定测试账号 / 带标记的 projectId(便于过滤与回收),并定义验证后清理 SQL,防止把违规 brief假任务误伤打到真实请求或留进 S5 采样池
- **交付物**:live 当前拓扑核实报告(dispatcher / flags / worker 版本指纹 / jar / DB / V26)+ GP9 旁路窗口审计结论(有无脏数据 + 清零计划)+ 负例隔离与清理约定
- **验证**:只读 ssh boot 日志 + 健康端点 + 配置 + DB schema + `game_aigc_task` 窗口查询;绝不改任何 live 配置或进程,审计查询只读
- **依赖**:创始人授权 + mini-desktop / live 可达
- **风险**:live 已漂移( Node / worker / jar / worker 版本落后于 M1 富化),S1 据此分支;GP9 旁路窗口若有违规 prompt 暴露,清零后再开闸
### S1 · 路由态对齐 + worker 更新到 M1 富化(触 live · 需授权窗口)
S0 结果分支, live 对齐到" M1 富化的 Python M3 ":
- live 仍是 6-28 Python 路且健康:确认 worker 代码是否需更新到含 M1 富化(生成质量提升) dev/2.0.0;需则按既定机制(`git fetch && checkout origin/dev/2.0.0` + `setsid` 起新 worker + 端口精确切换)滚动更新 worker, worker 在途任务跑完再退
- live 已漂移回 Node 或不健康:跑 `retire_authorization` 授权门(`authorized=True` 前置), M3a 既定机制重切(`dispatcher=http` + `worker-url` + 重启),复用既有全局 flag零新路由代码
切换 / 更新走应用重启,在途任务靠 `AigcGenerateExecutor` 既有 DB 扫描 + CAS 认领 restart-safe(不强杀),已派发到 worker 的任务 worker 仍异步回调端口操作一律精确(`fuser -k <port>/tcp`),绝不 global pkill
- **交付物**:live Python M3 worker 对齐最新代码拓扑确认
- **验证**:boot 日志 dispatcher=http;worker 健康;真投一个便宜档创作请求经 worker 真跑 result-out 真回调 后端落终态(沿用 M3a/M3b 真验范式)。
- **依赖**:S0;retire_authorization `authorized=True`;授权窗口
- **风险**:重启级切换粒度粗(D3 取舍),便宜档单次部署级切换可接受;回滚同为翻 flag + 重启6)。
### S2 · 开 control-plane:D12 四门 + GP9 + 待拍配额(staging 见决策点二 → live)
`aigc.control-plane.enabled=true`, D12 四门 + GP9 真生效;落创始人拍定的配额 / 背压 / 降级阈值;D12 额度记账骨架接线(真扣费留 M4)。
`AigcControlPlaneConfiguration` `@Configuration` + `@ConditionalOnProperty(aigc.control-plane.enabled=true)`,条件在应用 boot 期求值——只改配置不重启,Bean 仍缺席`AigcTaskServiceImpl` ObjectProvider 拿到空四门 + GP9 继续旁路故开闸是一套有序动作,任何一步漏了都会假绿:
1. **配置落盘**:`aigc.control-plane.enabled=true` + 配额 / 背压 / 降级阈值5 待拍数值表)+ safety new-api base/key/model
2. **重启 game-cloud**:条件装配 boot 期求值,不重启 Bean 不装配(`generationDispatcher` 翻转同样重启级,可同窗口做)。
3. **确认 control-plane 真装配**("只改配置不重启"假绿):boot 日志见 `AigcControlPlaneConfiguration` / `aigcSafetyCheckClient` Bean 注册,或经接口行为确认——投一个超配额请求,看是否真返 `AIGC_QUOTA_EXCEEDED`(而非旁路放行)。这一步是后续四门验证的前提,单列"control-plane Bean 已装配"作收口证据
4. **再跑四门 + GP9 负例**:Bean 装配确认后才验门效
- **交付物**:control-plane live 真装配(Bean 已装配证据单列)+ 配额 / 背压 / 降级阈值落定 + 记账骨架记录占位额度
- **验证**:Bean 装配确认后,验四门拒绝走业务码 HTTP200(`AIGC_QUOTA_EXCEEDED` / `AIGC_BACKPRESSURE_REJECTED` / `AIGC_GENERATE_PAUSED`)+ GP9 10 负例 100% `safe=false` / 0 入队 + fail-closed(安全检查超时抛中性 `AIGC_LLM_SAFETY_ERROR`);非阻断硬约束不破(降级门读配置失败 fail-open 放行)。负例投递走 S0 约定的隔离测试账号 / 标记 projectId,验后按清理 SQL 回收
- **依赖**:S1;创始人落定配额阈值5 待拍数值表);staging 先验的隔离前置见决策点二
- **风险**:漏重启 = Bean 缺席 = 四门旁路假绿 步骤 3 Bean 装配确认前置;阈值过紧误伤正常用户 保守起步 + 开闸回滚可独立关6);阈值过松失去保护 配额 / 背压按并发 15 容量画像设
### S3 · trace / D11 / D9 生产态 + 权重阈值起步值落定(触 live 配置)
确认 `aigc.trace.enabled=true`(6-28 已开,S0 核实); D11 四维权重(当前 0.5/0.25/0.15/0.1 占位)、`BUDGET_RMB` 效率维阈值(当前 0.15,与便宜档真实成本 ¥0.41.2 错配效率维恒 0 零区分)、D9 模糊相似阈值(当前仅精确撞重)各落定一个起步值真正的校准要质量轨拿真实生成数据迭代, plan 只落"先用什么值起步 + 怎么观察校准",不声称已校准到位
- **交付物**:trace 落库在 live 生效;D11 权重 + `BUDGET_RMB` + D9 阈值起步值落定 + 观察校准方案
- **验证**:生产真实生成的 `trace_json` 七项齐`readiness_score` NULL 且逐维真信号(playability / firstPlay / stability 脱离中性 0.5);故意喂坏 trace 看主链仍走到终态(non-blocking 复验)。
- **依赖**:S1;质量轨提供权重校准输入(可后续迭代)。
- **风险**:`BUDGET_RMB` 不校准则效率维对便宜档零区分力,审核台就绪分排序失真 起步值取便宜档成本中位列入待拍
### S4 · 端到端 e2e 生产复核(staging 见决策点二 → live 小流量观察)
control-plane 开启后,把全门链路在生产态复核一遍:创作页一句话 D12/GP9 入口门 Python worker 生成 九门 回调七步 D11/D9/trace 落库 落到可发布预览包生成线部分 M3b 已验,本步是 control-plane 开启后的全链路生产复核(`publish→feed→真玩` 属产品轨,本步到预览包就绪为止)。本步在 S5 种子受控内测之前,真实创作者尚未放开(W-CLEAN),故用 S0 约定的隔离测试账号投递,不依赖真实创作者流量
- **交付物**:生产态端到端链路证据( brief 到预览包 + D11 + trace + 六门入口生效)。
- **验证**:staging 先跑通(隔离前置见决策点二),live S0 隔离测试账号小流量观察少量请求;真浏览器确认产物走 `__GameBundle.bootGameHost` 真引擎非兜底壳( /gstack, mini-desktop)。
- **依赖**:S2 + S3
- **风险**:e2e stub 通道假绿 真浏览器真玩为准(R-D 教训)。
### S5 · 种子受控内测 → 生产真实分布 ≥80% 达标复验(lab→prod 口径升级)
M1 lab 代表样本口径(20 款约每品类 7),M3 交付定义要求生产真实 prompt 分布下 80% 复验真实 brief lab 更杂可能更难这里有一个先有鸡还是先有蛋的约束必须先解:对外放量在 S6排在 S5 之后, W-CLEAN 下创作页对真实创作者尚未放开,S4 又只跑内部测试账号——放量之前 live `game_aigc_task` 里只有内部测试任务,采不到种子用户的真实 brief直接声称 S5 已是生产真实分布口径,是假绿
解法是在 S5 内插一道**种子受控内测**作为放量前一档,真实 brief 由它产生:
- **S5a · 种子受控内测(放量前一档)**:在备案外测红线内(外测前 2 万人不接广告报备删档)向一小批种子用户放开创作页,让他们真实提交 brief,积累一段时间窗的真实分布这是 S6 全面放量之前的受控暴露,合规边界与放量约束同源(备案,法务运营轨)。它跑在已切的 live Python 路上, live executor split-brain;产生的任务即 S5b 采样源
- **S5b · 生产真实分布 80% 复验**:对 S5a 积累的真实 brief 按下方抽样协议取样, `bake_off.py` 同款判定复验。**退路(诚实口径)**:若种子内测尚未跑或样本不足,S5b 先用 M1 lab 代表样本复验,报告里明确标注"生产真实分布达标待种子内测 / 放量后回填",不把 lab 结果冒充 prod 口径——S6 放行据此知道这一项是 lab 证据还是 prod 证据
**抽样协议(钉死,防选择性取样自证)**: 固定 SQL / 导出脚本(纳入交付物,可复跑);② 明确时间窗(起止时间戳);③ 去重 key(brief 文本归一后哈希,同人重复提交只取一条);④ 违规 brief 剔除规则( GP9 判定 / 人工标记的违规项不进样本);⑤ 品类判定字段与规则( `templateId` / brief 关键词映射到 click-score / whack-mole / shop-serve + 后续品类,判定规则写死);⑥ 样本冻结哈希(取样后对样本集算哈希冻结,复验与报告引同一哈希,防中途换样);⑦ 失败分类标准(区分"编排未收敛"不计入质量分母单列,"九门质量挂"计入失败);⑧ 报告附完整样本清单 + 逐条 verdict(brief 品类 是否收敛 九门结果),可逐条复核
- **复验方案**:用样本 brief `bake_off.py`(`run_studio`自动 spec九门 verdict.pass),逐品类 0.8核心品类全覆盖绝不用总体平均掩盖卡死品类(对齐 002 按品类口径)。bake_off 只读取 brief 文本离线再生成(自带 gameId 品类前缀conc15串行 / 有界并发报告不覆盖),不认领 live 任务不与 live executor
- **交付物**:种子受控内测开闸记录 + 生产真实分布按品类达标复验报告(含抽样协议产出的 SQL / 时间窗 / 冻结哈希 / 样本清单 + 逐条 verdict);若走退路则标注 lab 口径与回填计划
- **验证**:逐品类 80%;不达标则定位根因——驱动侧回 WU-C 5.4,生成侧回质量轨 WU-B/C/F, plan 不堆改生成
- **依赖**:S4(生产态链路通)+ S5a 种子内测积累真实流量(受备案外测红线约束);bake_off.py(已有)。
- **风险**:生产分布不达标 路由可保持 Python(已切),但放量门(S6)不放,质量轨补齐后再复验;种子内测样本不足 lab 退路并明标待回填,不放量;这是 labprod 的真实风险,plan 不假设必过
### S6 · 6 门放行证据 + 对外放量决策(创始人裁定)
汇总 6 门生产证据,交创始人按 `验收门.md` §6 做放行决策(放行优先于任何自动门)。
- **6 门生产证据**:D12(四门拒绝业务码 HTTP200,control-plane 开启后实证)/ GP9(负例 100% )/ 9d trace(七项落库)/ D11(逐维真信号)/ D9(撞重告警不拦)/ 首局体验(harness verdict)。
- **放量约束**:灰测红线受备案约束(外测前 2 万人不接广告报备删档),备案是法务运营轨的外部前置
- **放行检查单增补(2026-07-04 知识面审计)**:放行前须确认**品类路由已接线,或显式接受降级**。事实:live Service 创建路 `cheap_service_driver.py:219-222` 硬编码 `scaffold_template=None`,不选品类骨架不透传 genre——W-GENRE 四件套(品类 skill/骨架/few-shot/评分尺)在生产 create 路不通电; S5 复验走 `bake_off.py` 是显式传品类的(bake_off.py:143),**复验口径与放量后生产口径不同轨**。两解任一: briefgenre 路由(最小=模板选择+genre 透传, W-S1 三单同窗);② 创始人显式接受首窗放量=通用模板、品类件后窗接线」并记入放行决策。不确认即放行 = 复验证据不代表生产行为
- **交付物**:6 门生产证据表 + 放行决策记录
- **验证**:6 门逐门 PASS 证据;回滚预案演练过一次6)。
- **依赖**:S2S5 全绿 + 备案状态(法务轨)。
```mermaid
sequenceDiagram
participant 创始人
participant Ops as Ops/部署
participant Live as live-48080
participant Worker as cheap-worker-9501
participant Stg as staging-minidesktop
创始人->>Ops: 授权 + 部署窗口
Ops->>Live: S0 只读核实拓扑(不改)
Ops->>Live: S1 对齐路由 + 更新 worker(授权窗口)
Ops->>Stg: S2/S3 staging 先验(隔离·见决策点二)
Stg-->>Ops: 四门/GP9/trace 证据
Ops->>Live: S2/S3 开 control-plane(重启生效)+ 配额 + 起步阈值
Ops->>Live: S4 e2e 生产复核(隔离测试账号)
Live->>Worker: 测试请求 → 生成 → 回调
Ops->>Live: S5a 种子受控内测(备案外测红线内,产真实 brief)
Ops->>Live: S5b 采真实 brief → bake_off 按品类 ≥80% 复验
Ops-->>创始人: S6 6 门证据表(标 prod/lab 口径)
创始人->>Live: 放行决策 → 对外放量(受备案约束)
```
## 5 决策点汇总(交创始人裁定)
### 决策点一 · 路由切换策略【已定 D3 整体翻转 · 仅余 SoT 对账,非待裁】
这条不需要创始人重新裁决路由策略 2026-06-28 已定 D3(全局 dispatcher flag 整体翻转不做 per-request 灰度)且当日执行完毕,正确性对等已被 M2 三门验绿;按比例灰度(在单 dispatcher 架构里新造按 key hash 的分流 seam)已被双评审两家判为 BLOCKER 级新增复杂度不采列在这里只为一件收口事:plan 残留的灰度措辞与已定 D3 冲突,需对账扫净
- **已做**:plan §119 迁移安全契约的"路由 feature flag"条目已加 2026-06-30 校正( D3 整体翻转"按比例灰度放量"措辞作废)。
- **待扫净(收口 TODO)**:plan §119 段标题"灰度迁移"、其内 line 124"不抬灰度比例"、line 110"灰度切换基础设施"仍残留灰度措辞,与已定 D3 半冲突,需一并改为"整体翻转 / 小流量观察"口径,否则 canonical 留半漂移
> 迁移契约其余条目(幂等 key 防双扣 / 在途任务不强杀原路跑完 / D12 扣退两路同语义 / 回滚触发 = 成功率或九门通过率掉则切回 Node / 对照验证 / A2A 六态前端无感)在整体翻转下都适用,已在 §3、§4、§6 照写。
### 决策点二 · control-plane 开闸:staging 先验 vs 直接 live(split-brain 是真约束)
M3b 拆掉 iso :48090,正是因为 live + iso 两个 executor 连同一个 DB 13306都扫描并 CAS 认领 generic 任务,抢同一批任务 = split-brain。重建 staging 先验若不解决这一点就会重现它先把两件事拆开:control-plane 是机制门(配额 / 背压 / GP9 / trace),≥80% 复验(S5)是离线 bake_off 取样真实 brief只读 live 自带 gameId 前缀再生成,根本不认领 live 任务不进 staging 议题所以"staging 先验"的真实范围只有 control-plane 机制门
- **选项 A · staging 先验 control-plane 机制门(需隔离,有条件推荐)**:在 mini-desktop 重建一个 executor 验四门 + GP9 + trace。**硬前提**:它必须连独立 DB / schema(或配置成不认领 generic 任务),否则连回 13306 = 重现 split-brain即便隔离干净,它只验机制不验 live 的真实配置与数据, S2 步骤 3 live Bean 装配确认 + live 四门复核仍是必须的,staging 不替代 live代价:多搭一套隔离环境;且独立 DB staging 拿不到 live 真实分布(那本就归 S5不归这里)。
- **选项 B · 直接 live flag + 回滚兜(隔离不可行时改推荐)**:control-plane 默认 false = 旁路现行行为,开了出问题可独立关回(关也需重启,见 §6.1)。负例验证走 S0 约定的隔离测试账号 + 清理 SQL,把误伤面圈在测试账号内,不打到真实请求若窗口内搭不出干净隔离的 staging executor, B 比硬上一个会 split-brain staging 更稳——不把会重现 split-brain A 当无条件推荐
- **✅ 创始人裁定(2026-06-30):选 B** —— control-plane 机制门直接在 live (配置落盘 重启 game-cloud Bean 装配 四门/GP9 负例走 S0 隔离测试账号),不走 staging 先验;出问题独立关回 false(需重启6.1)+ 一键翻 flag Node 兜底S2/S3/S4 下文"staging 先验"分支不采用,只保留其 live 执行与回滚路径
> live 当前态(是否仍跑 6-28 Python 路、worker 是否需更新到 M1 富化)原列为决策点三,已重归类为 **S0 只读核实事实**(创始人无从凭记忆裁,只能核实)——见 S0 核实项 2「worker 版本指纹」,其结果决定 S1 走"对齐更新"还是"重切"。
### 决策点三 · 待拍数值表(填起步值 · 含取舍影响)
起步值按已有容量画像与代码默认填定,留创始人改每行的取舍影响是同一句话的两端:取小则误伤正常用户 / 取大则失去保护
| | 当前值 | 推荐起步 | 取舍影响 / 备注 |
|---|---|---|---|
| 会员档配额(每人每日生成数) | L1 占位 = 10 / 并发 1(`AigcControlPlaneProperties` defaultQuota) | MVP 统一 L1维持日 10 / 起步(保守内测后放宽) | D12 配额门;取小则误伤迭代型创作者,取大则防刷削弱 |
| 并发上限 | 15(已定硬上限) | API conc=12 实测 OK;本地 worker N=46 起步 | 创始人 2026-06-26 已定 15;取小则吞吐不足排队,取大则撞 CPU 突发上限 |
| worker 内部队列深度 | `DEFAULT_QUEUE_MAXSIZE=8`(已在码) | 8 维持,压测后调 | 背压吸收队满 503;取小则突发易 503,取大则积压时延拉长 |
| D12 背压全局队列深度 | `queueDepthLimit=50`(default) | 50 起步( 15 并发 + 缓冲) | 守全局串行 worker;取小则正常突发被拒,取大则失背压保护 |
| D11 四维权重 | 0.5/0.25/0.15/0.1(占位) | 维持起步,质量轨真实数据校准 | 非阻断起步值不影响放行门;可后续迭代 |
| `BUDGET_RMB` 效率维阈值 | 0.15( ¥0.41.2 错配效率维恒 0) | ¥0.6(便宜档成本中位) | 取小则正常成本被判超支扣分,取大则失成本区分力 |
| D9 模糊相似阈值 | 仅精确撞重 | 维持精确撞重起步,真实分布后定模糊阈值 | observe-only 不拦截非阻断 |
| per-gen 成本闸 | 10(已定) | ¥10 | reframe 口径,已接线 fail-closed |
| 生产分布样本量 | 未定 | 每品类 20(对齐 bake_off 20 款代表样本量级) | S5 80% 复验分母;取小则统计力不足易误判达标 / 不达标,取大则采样与复验成本高 |
## 6 风险与回滚
### 6.1 回滚预案(分层)
回滚分三层,可独立触发,从轻到重:
- **开闸回滚( · Python )**:`aigc.control-plane.enabled` 关回 false D12/GP9 旁路 6-28 已切的现行行为;`aigc.trace.enabled` 可独立关。**关也需重启 game-cloud 才生效**——这个开关是 boot 期条件装配(`AigcControlPlaneConfiguration`),不是热开关,关了不重启 Bean 仍在席门仍生效重启窗口内新请求短暂被挡(同部署窗口),排低峰做用于"开闸后阈值误伤 / 门误判"。
- **worker 版本回退( · Python worker 版本)**:新 worker(本轮 M1 富化或后续更新)引入 regression Python 框架本身无恙想保住 Python 路时, worker 退回 6-28 已验过的旧 commit + `setsid` 起旧 worker + 端口精确切换,不动后端 dispatcher用于" worker 代码级 regression框架无恙"。
- **路由回滚( · Node)**:`dispatcher=saa` + `saaSourceMode=amodel` + 重启 新进任务全回 Node 旧路(代码原样保留活跑),在途任务 restart-safe 不强杀原路跑完落 verdict用于"成功率回退 / 九门通过率掉 / Python 框架级稳定性问题 / 成本异常"。
**在途回调幂等(回滚瞬间的承重验证)**:翻 dispatcher 或退 worker 的瞬间,已派发到 Python 的在途任务仍会异步回调回滚演练必须含这一项:制造一个 Python 长任务派发后立即翻 `dispatcher=saa` 并重启,确认旧 Python 回调仍按 taskId/traceId 幂等落库(job traceId 幂等防回调重入)——不生成二次任务不双扣不被 Node 路结果覆盖这是回滚不丢数据不双跑的承重断言,缺它回滚就是半套
**回滚资产清单(防"翻了 flag 也回不去")**:翻 flag 的前提是上一版可信产物还在手开工前固定登记并校验: 上版 game-cloud jar(6-28 M3 可信态)+ 其路径与校验和;② 对应配置备份(`application-staging.yaml` ,含回滚态 flag )+ 路径;③ 6-28 已验 worker commit hash;④ 各层恢复命令(jar 替换 / 配置还原 / 端口精确切换),逐条可复跑防的是新 jar 本身异常时,光翻 flag 无法把 live 恢复到 6-28 那个可信态
```mermaid
flowchart LR
NODE["Node 旧路态<br/>dispatcher=saa + saaSourceMode=amodel"]
PY0["Python 未开闸态<br/>dispatcher=http + worker-url + trace<br/>(6-28 已切)"]
PY1["Python 已开闸态<br/>+ control-plane + 配额阈值<br/>(本 plan 目标)"]
GO(("放行放量"))
NODE -->|"6-28 cutover"| PY0
PY0 -->|"本 plan S2/S3"| PY1
PY1 -->|"开闸回滚:关 control-plane + 重启"| PY0
PY1 -->|"路由回滚:翻 dispatcher + 重启"| NODE
PY0 -->|"路由回滚:翻 dispatcher + 重启"| NODE
PY1 -->|"S6 放行(受备案约束)"| GO
style PY1 fill:#fef9e7
style GO fill:#a9dfbf
```
```mermaid
flowchart TD
MON["监控信号"] --> Q{"哪类异常?"}
Q -->|"门误判/阈值误伤"| L1["关 control-plane + 重启<br/>(轻 · 保 Python 路)"]
Q -->|"新 worker regression<br/>框架无恙"| LM["退回 6-28 worker commit<br/>(中 · 保 Python 路换版本)"]
Q -->|"成功率回退/九门通过率掉<br/>/框架稳定性/成本异常"| L2["翻 dispatcher 回 saa+amodel + 重启<br/>(重 · 新进回 Node)"]
L2 --> SAFE["在途 restart-safe 不强杀 + 回调幂等<br/>Node 旧路原样活跑"]
LM --> OBS
L1 --> OBS["回现行行为 · 继续观察"]
```
### 6.2 风险
- **R1 · live 当前态未知**:不能假设仍是 6-28 S0 只读核实前置,S1 据实分支
- **R2 · 生产分布比 lab 、≥80% 可能不达**:这是 labprod 真实风险缓解 = 路由可保持 Python(已切),放量门不放不达标回质量轨 WU-B/C/F,达标后再复验 plan 不假设必过
- **R3 · control-plane 阈值误伤**:配额 / 背压过紧拒正常用户缓解 = staging 先验(隔离前提见决策点二)或直接 live flag + 保守起步 + 负例走 S0 隔离测试账号 + 开闸回滚可独立关(需重启)。
- **R4 · 真扣退缺口(M4)**:D12 记账骨架先顶(占位 + 日志),真扣费 / 失败退费留 M4(new-api UserId 阻塞)。 plan 标清边界不假装做了真扣退
- **R5 · 移交边界混淆**:`publish→feed→真玩`(产品轨)、生成质量内核(质量轨)易被揽进生成线 cutover缓解 = §2 划清,生成线交付到"可发布预览包 + 生产 80% 复验"为止
- **R6 · 重启级切换粒度粗(D3 取舍)**:全局翻转非热切缓解 = 便宜档单次部署级切换可接受 + 在途 restart-safe + 回滚同机制;per-request 灰度是 deferred 退路
- **R7 · 端口操作误伤 live**:iso / worker 操作绝不 global pkill,一律 `fuser -k <port>/tcp` 端口精确(M3a/M3b 铁律)。
- **R8 · 过门不等于好玩(继承 plan R6)**:九门是机制地板,好不好玩归人工终审 + L3 视觉软检
## 7 验证方式(里程碑收口判据)
- **S0**:live 拓扑核实报告产出(dispatcher / flags / worker 版本指纹 / jar / DB / V26)+ GP9 旁路窗口审计结论 + 负例隔离与清理约定,全程只读
- **S1**:live boot 日志 dispatcher=http + worker 健康 + 真请求经 worker 真跑真回调落终态
- **S2**:control-plane Bean 装配确认(boot 日志 / 接口行为)前置成立后,staging + live 四门拒绝业务码 HTTP200 + GP9 负例 100% + fail-closed + 非阻断不破
- **S3**:生产 trace_json 七项齐 + readiness 逐维真信号 + non-blocking 复验
- **S4**:生产态端到端链路证据(brief 预览包 + D11 + trace) + 真浏览器真引擎( stub)。
- **S5**:种子受控内测开闸记录 + 生产真实分布按品类 80% 达标复验报告(逐品类绝不平均掩盖,含抽样协议产出与样本清单; lab 退路则明标口径)。
- **S6**:6 门生产证据表 + 回滚演练一次干净 + 创始人放行决策记录
- **里程碑级**:live Python M3 + control-plane 六门实证 + 生产 80% 达标 + 6 门放行 + 一键回滚就绪 = 便宜档对外可放量上线(放量本身受备案约束、由创始人放行)。
## 8 双评审 TODO 与跨文档对账
plan 收口前过双评审门(Codex + Opus,Codex 挂回落 Opus 单评)。开工前需横切一致性主人(创始人 + 6c6g 文档/设计线)裁定的对账项:
- **状态矛盾对账(头号)**:M3b 留痕记 dispatcher 路由 cutover 已于 2026-06-28 完成, plan §M3 line 133 memory 仍当未做请确认 live 真实状态,并把"cutover 已部分完成"回写 plan 切片一现状 + MVP 进度总账 + memory3.1 / S0)。
- **M1 达标状态对账**:plan §75 / §104 早期记的"M1 未过 / 五款 3/5卡两类品类生成幻觉"已于 2026-06-30 校正为达标104 已带校正注 + `bake-off-M1-rich.json`)。 plan M1 达标推进1.1 / §3.4 引同一证据)——确认这条已收敛,后续引用不要再回退到 3/5 旧口径
- **plan §111 "D12 扣退真接线"措辞更正**:§111 现写 M3"game-cloud 后端路由 flag D12 扣退真接线"。据验收门 SoT,真扣退 / 补偿(按量扣费 / 失败退费)划归 M4(new-api UserId 阻塞MVP 无真支付),本里程碑只做记账骨架(占位 + 日志, §2.2)。§111 "真接线"措辞需更正为"记账骨架接线真扣退留 M4",免得读成本里程碑已交付真扣退
- **plan §111 "feed真人试玩端到端打通"措辞更正**:§111 现把"创作页 生成 九门 发布门 feed 种子用户真人试玩端到端打通"算进 M3 生成线这条已收缩移交产品 / 审核台轨( plan §2.2 已划清接收方),生成线交付到可发布预览包为止。§111 措辞需更正, feed 真玩划出生成线 M3
- **SoT §119 灰度语言更正(canonical-uniqueness)**:plan §119 "路由 feature flag"条目已加 2026-06-30 校正; §119 段标题"灰度迁移"+ 段内 line 124 / line 110 残留灰度措辞仍需一并扫净(决策点一)。
- **待拍数值表**:配额 / 背压 / D11 权重 / `BUDGET_RMB` / D9 阈值 / 样本量交创始人5 决策点三)。
- **移交边界对账**:`publish→feed→真玩`(产品/审核台轨,接收方见 §2.2)、生成质量内核(质量轨 WU-B/C/F)、真扣退(M4)、16 周日历闸门(法务运营轨)归属确认,回填 MVP 进度总账时据此反查不重复计入
- **生成丰富度新缺口**:plan §2 浮现的"能跑能过九门却偏薄"缺口归质量轨;若它压低生产 80% 复验,S5 不达标根因可能在此,需与质量轨并联
## 附 · 图清单与状态
| | 媒介 | 状态 |
|---|---|---|
| 图1 三段定位总览(已完成/本plan/移交) | Mermaid | 已出 |
| 图2 路由 flag 状态机 | Mermaid | 已出 |
| 图3 cutover 时序 | Mermaid | 已出 |
| 图4 回滚触发流 | Mermaid | 已出 |
| §0 SVG 概览门面 | SVG | 后补(text+mermaid 优先) |
> **状态**:已批准(创始人 2026-06-30 · 双评审收口,以 frontmatter 为准;本行原「draft 待审批」尾注过时,2026-07-02 更正)。**尚未执行**——未碰 live、未写代码;执行从 S0 起,需创始人授权 + 部署窗口。承重事实(路由机制 / flag 默认值 / 6 门 / 工具 / 6-28 cutover 留痕)均经代码与文档核实并标注来源。
>
> 2026-07-02 对账与执行提示〕① §8 要求的 plan① 措辞更正已由横切一致性主人执行:灰度残留扫净(§迁移安全契约四处)、§111「D12 扣退真接线」改记账骨架、「feed→真人试玩端到端」划归产品/审核台轨;cutover 既成事实已回写 plan① 与进度总账。② **S1 worker 版本口径**:配置控制面阶段一②(cheap 归并 Service,待创始人终评审→SDD)也要动 cheap-worker——若它先落地,live worker 一次更新到含 Service 壳的版本,避免两次动 live;版本口径在 S0/S1 核实时与创始人确认。③ 执行模式 = opus 会话 plan 模式领本 plan → goal/ultracode 自治执行+自审(六要素已在 S0S6 各步);没全绿报 BLOCKED,不谎报 DONE;触 live 步骤逐步报。
## 9 执行记录(2026-07-03/04 窗口 · fable 主持 · 创始人全权授权下自主批,S6 放行仍留创始人)
执行环境:mini-desktop(100.64.0.7),live 后端 :48080(6-28 jar,不换 jar 只加 flag),worker :9501 + cheap Service :8300 部署树 `/root/tier2-run`每步证据都来自真实日志 / 真实 HTTP 响应,无合成
### S0 · 只读侦察(✅ 2026-07-03)
live=6-28 jar 健康dispatcher=http、trace control-plane ;worker 9501 已死(S1 重拉);GP9 旁路窗口零真实用户流量回滚资产清单落 `/root/cutover-rollback-s0.md`(jar md5 指纹 f4697418…、启动命令三层回滚命令worker 回退树 tier2-cv@eed34d0a)。
### S1 · 对齐 worker(✅ 2026-07-03,抓获真 bug 一枚)
两进程部署 @最新主干并真验回调闭环。**真验局 1 抓获生产 bug**:worker 门面路 `_service_run_fn` 惰性导入 driver 时漏接 `_bootstrap` sys.path 接线 `ModuleNotFoundError: No module named 'worker'` 兜底 failed 回调(干跑 import 测不出:先导 cheap_service_app 会顺带接好路径,门面路单独走才踩)。修一行 + 回归 15/15,commit `dbfe4090`真验局 2(80007,shop brief)证:生产 genre 路由真命中(`品类路由命中:genre=sim-business template=_template-shop`)、menu 起局修复生效(phaseNow=play)、两段式预算硬地板 fail-closed14.90 > ¥15 硬地板前最后一次预估拦停)、诚实 failed 回调落终态。
### S2 · 开 control-plane(✅ 2026-07-04)
- **重启带闸**:`restart-48080-s2.sh`(同 jar + `--aigc.control-plane.enabled=true` + safety.api-key;`off` 参数=开闸回滚)。首启踩坑:S0 环境快照只采到 PATH(采集不完整),DB 密码丢失 → boot 失败 Access denied;**修正=真环境源 `/root/game-staging/infra/.env`**(6-28 旧进程同源,MYSQL_ROOT_PASSWORD/REDIS_PASSWORD 等),脚本已改 source 它。二次启动 17.7s 健康。
- **Bean 装配核验(防假绿前置)**:boot 日志无 control-plane 行、actuator/beans 未暴露 → 用功能实证:GP9 负例中 `SafetyCheckClient:193` 真跑(M2.7 判 safe=false,4783ms,attempt=1,含「提交侧合规成本独立于生成预算」归因日志)= Bean 在席且工作。
- **GP9 违规 prompt 负例**:真钱赌博类 brief → `runSafetyGate``1101001004`(拒绝理由由审核模型给出),**零派发零生成成本**。良性星星 brief 同日过 safety = 误杀防线同证。
- **并发负例**:绿腿在飞时第二提交 → `门①并发位满 在飞=1 上限=1 → 拒 1101001001`,拦截点在 quota 记账与 safety 调用**之前** = 拒绝零 LLM 成本,成本排序正确。配额记账骨架走通(`当日已用(过门前)=2 日上限=10`)。
- **发现并修:studio 包裹拒绝码**:三类型化拒绝到 HTTP 层被 `StudioServiceImpl` 一刀切包成 `1112002000 生成委托失败`,创作者看不到「Prompt 不安全/额度已满」。修=透传三码(集合引 aigc ErrorCodeConstants SoT,非透传异常行为一字不变),单测 35/35(31+4),commit `f9b85d42`;**本窗口不换 jar,该修随下轮 jar 轮换生效**,S2 断言以 aigc 层日志为准。
- **绿腿 e2e 首跑(80009)失败 → 抓获熔断观测盲区**:stuck 熔断「连续 4 次工具失败(签名=error)」¥2.60/252s 拦停,但**签名恒为裸状态值、不带工具名/错误文本,事后无从归因**(trace 瘦骨架无工具名、Redis 会话崩溃未 flush、结果文件只 dump 大结果——四路取证全空)。修=签名富化(工具名+状态+归一化错误头,长 hex/数字→#)对齐设计意图「同错反复才判死圈」,异类 4 连败不再误熔断(交 step_cap/¥ 闸/timeout 兜底)+ 每次工具失败即时打印。单测 5 新增、tier2 90/90,commit `5afb9823`
- **签名富化当场破案 → 抓获本窗最重缺口:Service 内建工具面击穿写白名单**:绿腿复跑(80011)的失败打印给出完整目录——内建 `Bash`(cwd=Service 工作区,M3 惯性相对路径 `ls game-runtime/...` 连败)、`Grep` 同款、`ToolStop`(幻觉任务 id)、**我们的 `read_file` 被按框架 `Read` 的参数模式调(`limit` kwarg)**、内建 `Edit` 连败(read-first 约束 + old_string 缺参)。根因:agentscope 2.0.2 Service 路 `build_toolkit` 把 workspace 内建(Bash/Edit/Glob/Grep/Read/Write)无条件并入 agent 工具面——**内建 Write/Bash 不走六工具写白名单 = 护城河旁路**,且 12+ 工具重叠语义是混乱税本体(CLI 路从来只有六工具,Service 归并带进此面,per-task review 未抓、live 观测抓获=「跨路径封口」教训再证)。修=第三块钉版本补丁 `ws_builtin_tools_patch`(进程内关内建;本进程只跑便宜档,作用域恰好;tier2 独立进程不影响),单测 3/3,commit `a6d5c29a`;Planning/Team/Schedule 工具面收窄记工单 (h)(成本上界已有 ¥ 硬地板兜)。
- **80011 终态 = 兜底链组合生产实证(¥12.24 买到)**:14 次异类工具失败**零误熔断**(新签名行为正确)→ 3 attempts / 2 repairs → 软停线 ¥10 触发(softTripped=True)→ **step_cap(>150 步)硬兜拦停** → 诚实 failed 回调落终态。熔断四道 + 两段式预算 + 诚实回调的组合在生产按设计协同。绿腿第三跑(80012)在干净工具面上进行。
### S4 · 端到端 e2e 生产复核(✅ 2026-07-04,绿腿三跑而成——每次失败都换回一个真修)
**绿腿终绿(80012 / chain 180 / task 200 / version 93149)**:干净工具面上 brief→受理→M3 生成→九门→**1 轮 C6 续修真转并修活**→成功回调→版本落库,全程 **attempts=2 / repairs=1 / ¥2.13 / 428s**,工具失败打印 **0 次**(对照 80011 同 brief 在旧工具面 14 次失败 ¥12.24 flail——工具面封口的降本证据就是这组对照)。产线证据逐项:
- **trace_json 七项+**:attempts=2 / repairs=1 / cost / gameId / gatespec{driver:key-cycle} / models / pass / sevenGateVerdict / similarity / stage / wallS 全齐(DB `game_aigc_task` id=200 实读)。
- **D11 readiness_score=86**:远离退化带(45)与失败带(28),三值判别在真生产续证。
- **预览包承重**:`game_runtime_package` version_id=93149,bundle_size=243628、sha256 checksum、entry=index.html、sandbox_attr=allow-scripts;package_json 内 **engineBundle 238KB 含 `__GameBundle`**(M3a 承重字段)、gameConfig 占位(engineDriven/templateId/theme/title)、assets/manifest/meta/provenance 齐;sourceProject absent=契约内 best-effort(modify 路走 worker 本地 amgen-<id> 源)。status=0 未发布 = 发布审核归产品/审核台轨,生成线交付到此为止(界清)。
- 玩家侧 `runtime/package/{vid}` 拒「运行包未发布」= 发布门未开时玩家不可达,**正向验证了发布闸**。
### S3 · 起步值落定(✅ 2026-07-04 对账)
代码默认即决策点三起步值,无需改配置:L1{日 10, 并发 1} / L2{50,2} / L3{200,5}(占位待创始人 §5.4)、queueDepthLimit=50、safety fail-closed=true、审核模型 MiniMax-M2.7(网关在列已核)、baseUrl=new-api mini-infra。**`BUDGET_RMB`(¥0.6)裁定随 Node 路废止**:Python 路预算=genconfig 两段式(cheap 软停线 ¥10 / 硬地板 ¥15),S1 真验局 2 已实证 fail-closed,该起步值不再有生效路径。
### A11 计费真后端 e2e(决策④与③同窗并 · 2026-07-04 在跑)
- **jar 轮换(A11 的腿,授权=决策④)**:A11 端点(/modify/plan)是切片三代码(06-29 合),6-28 jar 里没有(实测 404)→ 按决策④「可与③同窗并」构建新 jar @`2a8d5e45` 上线(studio 透传 f9b85d42 随批生效);旧 jar 备份 `/root/game-staging/huijing-server-6-28.jar.bak`(md5 f4697418…)= 回滚资产。
- **新 jar 首启双杀 → Nacos 凭据缺**:新 jar 带阶段〇 Nacos 接线(6-28 jar 没有),`${NACOS_PASSWORD}` env 缺 → 登录 403「user not found」→ 注册 failFast → 进程静默退出(两次)。修=NACOS_PASSWORD 入 `/root/game-staging/infra/.env`(真值在内网凭据档「Nacos」段)→ 19.7s 健康,**staging 首次真注册进 Nacos**(阶段〇接线的生产首证)。教训:jar 世代升级=依赖面升级,回滚资产必须含「旧 jar + 旧 env 面」两层。
- **两段式回路生产真转**:`/modify/plan`(星星连击特效指令)→ category=behavior / mode=regenerate-module / target=src/game-logic.js / intent 富化(带 juice 插件意识)/ riskLevel=medium / **needsConfirm=true(改玩法必确认 P0 契约)**;确认后 `/modify` 受理 chain 181 / task 201 / base 93149。
- **✅ A11 计费 e2e 收官(约 4 分钟一次过)**:新版本 **93150** 产出(package checksum 与 base 不同=真新构建,bundle 244058);task 201 断言全绿——status=2 / modify_mode=regenerate-module / base_version_id=93149 / version_id=93150 / **readiness_score=90** / idempotency_key 持久化;trace:attempts=1 / repairs=0 / stage=play / pass=True / **cost.totalRmb=0.9871 落账**(计费=记账骨架真接线,真扣退归 M4)/ models=MiniMax-M3。执行中 **C5 考卷契约在 modify 路首次生产实证**:base 源改动后「play-spec 陈旧(sourceHash 已变)→ 重生考卷」自动触发。决策④ 兑现。
### S5b · lab 复验(2026-07-04 在跑;两次假起步各钉死一个真缺陷)
- **第一跑(conc=3)作废=测量污染**:spec-smoke 100% FAIL → 全场考卷回退 key-cycle,过门率测的是环境噪声非生成质量;停批(已烧一局 ¥7.49 step_cap)。顺手补观测:smoke FAIL 时打印 raw 尾(`39646106`,真因先前被吞、烧掉一轮诊断)。
- **第二跑(conc=1 串行)仍 FAIL → raw 观测行当场破案,钉出生产级根因**:`cheap_run._shell_env`**Mac 的 Chrome 路径盲注 CHROME_BIN**,Linux(mini-desktop)上 smoke 全体 `spawn ENOENT` → state=None → **生产考卷从来就是 key-cycle 回退**(80012 成功局 gatespec.driver=key-cycle、80007 族错配盲修 ¥14.9 的共同上游根因;门跑没死只因 play.cdp.cjs 自探测 Chrome)。修=该路径真实存在(=Mac)才注入,Linux 交 play.mjs 自身默认 `/usr/bin/google-chrome`(`e4a4d025`,双向单测+全套基线不变)。**含义:此修上线后生产考卷将首次在 Linux 上拿到真实运行态(tap-targets 族),预期系统性抬过门率/压盲修**。
- **✅ 第三跑(conc=1,带 CHROME_BIN 修)达标**:三品类各 n=5——click-score / whack-mole / shop-serve **收敛局全部 4/4 过九门(质量口径 100%,raw 口径恰 80% 亦过线)**,整体「达标 ✅(逐品类阈值 0.8)」;未收敛 3/15(timeout/step_cap,按门义归 M2 编排硬化、不计质量分母)。修复红利同批可见:过门局成本 ¥0.73.7(对照 CHROME_BIN 坏考卷时代的 ¥5.97.6 flail);首局 smoke 即 PASS→driver=tap-targets。报告=`/root/tier2-run/cheap-worker/results/bake-off-1.json`,日志 `/root/bakeoff-s5b.log`。**口径明标:lab 复验(bake_off 基线 brief,CLI 路与 Service 同 driver 内核);生产真实分布 ≥80% 复验待 S5a 种子内测回填(创始人)**。bake_off 空转陷阱一并记:brief 源缺失时打「0 款达标 ✅」的空过(缺样本列表未列)——无声截断,待 bake_off 侧补一行 fail-fast(工单 i)。
### 回滚演练(✅ 2026-07-04,零 LLM 成本;S6「回滚演练一次干净」判据达成)
- **在途回调幂等 + 终态保护**:对已成功终态的 task 201 重放 status=failed 回调(正确 HMAC)→ HTTP 200 受理但 **task/version 状态零变化**(仍 succeeded/93150)= 幂等无害、成功终态不被迟到 failed 回调翻转。**验签双向**:正确签名过(日志「验签通过」),错签 **401「回调签名校验未过」**拒(不落库不驱动状态机)。
- **开闸回滚(off→on 全循环)**:先杀 worker(旁路受理的任务无从生成=演练零成本)→ `restart-48080-s2.sh off` 健康 10s → **同一违规赌博 prompt 在 OFF 态被受理**(code=0 建任务,对照 ON 态 1101001004 拒)= 总开关旁路语义逐字生效;→ 恢复 ON 重启健康 → 同 prompt 直出 **`1101001004「Prompt 不安全」`** = 控制面恢复,且 HTTP 层直出类型化拒因 = **studio 透传修(工单 d)生产实证**(创作者可见真实原因,旧 jar 只给 1112002000)。worker 拓扑收尾恢复。演练残留 task 202(OFF 态受理、派发撞死 worker 终 failed)为负例隔离约定内测试残留。
### S6 · D12 负例四门真机证据(✅ 2026-07-04,零 LLM 成本)
四拒绝门逐门真机负例,全部做在 worker 关停窗口(拒绝点在派发之前,零生成成本);测毕 `restart-48080-s2.sh` 回标准 flags、health 200,live 态复原。
- **暂停门(1101001003)**:`infra_config` 热键 `aigc.generate.paused=true`(fail-open 读)→ 提交被拒,日志「[control-plane] 降级开关开启(aigc.generate.paused=true),拒绝入队」;演练后键值回 `false` 并留 remark。运营免重启熔断入口生效。
- **日额门(1101001001 日额支)**:临时 flag `--aigc.control-plane.quota.1.daily=0` 重启 → 提交直出 1101001001,日志「门①配额超限 creatorUserId=1 level=1 **当日已用=7 上限=0 → 拒**」——与 S2 并发支(「门①并发位满 在飞=1 上限=1」)同码不同分支,两支线均有独立日志证据。
- **背压门(1101001002)**:临时 flag `--aigc.control-plane.queue-depth-limit=0` 重启 → 提交直出 1101001002「生成排队过多」,日志「门②背压拒绝 **全局在飞=0 上限=0 → 拒**(保护串行 worker)」。
- 加上 S2 的并发负例与 GP9 unsafe 负例(1101001004),**control-plane 全部五种拒绝行为(并发/日额/背压/暂停/不安全)都有真机 HTTP 响应码 + 后端日志双证**。
### S6 · 六门放行证据表(证据集齐 ✅;放行决策=创始人,S5a 种子内测=前置)
| 门 | 证据 | 口径 |
|---|---|---|
| D12 四拒绝门 | 并发(S2)/ 日额 / 背压 / 暂停(上节)+ unsafe(GP9)全负例真机双证 | prod(staging 真后端) |
| GP9 安全门 | 违规 brief 拒 1101001004 零成本 + 良性 brief 同日过(误杀对照);off→on 回滚演练同 prompt 对照 | prod |
| 9d trace | task 200:attempts/repairs/cost/gameId/gatespec/models/pass/sevenGateVerdict/similarity/stage/wallS 全齐(DB 实读) | prod |
| D11 readiness | 80012=86、A11 93150=90,远离退化带 45 / 失败带 28,三值判别生产续证 | prod |
| D9 similarity | trace_json.similarity 在席(task 200/201 实读) | prod |
| firstPlay verdict | sevenGateVerdict pass=True(80012;A11 修改路 stage=play pass=True) | prod |
| ——附:S5b ≥80% | 三品类收敛局 4/4 过九门(质量口径 100%,raw 恰 80%)整体达标 | **lab**(生产真实分布待 S5a 种子内测回填) |
| ——附:回滚演练 | off→on 全循环 + 回调幂等 + 验签双向,一次干净 | prod |
品类路由核对项随 A1 `route_genre` 收口:80007 生产日志「品类路由命中:genre=sim-business template=_template-shop」= 生产首证。**放行(对外放量)与 S5a 种子内测为创始人决策(备案红线 ≤2万人/不接广告/报备删档),证据侧已备齐。**
### 残余工单(执行中收获,非本窗口阻塞项)
- (a1) ✅ 已修(C6 反馈「驱动器族错配直指」:genre 命中 + spec.selectionBasis 含「回退」+ H_progress 零增量 → fixDirection 直指「考卷族错配,先修 targets/spec,别改游戏计分」;gate_judge 落地 + 7 单测,tier2 97/97,merge f121bb01)。
- (a2) ✅ 关闭(前提证伪):six 模板 targets 契约本就齐(_template-shop 的 `_forensicsView` 一直暴露 targets);80007 的「state 无 targets 键」是**生成代码丢键**非模板缺口——属 C6 直指(a1)的治理面,模板侧无活可干。
- (c) 软停 finish 逼近强化(observe 注入,A1 T8 教训:on_acting 文案已催 finish 但 M3 可能烧推理到地板不触发)。
- (d) ✅ 已修(studio 透传,f9b85d42;jar 轮换后回滚演练中生产实证,创作者可见类型化拒因)。
- (e) ✅ 已修(richness 日志行补 genre 段,2a8d5e45)。
- (f) 收口采集重复打印(崩溃路 `_flush` 两次「收口采集落盘」重复行,幂等无害纯观感)。
- (g) trace 富化:框架 tracing 中间件 raw 只存事件类型骨架,ToolCall/ToolResult 事件的 tool_call_name/state 未入 trace(80009 取证四路全空的一路;涉框架序列化面,单独评估)。
- (h) Service 进程 Planning/Team/Schedule 工具面收窄(内建六工具已由 ws_builtin_tools_patch 关停;这三组是框架另一面,成本上界有 ¥ 硬地板兜,非急)。
- (i) bake_off brief 源缺失 fail-fast(空样本打「0 款达标 ✅」的无声截断,S5b 第一跑实录)。
- (j) studio 透传集扩 1003/1005/1006(现集={001,002,004};1003 暂停态创作者仍见「生成委托失败」,体验税非正确性税)。