# Tier1 运行时重设计 · 评审版(HJ-T1-REDESIGN-001) > **状态:v1.2 —— 🔨 引擎已终裁 LittleJS(2026-06-12,spike 85/82,终裁包 `2026-06-11-T1引擎终裁包.md`);D3 模板架构升级为创始人拍板的双层制(核心代码模板/玩法模板,好玩基线 v2 五要素),W-T1b 双 spec 接续。** > **约束框架单一事实源**:`docs/brainstorms/2026-06-11-tier1-runtime-constraints-requirements.md`(2026-06-11 创始人拍板:15KB 红线废除 → SLO 地板@千元机+4G P75 / 预算入场券 / 工程增强层三层框架)。 > 本文件产自「Tier1 栈由创始人亲自设计的专门会话」(2026-06-11 拍板,见记忆 `tiered-engine-cocos-decision`)。主会话已完成诊断+给候选;本会话职责 = 设计 + 创始人裁决。 > 日期:2026-06-11 | 分支:`dev/2.0.0` | 上游:`.agents/knowledge/tech-decisions.md` §1.1(裁决后须回填) --- ## 0. 一页结论(给拍板人) 1. **为什么重设计**:「好玩」要求暴露自研 Canvas 壳实为「机制演示」。五条代码铁证见 §1。根因是结构性的——`toString()` 注入模型**禁止一切依赖**,导致 juice 能力(粒子/音效/缓动/失败态)只能逐模板手搓,「好玩工时」随模板数线性爆炸。创始人已判「手搓引擎 = critical risk」。 2. **重设计 = 三件事的捆绑**,缺一不可: - **D1 引擎置换**:自研壳 → 成品轻量引擎(候选 LittleJS / KAPLAY / Phaser,§4.1); - **D2 加载面换代**:`srcdoc + toString()` 内联 → **构建版 Runner 页**(iframe src URL + HTTP 强缓存)。这是任何成品引擎「进得来」的前提——现行 CSP `script-src 'unsafe-inline'` 外部脚本根本进不来(§4.2); - **D4 好玩基线**:失败态 + juice 清单 + 难度曲线进模板验收门。只换引擎不改玩法 = 白换(§4.4)。 3. **不变的承重墙**(创始人已拍板,本设计严格遵守):`GamePackage` / SDK / `iframe` 沙箱 / 生命周期(`game_loaded/start/end`)契约不动;**生成模型不变**(深模板人工/agent 建 + LLM 填主题/数值/文案参);Cocos 仍只 Tier2/3;引擎是契约下可换的实现细节。 4. **迁移零风险路径**:契约里现成的 `manifest.runtimeVersion`(semver)就是迁移缝——存量 50 款 1.x 包走冻结的 legacy 路径,新包走 2.0 Runner;回滚 = 生成默认切回 1.x(§4.6)。 5. **推荐引擎裁决**(四路尽调已收口,证据见 §4.1):**KAPLAY 纸面淘汰、「自研+微库」路线淘汰、候选集查漏确认无遗珠;LittleJS 为默认领跑(硬约束全过:无 eval/程序化音效零网络/55KB gz/Canvas2D 自动降级),Phaser 为对照(juice 工具链与训练语料碾压,但 1.35MB+unsafe-eval+destroy 泄漏三座山)**。建议 top-2 eval-spike 实测定终裁(§5)。约束框架定稿后的语义更新:**B1 入场券(gz≤350KB/raw≤1.5MB)双引擎皆过门——Phaser 免预裁剪获入场资格,tree-shake 降为优化手段;生死改判于参考机 S2 实测(关键题=编译缓存真实表现)**。 6. **待拍板 3 项**见 §9。 --- ## 1. 背景与诊断:自研壳为什么到头了 ### 1.1 五条代码铁证(`game-studio/src/host/runtime/index.ts`,843 行,亲读核实) | # | 事实 | 证据位置 | |---|---|---| | 1 | 四模板(clicker/merge/idle/tycoon)全部内联在单个 `startRuntime` 函数体内 | `index.ts:53-843` | | 2 | 渲染 = 纯 `fillText` + `fillRect` + hsl 色块;**全文无一处 `drawImage`**——assets 预加载后从不绘制 | `loadAssets` 只计数(`:127-156`),无消费者 | | 3 | 零 juice:无粒子、无缓动、无音效、无屏震、无精灵动画 | 全文 | | 4 | 只胜不败:四模板全部「数到 N 即 `finish(completed:true)`」,无失败态、无难度曲线 | `:252,:414,:530,:711` | | 5 | `toString()` 注入禁依赖 → 工具函数(`clampInt`/`localXY`/`inRect`)被迫**逐模板复制粘贴**(注释明令「严禁提升到共享作用域」) | `:443-457,:650-664` | ### 1.2 结构性根因(不是写得差,是模型到头了) `inject.ts` 用 `Function.prototype.toString()` 把 SDK 工厂 + Runtime 工厂序列化成文本拼进 iframe `srcdoc` 内联脚本。这个骨架期的聪明 hack 换来「零打包配置」,但代价如今全部到期: - **禁止任何 npm 依赖**进 runtime → 粒子/缓动/音效全部只能手搓; - 函数体必须自包含 → 跨模板复用靠复制粘贴,×N 漂移靠纪律硬顶; - CSP `script-src 'unsafe-inline'`、`connect-src 'none'` → 外部引擎脚本进不来、音频资源载不进; - 「好玩工时」逐模板线性增长,且每一分都花在重造 40 年前就成熟的轮子上。 > 反向佐证:蓝图(技术决策版 §4.2)的 CSP 本来就是 `script-src 'self'`——同源加载构建版引擎 bundle 恰好是蓝图设计,现行 `unsafe-inline` 才是骨架期的临时偏离。 ### 1.3 与既有裁决的关系 - 一次/二次裁决「Tier1 自研壳=护城河」的真实护城河成分是**沙箱 + SDK + 三容器 + 契约**,不是渲染循环本身——这些全部保留。 - 旧 ADR 曾否决「Phaser 3 全栈」,否决语境是「全 Tier 通吃 + 导出弱」;本次 Phaser 仅竞标 Tier1 单层,不受旧否决约束(导出枢纽仍按既有裁决走微信格式包 adapter)。 --- ## 2. 目标 / 非目标 **目标** 1. 新模板「好玩工时」数量级下降:juice(粒子/缓动/音效/屏震/精灵)成为引擎自带能力,模板代码只写玩法; 2. 建立「好玩基线」并进五级验收门:失败态、难度曲线、juice 清单(§4.4); 3. 全契约零破坏:GamePackage / SDK / 生命周期 / postMessage 信封 / storage 通道原样; 4. 首屏不退步:P75 < 3s 红线不动;新增「点卡→可玩」S2 门(常态≤2s/全新设备首次≤3.5s,约束框架 R2); 5. 存量 50 款内容池零影响(双轨迁移)。 **非目标** - 不动生成模型(不做 LLM 直出代码;深模板仍由人/agent 编写、LLM 填参); - 不动 Tier2/3(Cocos 定位不变)、不做 3D; - 不动发布链 / feed / 鉴权 / 遥测后端(`game_end` 仅 additive 加字段,见 §4.4); - 不在本波做多渠道导出 adapter 真实化(仍按既有 backlog 排); - 不动 SDK Core(<8KB 约束与实现不变;SDK 与引擎解耦正是契约的意义)。 --- ## 3. 设计总图 ```mermaid flowchart LR subgraph 生成侧["生成侧(不变)"] LLM["LLM 填参
(designer prompt)"] --> GC["GameConfig
(模板 schema 约束)"] GC --> GP["GamePackage v2
manifest.runtimeVersion=2.x"] end subgraph 宿主["game-studio 宿主(GamePlayer.vue 不换)"] BR["postMessage 桥
origin+schema 双校验(不变)"] end subgraph Runner["Runner v2(新:构建版 iframe 页,HTTP 强缓存)"] ENG["成品引擎
(D1 裁决)"] TPL["深模板模块 ×N
(与引擎同 bundle 同版本)"] SDKi["WanxiangGameSDK
(契约 #3,不变)"] end GP -- "init 下发(postMessage)" --> Runner 宿主 <-- "生命周期/遥测/storage/ad/pay(信封不变)" --> Runner GP -.-> LEG["Legacy 路径(冻结)
runtimeVersion=1.x
srcdoc+toString 原样"] ``` **一句话**:宿主与契约一行不动;变的是 iframe 里面那张纸——从「每局现拼的内联脚本」换成「一张构建好、强缓存、带引擎和全部深模板的 Runner 页」,GamePackage 改由 postMessage `init` 下发(contract.ts 里 `init` 通道现成)。 --- ## 4. 关键决策 ### 4.1 D1 · 引擎选型(四路尽调已收口,2026-06-11,全部一手证据:官方 repo 源码/npm registry/issue/HN) **硬约束对比表**(我们场景的一票项在前): | 维度(硬约束在前) | LittleJS v1.18.19 | Phaser 4.1.0 / 3.90 | KAPLAY v3001 | |---|---|---|---| | CSP 无 eval(沙箱红线) | ✅ 源码实证无 eval/`new Function` | ⚠️ v3 确证需 `unsafe-eval`(单点 polyfill 可 patch;v4 未验证) | ❓ 未验证 | | 音效在 `connect-src 'none'` 下可用 | ✅✅ ZzFX/ZzFXM 程序化合成,零网络零资产 | ⚠️ WebAudio 播 sample 需载资源(CSP 要开口) | ❌ 仅 sample 播放,无程序化 | | 体积(引擎=强缓存宿主资产) | min 175.7KB raw / **≈55-60KB gz** | 全量 1.35MB raw / ≈345KB gz;tree-shake 到 gz<150KB **未实证** | 未取到数字(npm/bundlephobia 被拦) | | 低端 WebView 兜底 | ✅ WebGL2 不支持自动降级 Canvas2D(源码实证) | ⚠️ 有 Canvas 渲染器,但 1.35MB 低端机解析 ~1-1.3s + 多 tween 卡顿 issue | ❓ 移动端实测空白 + 2 个已知 Safari bug(加载失败/文字裁切,直击微信内核) | | CJK 中文 | ✅ `fillText` 系统字体路径(源码实证),缺真机案例需走查 | ✅ Text=canvas fillText→纹理(高频变更有重传成本,数字用 BitmapText) | ❓ 零官方背书,内部管线未明 | | juice 工具链 | 粒子(含编辑器)/ZzFX/屏震/后处理 shader/街机物理全内置;**缺 Tween 管理器**(有缓动数学,需自封薄层,一次性成本) | ★ 全维度最成熟(粒子/Tween Chains/摄像机特效/双物理) | 齐全但成色未经移动端验证 | | 可生成性(agent 写深模板) | 中上:文档好+单文件百行级示例对 agent 友好;语料少于 Phaser | ✅✅ 语料碾压(39.8k★/700+教程),**Phaser 官方亲出 Claude Code 教程(2026-02)**;注意语料是 v3、v4 刚出 2 个月 | ⚠️ 语料多为 Kaboom 旧 API(好在 API 近零破坏可沿用);**官方"LLM friendly/llms.txt"经核验不成立(404)——纠偏候选预设** | | 生命周期(feed 滑走销毁) | 无 destroy——被我们「一游戏一 iframe、滑走即卸载」契约天然规避,但**严禁同 iframe 内重启** | destroy() 不自净是多年已知泄漏(#2138/#5456)——同样靠 iframe 卸载兜底 | ❓ 未验证 | | 维护健康度 | 单人 bus factor(Frank Force),但近一月 8 连发极活跃;单文件 MIT,fork 自持成本极低 | ✅ Phaser Studio 公司化($2M),39.8k★,issue 仅 101 | ❌ 3 人团队 + $5/月捐赠档,v4000 滑期 ≥5 季度 | | 尽调评分 | **8.0 / 10** | **8.0 / 10** | 6.5 / 10 | **裁决建议**: 1. **KAPLAY 纸面淘汰**:三重盲区(移动+中文+微信零先例)+ 2 个 Safari bug + 可持续性最弱 + 程序化音效缺失,且"LLM friendly"预设被证伪——没有任何维度赢过另两家。 2. **「自研+微库」路线淘汰**(查漏报告关键论断):ZzFX/tween.js/手写屏震各自成熟,但这条路的形态终点**就是亲手再造一个 LittleJS**——除 CJK(本来就不输)外零独占收益,还把粒子/缓动/生命周期的维护永久揽上身。创始人「手搓引擎=critical risk」的判断被外部证据反向确认。 3. **查漏确认候选集无遗珠**:Pixi(渲染器非引擎,CJK 丢最快路径)/melonJS/Excalibur/Kontra/Litecanvas(alpha+零语料)/Defold(MB 级)逐一排除;「为 LLM 设计的开源 2D 引擎」生态位当前为空。 4. **终裁在 LittleJS(默认)与 Phaser(对照)之间**,本质是一道权衡题:**平台硬约束契合(LittleJS:无 eval/零网络音效/55KB/自动降级) vs 工具链成熟+语料优势(Phaser)**。LittleJS 仅剩的两处实证空白(CJK 真机、agent 写模板的实际摩擦)与 Phaser 的三座山(unsafe-eval patch 可行性、tree-shake 实测、低端机解析)恰好都是 spike 一次测清的事。 ### 4.2 D2 · 加载面换代:srcdoc+toString → 构建版 Runner 页(推荐,随 D1 必做) - **Runner = Vite 构建的独立入口**(如 `/runner/2.0.0/index.html`),内含:引擎 + 全部深模板模块 + SDK + 引导。iframe `src` 指向它(带版本号路径 → 强缓存/immutable),**引擎只在首次冷加载付一次代价,之后全游戏共享缓存**——这正是创始人「缓存抹平体积」拍板的工程形态。 - **引擎 URL 化交付是铁律**(约束框架 KD4):URL 脚本同时享 HTTP 缓存与 Chromium 编译缓存(v8.dev 文档化行为;srcdoc 内联两者皆无——旧架构不光挡引擎进场,还白白放弃两层免费缓存)。feed 浏览期预热 Runner(下载+编译双热)。工程增强层 E1/E2/E4/E6(预热管线/首帧保障/模板共享资产入 Runner/brotli+WebP)落在 Runner 设计内,详见约束框架 R11-R16。 - GamePackage 不再内联进 srcdoc,改走现成的 `init` postMessage 通道下发(契约 #3 已定义,零新协议)。 - 沙箱姿态不变:`sandbox="allow-scripts allow-same-origin"` + origin/schema 双校验照旧;CSP 收敛到蓝图形态 `script-src 'self'; connect-src 'none'`(比现行 `unsafe-inline` 更紧,安全是**加强**不是放松)。 - **音效走程序化合成**(ZzFX 类,零网络),`connect-src 'none'` 不必放开;采样音频留待后续单独评(需动 media-src,标记为契约邻接变更,本波不做)。 - 三容器预加载护栏:N±1 容器只预取 manifest+assets,**不起活引擎实例**(WebGL context 与内存 ×3 是低端机雷区),当前容器独占活实例。 ### 4.3 D3 · 模板架构:深模板 = Runner 内置代码模块 - 模板实现与引擎同 bundle、同版本、同验收(彻底告别「函数体内自包含+复制粘贴」范式); - `GameConfig` 仍是纯数据(schema 约束 + 后端校验 + runtime 钳制三层不变),LLM 职责零变化; - `add-game-template` 七步配方保留骨架,步骤三从「switch 加分支+体积门」改写为「新增模板模块+Runner 构建门」(配方升版随执行波蒸馏)。 ### 4.4 D4 · 好玩基线(重设计的目的,建议与 D1 捆绑交付) 1. **juice 底线清单**(新模板验收新增门):交互必有即时反馈(缓动/粒子任一)+ 关键节点音效(程序化)+ 通关/失败演出 ≥1 处 + 屏震或等价强反馈 ≥1 处; 2. **失败态**:模板必须有「会输」的路径(超时/失误/资源破产任一),难度参数进 GameConfig 由 LLM 填; 3. **契约影响(additive,semver 安全)**:`game_end` 的 data 增加 `outcome: 'win'|'lose'`;`completed` 语义微调为「到达终局态」(赢或输都算 completed,弃玩才是 false)——**quality_score 完玩率口径因此保持有效**,无需动后端公式。此项动数据口径,列为待拍板(§9-Q2)。 4. 存量四模板在新栈重做时同步补好玩基线(每模板一次五级验收门重走)。 ### 4.5 D5 · QA 探针承重接口:隐性公式 parity → 显式只读布局契约 现状:merge/tycoon 的布局/按钮坐标公式要求 runtime 与 `player_cdp.py` **逐字符对齐**(隐性承重接口,收口靠人肉比对)。新栈下改为:**Runner 按模板暴露只读「取证几何清单」**(确定性布局数据,挂只读全局或 postMessage 查询),player 按清单驱动**真实输入事件**。取证纪律不变(真实事件、禁篡改内部状态),但承重接口从「散文公式 parity」升级为「显式契约」。 ### 4.6 D6 · 迁移与回滚:runtimeVersion 双轨 ```mermaid flowchart TD A[GamePlayer 取包] --> B{manifest.runtimeVersion} B -- "1.x(存量 50 款)" --> C["Legacy 路径:srcdoc+toString 原样冻结
只修 P0,不再演进"] B -- "2.x(新生成)" --> D["Runner v2:引擎+深模板"] ``` - 阶段①:Runner v2 + 首个模板(建议 spike 的「落物 action」直接转正,§9-Q4)五级验收门全过 → 金丝雀入 feed; - 阶段②:四存量模板在新栈重做+好玩基线,逐模板过门; - 阶段③:生成默认切 2.x,1.x 冻结只读;存量包**不迁移**(零风险,自然汰换); - **回滚**:任一阶段生成默认切回 1.x 即回滚,legacy 路径全程在位;feed/发布链对 runtimeVersion 无感。 --- ## 5. eval-spike 设计(top-2:LittleJS vs Phaser,建议方案) - **题目**:同一款「落物 action」(接住坠落物得分、漏接扣命、速度随时间爬升——天然带失败态与难度曲线,正好检验好玩基线)。 - **双引擎各搭一遍**,统一跑在 **Runner v2 雏形**里(iframe 沙箱+SDK 真接,不做编排器接入)——spike 同时就是 Runner 底座 bring-up,不是丢弃式工程。 - **评分卡**(满分 100):好玩工时 30(达到 juice 底线清单的 agent 轮次/耗时;LittleJS 需自封 tween 薄层的成本计入)、可生成性 25(agent 首轮代码正确率+API 踩坑数;两边都喂官方示例,对齐 Phaser 官方 Claude 教程的「给 working example」方法论)、**S2 实测 20**(参考机画像 CDP 节流下首开/二开/稳态三档「点卡→可玩」耗时——B1 入场券双双过门后,**S2 是主考**,约束框架 KD3;Phaser tree-shake 从入场前提降为优化手段)、沙箱适配 15(**Phaser v4 unsafe-eval 现状 grep 实证** + 严格 CSP 下双引擎实跑 + 中文文案真机/微信 WebView 走查 + 三容器护栏)、维护健康度 10(已有研究数据直接计分)。 - **定向钉子**(研究报告点名必须实测的空白,spike 内逐项打掉):① Phaser v4 dist 是否仍含 `new Function`(grep 即可);② Phaser 裁剪后 gz 实数;③ LittleJS 中文文案在低端 Android/微信 WebView 的真机渲染;④ 双引擎在 `script-src 'self'; connect-src 'none'` 严格 CSP 下零违规跑通;⑤ **编译缓存真实表现**:XWeb/低端 WebView 上 Runner 脚本首开/二开/三开的 parse 耗时曲线(code cache 是否生效——大引擎稳态成本的生死题,约束框架 A2)。 - **产出**:实测计分表 + 裁决建议 → 创始人终裁;**获胜实现直接转正为模板五**(spike 钱花两次用)。 - **预算**:每引擎 1 个执行 agent(opus 档)+ 主会话验证门,mini-desktop 构建/走查,预计 1~2 天等效(双引擎并行)。 --- ## 6. 爆炸半径与兼容 | 面 | 影响 | 处置 | |---|---|---| | `contracts/`(8 契约) | **零破坏**。`game_end` data 加 `outcome`(additive);GamePackage/SDK/信封/storage 原样 | 契约先行流程走一遍,通知面小 | | game-studio 宿主 | GamePlayer.vue 加 runtimeVersion 分流 + Runner 入口构建;bridge/双校验不动 | 中等,单仓内 | | 后端 game-cloud | **零改**(模板白名单/schema 校验/quality 公式不动;`runtime 真实编译打包` backlog 顺势按 v2 产物形态实现,反而少走弯路) | 排期受益 | | 编排器 player_cdp | 每模板取证策略随新栈重写(D5 显式几何契约后更稳) | 逐模板随执行波 | | `.agents` 配方 | add-game-template 步骤三/体积门改写;runtime-and-multichannel、tech-decisions §1.1 回填 | 收口铁律内 | | 存量内容池 50 款 | 零影响(1.x 冻结路径) | 双轨保障 | | 体积门 | 「runtime<15KB」红线**废除**,按约束框架三层重建:B1 引擎入场券 gz≤350KB 且 raw≤1.5MB(2026-06-11 创始人拍板放宽档)+ S2 实测主考(常态≤2s/首次≤3.5s)+ R7/R8 游戏包门(首批 ≤1MB/总 ≤10MB/config ≤32KB) | ✅ 已定稿(brainstorm requirements) | ## 7. 风险(按严重度) 1. **引擎选错的纠错成本**(中高):深模板代码与引擎强耦合,换引擎=重写全部模板 → 用 spike 实测+双轨缓释;契约层保证宿主/后端/生成侧零返工。 2. **低端 WebView 实测不达**(中):WebGL 兼容/内存——spike 评分卡含真机维度;引擎若 WebGL-only 需确认 Canvas2D 回退。 3. **好玩基线推高生成失败率**(中):难度参数进 GameConfig 后 LLM 填参违例面变大 → schema 钳制+runtime 兜底纵深照旧,校准批先行。 4. **completed 语义微调的数据连锁**(低中):outcome 字段 additive,但 BI/报表若有硬编码读法需 grep 一遍 → 执行波清单项。 5. **双轨期维护两套 runtime**(低):1.x 冻结只修 P0,演进全在 2.x;冻结纪律入 rules。 ## 8. 验收标准(重设计整体收口线) 1. Runner v2 + 获选引擎:构建门绿 + 首载预算达标 + 三容器护栏实测; 2. 模板五(落物 action):五级验收门全过 + **好玩基线门全过** + 金丝雀入 feed 真人实玩; 3. 存量四模板新栈重做:逐模板五门+好玩门,clicker 回归与 1.x 行为对照留档; 4. 生成默认切 2.x,连续一个校准批 accept ≥80% 量级不回退; 5. 契约 grep:生命周期/信封/storage 零破坏证据 + `outcome` 字段三端(runtime/宿主/遥测)一致; 6. 蒸馏回填:tech-decisions §1.1 / add-game-template / runtime-and-multichannel / 总账+作战清单(按 wave-close-checklist 七步)。 ## 9. 待拍板项 > **✅ 拍板落账(2026-06-11,创始人「continue」沿推荐路径全采纳)**:Q1=(b) top-2 spike(执行单 HJ-T1-SPIKE-001 in flight,Phaser 版本统一 4.1 见执行单 §2.1)/ Q2=捆绑好玩基线(`outcome` 字段 spike-local 先行,契约补丁随 W-T1b 契约先行流程)/ Q3=spike 先行与现队列并行,终裁后重锁完成线。下表保留为决策历史。 | # | 问题 | 选项 | 我的倾向 | |---|---|---|---| | Q1 | 引擎裁决方式 | (a) 直接拍 LittleJS(研究已足够一边倒)/ (b) **top-2 spike(LittleJS vs Phaser)实测终裁** / (c) 三款全 spike | **(b)**——KAPLAY/自研+微库纸面淘汰已稳;LittleJS 两处实证空白(CJK 真机/agent 摩擦)与 Phaser 两座山(unsafe-eval/编译缓存下的 S2 稳态)只有实测能定(tree-shake 已随 B1 放宽档降为优化手段),且 spike 顺产 Runner 底座+模板五,不是纯评测成本 | | Q2 | 好玩基线是否本波捆绑(含失败态+`outcome` 字段+completed 语义微调) | 捆绑 / 只换引擎先行 | **捆绑**——不捆绑则重设计只剩搬家,「好玩」无验收抓手 | | Q3 | 队列位置 | 插队成当前主线 / 与链路③⑤走查、W4 埋点并行 / M4 变现先行 | 创始人定(作战清单本轮完成线本就待重锁);注意 Tier1 重设计预计 2~4 个执行波,是大动脉手术 | (原 Q4「spike 产物转正」并入 §5 设计默认:转正为模板五,不另问。) ## 10. 演进路径(拍板后的波次切分预估) 1. **W-T1a**:(若拍)eval-spike → 引擎终裁 + 本 spec 定稿 + execution spec(双 spec 铁律); 2. **W-T1b**:Runner v2 底座 + 模板五转正 + D5 取证契约 + 五门收口; 3. **W-T1c**:存量四模板新栈重做 ×4(可两批并行,复用 add-game-template 升版配方); 4. **W-T1d**:生成默认切 2.x + 1.x 冻结 + 全链收口蒸馏。