diff --git a/docs/agent-specs/2026-06-13-P2-runner-v2泛化宿主-execution.md b/docs/agent-specs/2026-06-13-P2-runner-v2泛化宿主-execution.md
new file mode 100644
index 00000000..6f2e0d02
--- /dev/null
+++ b/docs/agent-specs/2026-06-13-P2-runner-v2泛化宿主-execution.md
@@ -0,0 +1,307 @@
+# P2 · 通用宿主泛化(Runner v2 装载任意 GamePackage)· 执行版
+
+> **状态**:execution 版 · 2026-06-13 · 给执行 agent 实现。配套 review 版 [`2026-06-13-P2-runner-v2泛化宿主-review.md`](./2026-06-13-P2-runner-v2泛化宿主-review.md);母梁 [`2026-06-13-runner-v2-arc-review.md`](./2026-06-13-runner-v2-arc-review.md) §5.2;母 spec [`2026-06-13-T1b-β引擎真接线与Runner-v2-execution.md`](./2026-06-13-T1b-β引擎真接线与Runner-v2-execution.md)(Phase B/C/D + 门4/门6)。
+> **修订**:2026-06-13 对抗复审 → 纳入 4 mustFix(门② lifecycle game_end·非 telemetry / 体积 259KB·非 540KB / O2 范围 Phase C 标扩张 / ref bundle 产线落实)+ 3 shouldFix(门③后端 status=1 门禁叠加 / CSP img-src 补全 / bridge.ts 行号校准)。逐条裁决见 §13。
+> **模型分流**:一律 opus(创始人拍,本环境 fable 子代理不可用)。
+> **铁律**:下层受控面 6 项契约(`getContext2d/getInput/getAudioContext/getEngine`,`api.d.ts:269/281/286/303`)+ 上层装载契约(`game-host.d.ts:25-59`)**零改**;引擎 import 只活 entry/host(Q4);区分 verified/inferred/assumption,凡引代码事实带 file:line。
+> **前置裁决(4 阻断项全拍定 · 2026-06-13 创始人 + 主 agent)→ P2 全面解锁可直接落地**:
+> - **O2(b)=追认纳入 Phase C**(创始人拍):掏空壳 `runtime/index.ts:56` 直接改「引擎包加载分支」、**跳过复活 1.x**;母 spec Phase C 条目由 P2 supersede,改动记账归 P2。
+> - **O-P2-2=① DB-manifest 内嵌**(创始人拍·安全红线):bundle 文本进 GamePackage JSON `engineBundle` 字段、iframe 内**内联 ` → window.
+ IJ->>BH: bootGameHost({factory:取自全局名, pkg, canvas})
+ BH->>LJS: setGLEnable(false)+engineInit 五回调
+ LJS-->>BH: .then → mainContext 就绪
+ BH->>BH: game.init({ctx,mainContext,canvas,seed})
+ loop 引擎内部 RAF
+ LJS->>BH: gameUpdate→game.update / gameRender→game.render(mainContext)
+ end
+ BH->>GP: sdk.__emit('game_loaded')→bridge→GamePlayer:292
+ BH->>GP: 结算 sdk.__emit('game_end',{completed:true})→bridge→GamePlayer:300
+ else 无 engineBundle(向后兼容/demo 兜底)
+ IJ->>IJ: startRuntime:184 掏空壳 → game_error「重构中」
+ end
+```
+
+**关键数据流不变量**:
+- bundle 载体经 `package_json` LONGTEXT 随 manifest 一跳下发,sha256(整包) 覆盖 bundle 完整性(无第二校验面)。
+- 取包一律 **play 场景**(不拼 `?scene=preview`),后端 manifest 端点强制 status=1(shouldFix#1 第一道门禁)。
+- 就绪闭环唯一信号=lifecycle `game_end`(`GamePlayer.vue:300`),**非** telemetry `game_play_end`(mustFix#1)。
+- 引擎掌帧/绘制面/能力面三不变量沿 P1(掌帧唯一源=引擎 / 绘制面=mainContext / 能力面=ctx.getEngine())。
+
+---
+
+## 5. 接口 / 契约(复用 + additive 增量逐字写清)
+
+### 5.1 复用(零改)
+- **上层装载契约**(`game-runtime/src/core/game-host.d.ts:25-59`,verified):`GameHostBootContext{ctx,mainContext,canvas,seed}` / `GameInstance{init,update,render,onInput?,destroy}` / `GameHostFactory=(opts?)=>GameInstance`。P2 通用宿主 import 它、取 factory、按五生命周期驱动。**零改。**
+- **下层交付锚**(`contracts/game-package.schema.json:66-74`,verified):`packageUrl`(additive 可选,MVP 降级=DB-manifest 端点)+ `immutable`。**零改。**
+- **下层受控面 6 项**(`api.d.ts:269/281/286/303`):`getContext2d/getInput/getAudioContext/getEngine`。**零改。**
+- **宿主↔runtime 稳定边界**(保不破):`RuntimeSDKView.__emit/track/reportError/saveState/loadState` + `RuntimeHandle.destroy` + GamePlayer lifecycle emit 映射(`game_loaded:292`/`game_end:300`)。
+
+### 5.2 additive 增量(唯一契约面新增,逐字)
+
+**`contracts/game-package.schema.json` `properties` 增**(与 `packageUrl`/`immutable` 同级,不进 `required`):
+
+```jsonc
+"engineBundle": {
+ "description": "引擎+包装层+游戏代码的可执行 iife bundle 文本(T1b-β P2 通用宿主载体;additive 可选,存量消费者无此字段时走 startRuntime 旧路/demo 兜底)。MVP 默认=随 manifest 内嵌经 DB-manifest 端点下发(落 game_runtime_package.package_json LONGTEXT,sha256 整包 checksum 覆盖其完整性,不接 OSS、不增第二校验面);切 OSS 后改为 packageUrl 外链。iife 顶层全局名固定为 (宿主据此从 window 取 GameHostFactory)。后端写权=DifyCallbackTxService.buildGamePackage put。",
+ "type": "string"
+}
+```
+
+> **[verified]** 现 schema 无 `engineBundle`/`engineCode`/`engineUrl`(grep contracts/+game-studio/+game-cloud/+game-runtime/ 零命中)。本字段是 P2 唯一契约面新增。`game-studio/src/host/contract.ts` GamePackage 前端副本同步加 `engineBundle?: string`。
+> **[verified]** bundle 随 JSON 落 `package_json` 后,`buildGamePackage` 末段 `bundleSize = T_base.getBytes(UTF_8).length` 自然涵盖 bundle 字节(门禁语义成立);checksum=sha256(整包文本) 覆盖 bundle 完整性。
+
+---
+
+## 6. 关键实施步骤(分三轨·有序)
+
+> 三轨可部分并行(后端轨/宿主轨弱耦合),但**前端引擎包分支依赖宿主轨 `bootGameHost` 签名 + 后端轨 `engineBundle` 字段**,故前端轨末做。开工前 P-8 待拍项(O2(b)/O-P2-1/2/3)必须先拍。
+
+### 6.1 后端轨(game-cloud + 产线)
+
+- **B0(mustFix#4·产线先固化)**:
+ - `game-runtime/package.json` scripts 加 `build:ref-bundle`,内部 `node scripts/build.mjs games/wanglanmei-ref/entry.js games/wanglanmei-ref/dist/ref-bundle.js --global-name=`(钉死路径+globalName)。
+ - 落实 game-cloud 后端取 ref bundle 文本的路径(O-P2-1 三选一):打包期拷贝 / 构建产物入库 / CI 产物传递。**P2 仅跑 ref 一款时,可显式降级为「脚本一次性把 ref-bundle.js 文本灌入 DB 某 versionId 的 package_json.engineBundle」过渡桩**(须在代码注释+ §11 标过渡桩,P3 接生成主线改随回调入参)。
+- **B1(唯一必要后端代码改动)**:`DifyCallbackTxService.buildGamePackage`(`:268-329`)在 checksum 占位回填前增 `pkg.put("engineBundle", )`(来源=B0 落实的取得路径)。`storeForVersion`(`:198`)/`DbPackageStore.putManifest`(`:27`)/表/端点零改。
+- **B2(契约)**:`game-package.schema.json` 加 `engineBundle`(§5.2 逐字);前端 `contract.ts` 副本同步。
+- **B3(验证·后端只读)**:发布主链三服务不改,被动验证(门①)。
+
+### 6.2 宿主轨(bootGameHost·P1 bootRef 泛化)
+
+- **H1**:把 P1 `bootRef` setupReal 内引擎骨架(`setGLEnable(false)`→`engineInit` 五回调→`.then(setupReal)`→`createHostDevContext(context2d=mainContext)`→`createEngineCaps`→`game.init`→`__refBootedReal`)抽成 `bootGameHost(opts)`,其中:
+ - **游戏工厂来源参数化(D1/D2)**:替 P1 `main.js:48` 静态 `import createShopGame`——`bootGameHost` 从 `opts.factory`(宿主已从 bundle 全局名取出的 `GameHostFactory`)建实例。
+ - **插件清单参数化(D3·O-P2-4)**:P2 阶段先用王蓝莓 7 件作 `opts.plugins` 默认标准集。
+ - **视口参数化(D4)**:`opts.viewport`(P2 阶段先用王蓝莓 390×844;后续从 GamePackage 取)。
+- **H2**:`bootRef` 退化为薄包装:`bootGameHost({factory:createShopGame, plugins:王蓝莓7件, viewport:390×844, recHook})`,保 ref 取证全局名(`__refForensics/__refHost/__refBootedReal`)。**三者共用同一引擎骨架与 engine-caps 模块,不产生第三套。**
+- **H3**:SIZES.md 确认游戏产物口径=259KB raw / 88KB gz(`SIZES.md:33` 已坐实,校对无误即可,mustFix#2)。
+
+### 6.3 前端轨(studio host 引擎包分支)
+
+- **F1(分流·依赖宿主轨 H1 + 后端轨 B1)**:`inject.ts boot()`(`:174`)加 `pkg.engineBundle?` 分叉:
+ - **有 `engineBundle`**:iframe 内注入内联 ``(DB-manifest 内嵌路·非外域 `