From a0a46ae32de38d9baaf0eb5e6898b94c8b634550 Mon Sep 17 00:00:00 2001 From: lili Date: Thu, 25 Jun 2026 01:16:26 -0700 Subject: [PATCH] =?UTF-8?q?docs(=E6=9E=B6=E6=9E=84):=20gamedef=20reframe?= =?UTF-8?q?=20pass-2=20=E2=80=94=20broader/=E6=B2=99=E7=AE=B1=E6=A1=A3=20+?= =?UTF-8?q?=20=E6=AE=8B=E7=95=99=20mentions?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 续上轮(banner+README),把 broader/沙箱档里 gamedef-当现行/迁移中清成「已废错误路线、 A-model 现行」(opus 代理 + 我补漏): - 00-系统总览:左轨现行 gameDefinition→A-model 写真 src/,无迁移/cutover - 03/架构产物沙箱:scanLogic(behavior.code/rule.condition 扫描)、new Function/unsafe-eval 标为已废 gamedef 路 build 段机制,A-model 真 src/ 经 esbuild 无 new Function; **沙箱层(iframe/CSP/桥/九门)对两路通用、保留**;装载路 L146 改 A-model 现行 - OpenGame对照:L325「当前实现 gamedef」→已废、L318 smart_edit 注 A-model 文本补丁回归 - 验收门:九门收窄 91.7% 标为 gamedef 路历史实测 + 该验收策略引擎无关对 A-model 适用 - 数据飞轮:去「待 gamedef→src 迁移协调」(无迁移,gamedef 已废) 门:全仓死链 0。 Co-Authored-By: Claude Opus 4.8 (1M context) --- docs/architecture/00-系统总览图说.md | 4 ++-- docs/architecture/03-产物执行沙箱图说.md | 4 ++-- docs/architecture/架构/产物执行沙箱.md | 4 ++-- docs/architecture/架构/生成引擎/OpenGame对照.md | 4 ++-- docs/architecture/架构/生成引擎/数据飞轮.md | 2 +- docs/architecture/架构/生成引擎/验收门.md | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/architecture/00-系统总览图说.md b/docs/architecture/00-系统总览图说.md index 74af997e..201b844d 100644 --- a/docs/architecture/00-系统总览图说.md +++ b/docs/architecture/00-系统总览图说.md @@ -93,7 +93,7 @@ status: 现行为主(系统级 9 图)· 架构图集入口 · 通用图例与按 这张图是看清「生成引擎现行 vs 远期」的**总闸**,也是本主档最该守状态纪律的一张。绘境AI 有两条生成轨:**左轨是现行的 SAA 廉价线**——已实测合入主干,承载超休闲档(打砖块 / 合成 / 挂机 / 答题 / 网格点选),一条流水线从「创作者一句话」经 SAA 裸图编排(Java·16 节点)、new-api 网关、便宜 LLM、harness 九门兜底,到 emit 出包,用 LittleJS 当引擎、产物是一份可维护的 `src/` 源项目;**右轨是 tier2 富游戏自治轨**——核心已落、0 号 spike 已过 accept(n=1 机制验证,n≥30 统计待跑),承载 premium 富游戏(经营 / 合成 / 多系统富交互),走的是与左轨正交的另一套范式:AgentScope(Python)的自治 ReAct agent、作为一个独立 service 跑、用 Phaser / Pixi 全无头引擎、靠三层校验当确定性地板加人工终审兜底,产物是 Phaser 的 `src/` 源工程。两轨**只经公共件交汇**:计费平面、送审 + feed、验收基线 + 执行沙箱、控制 / 管理面治理层。两轨**远期有可能收敛为一条**——把左轨的 SAA + LittleJS 也并入 AgentScope 自治范式(登记为未来方向,当前不做)。 -读这张图,**最要紧的是把左轨的实心和右轨的紫色虚线分清**:左轨是「现行已建」;右轨那道紫色虚线是 spike 前视角的画法,而 tier2 的现状是核心已落、0 号 spike 已过 accept(n=1 机制验证,n≥30 统计待跑),状态以 SoT① [`生成引擎/agentic运行时架构图说.md`](架构/生成引擎/agentic运行时架构图说.md) 为准。还有三层意思必须读到。其一,**左轨的现行真实状态要诚实说清**:骨架立住、控制流确定、九门很硬已合入主干,但生成质量尚未稳定到 80% 门(便宜模型天花板,实测约 60%)、一部分策略被焊进机制代码;范式侧的终态产物定为可维护的 `src/` 源项目(改源不改包),现行 generate 产出的 gameDefinition JSON 只是通往它的中间脚手架、产线正把它迁成直接生成 `src/`(仍在落地,以生成引擎子树最新裁定为准);默认产线切换交 W-G1 把质量做到 80%(dispatcher flag 已存在,一行 flip)。其二,**为什么两轨不合并**:左轨声明式有向图与右轨命令式循环是两种正交范式,硬塞就成项目明令反对的「缝合设计」,而且对卡 80% 门,图的确定性本就比口头督促更稳。其三,**它们的唯一交汇面是公共件**——tier2 换的是「游戏内容怎么造出来」,换不掉「造出来之后怎么被关进笼子跑、怎么计费、怎么送审发行」。生成引擎的深度(SAA 16 节点拓扑、加节点法、救场阶梯、引擎运行时、tier2 详设)在生成引擎子树,本图只画两轨硬边界。 +读这张图,**最要紧的是把左轨的实心和右轨的紫色虚线分清**:左轨是「现行已建」;右轨那道紫色虚线是 spike 前视角的画法,而 tier2 的现状是核心已落、0 号 spike 已过 accept(n=1 机制验证,n≥30 统计待跑),状态以 SoT① [`生成引擎/agentic运行时架构图说.md`](架构/生成引擎/agentic运行时架构图说.md) 为准。还有三层意思必须读到。其一,**左轨的现行真实状态要诚实说清**:骨架立住、控制流确定、九门很硬已合入主干,但生成质量尚未稳定到 80% 门(便宜模型天花板,实测约 60%)、一部分策略被焊进机制代码;范式侧的终态产物定为可维护的 `src/` 源项目(改源不改包),这一点由廉价线现行路径直接兑现:**gameDefinition 已废(判错误路线),廉价线现行 = A-model 写真 `src/`(LittleJS,经 esbuild 构建成 engineBundle)**;默认产线已是 A-model 单线,既无「迁移中」也无「cutover 切换」,质量做到 80% 仍交 W-G1。其二,**为什么两轨不合并**:左轨声明式有向图与右轨命令式循环是两种正交范式,硬塞就成项目明令反对的「缝合设计」,而且对卡 80% 门,图的确定性本就比口头督促更稳。其三,**它们的唯一交汇面是公共件**——tier2 换的是「游戏内容怎么造出来」,换不掉「造出来之后怎么被关进笼子跑、怎么计费、怎么送审发行」。生成引擎的深度(SAA 16 节点拓扑、加节点法、救场阶梯、引擎运行时、tier2 详设)在生成引擎子树,本图只画两轨硬边界。 ### 图 4 · 跨域数据流(越用越聪明)〔SVG·流·现〕 @@ -194,7 +194,7 @@ flowchart TB 生成引擎是绘境AI 护城河的关键路径,内容最厚、单独成一棵子树。它回答「一句话怎么变成一款可上线的游戏」这条技术主线:现行那台被刻意设计成可靠的、固定相位的生成机器(便宜模型驱动 + 确定性图编排约束控制流 + 九门 harness 兜底),以及它要往哪走的演进路线、贯穿全程的范式原则(游戏是长生命周期源项目、LLM 是它的工作室)。本主档的第一篇图 3 已给出「两条生成轨现行 vs 远期」的总闸轮廓,这棵子树是它的深度展开。 -读这棵子树最该带着一条**范式定性**:这套「便宜模型 + 受限 schema + 九门验收」是一条**为超休闲轻游戏(Tier0)量身打造的可靠产线,而不是一个通用生成范式**;它最大的风险不在工程层,而在被当成通用范式去对标 demo 里那一档富交互游戏(那一档结构性地够不着,必须显式分层、复杂品类另开一轨)。子树内现行结论可能随产线化 plan(把现行的 gameDefinition JSON 中间脚手架迁成直接生成 `src/` 源项目)的推进变化,以最新裁定为准。 +读这棵子树最该带着一条**范式定性**:这套「便宜模型 + 受限 schema + 九门验收」是一条**为超休闲轻游戏(Tier0)量身打造的可靠产线,而不是一个通用生成范式**;它最大的风险不在工程层,而在被当成通用范式去对标 demo 里那一档富交互游戏(那一档结构性地够不着,必须显式分层、复杂品类另开一轨)。廉价线现行已是 A-model 写真 `src/` 源项目(gameDefinition 已废、判错误路线),子树内细节以最新裁定为准。 > **跨 session 协调红线 + 链接(只链不并)**:生成引擎子树正被**另一条 session 在飞建设**,本主档对它**只链接、不并入其内部图与散文**——它的两簇(现行 SAA 廉价线 / 远期 tier2 自治轨)的逐张图、SAA 16 节点拓扑、九门逐门、tier2 详设都在子树内,本文不重复承载。 > diff --git a/docs/architecture/03-产物执行沙箱图说.md b/docs/architecture/03-产物执行沙箱图说.md index 6ad09f10..de14cc3d 100644 --- a/docs/architecture/03-产物执行沙箱图说.md +++ b/docs/architecture/03-产物执行沙箱图说.md @@ -25,7 +25,7 @@ status: 现行为主 · 每图具体映射源档见该图脚注 / 内联小注 这张全景图回答整份文档的总问题:**一段模型现写的不可信 JavaScript,凭什么敢放进玩家的浏览器里跑**。答案是三层封堵,它们在不同时机、不同位置生效,合起来才是完整的封锁,单看任何一层都不够。图从左到右按「出厂前 → iframe 这层壳 → iframe 外的宿主平台」铺开,用绿色标出唯一被放行的通道、用红色虚线标出每一个被封死的逃逸面。 -最左边一层最容易被忽略,因为它**不在 runtime、而在 build 段**。`build-from-source.mjs` 的 `scanLogic` 在把 gameDefinition 装配成可玩工厂、交给 esbuild 打包**之前**,对模型产出的 `behavior.code` 和 `rule.condition` 做静态扫描,命中危险模式就转成 `validationError` 回灌给 repair,而不是指望 prompt 自觉。为什么这一层必须放在 build 边界做?因为同步 JS 在进程内没法被硬中断——一个 `while(true)` 死循环或一次沙箱逃逸只要执行了就晚了,所以唯一的机会是在执行前的校验边界把危险模式拦掉。图上把 `LOGIC_BANS`(逃逸 / DOM 网络 / 死循环 / 确定性四类)和 `CONDITION_BANS`(条件必须是无副作用的纯布尔表达式)的实际拦截清单都列了出来,让人看清这层拦的不是抽象的「危险代码」,而是一份具体的黑名单。 +最左边一层最容易被忽略,因为它**不在 runtime、而在 build 段**;同时要点明它属于**已废 gamedef 路的 build 段机制**。`build-from-source.mjs` 的 `scanLogic` 在把 gameDefinition 装配成可玩工厂、交给 esbuild 打包**之前**,对模型产出的 `behavior.code` 和 `rule.condition` 做静态扫描,命中危险模式就转成 `validationError` 回灌给 repair,而不是指望 prompt 自觉。这套静态扫描是 gamedef 专属的——它扫的 `behavior.code` / `rule.condition` 串字段只存在于 gameDefinition;A-model 写真 src/ 多文件、没有这类逻辑串字段,这一层随 gamedef 废弃而不再是现行路径。为什么这一层必须放在 build 边界做?因为同步 JS 在进程内没法被硬中断——一个 `while(true)` 死循环或一次沙箱逃逸只要执行了就晚了,所以唯一的机会是在执行前的校验边界把危险模式拦掉。图上把 `LOGIC_BANS`(逃逸 / DOM 网络 / 死循环 / 确定性四类)和 `CONDITION_BANS`(条件必须是无副作用的纯布尔表达式)的实际拦截清单都列了出来,让人看清这层拦的不是抽象的「危险代码」,而是一份具体的黑名单。 中间是 iframe 这层壳,它叠了两道:**CSP** 硬编码进 srcdoc 的 ``,其中 `connect-src 'none'` 是最关键的一条——它禁掉一切网络出站,所以即便游戏代码想把玩家数据 `fetch` 出去也发不出去;引擎 bundle 不在 iframe 内 fetch,而是由宿主层 fetch 后内联进来,所以这条不会卡死引擎装载。**sandbox 属性**则封死宿主 DOM 逃逸、顶层导航与弹窗,并把游戏与宿主之间的通道收窄到只剩 postMessage 一条。这条收窄直接决定了产品形态:广告、支付、存储这些要碰平台资源的事,游戏在 iframe 内根本办不了(没网络、碰不到宿主 DOM),只能经 postMessage 抛给宿主侧去办、办完再回包——这就是为什么 SDK 的 ad/pay/storage 都是「游戏发请求 → 宿主执行 → 回包」的形状,而不是游戏直接调。 @@ -95,7 +95,7 @@ flowchart TB direction TB C1["default-src 'none' —— 兜底封掉一切未显式放开的资源类型"] C2["connect-src 'none' —— 禁一切网络出站(最关键)
引擎 bundle 由宿主层 fetch 后内联,不在 iframe 内 fetch,故不被卡"] - C3["script-src 'unsafe-inline' 'unsafe-eval'
gamedef 运行时用 new Function 编译逻辑串,必需 'unsafe-eval'"]:::debt + C3["script-src 'unsafe-inline' 'unsafe-eval'
'unsafe-eval' 是已废 gamedef 路的 CSP 债(gamedef 用 new Function 编译逻辑串)
A-model 真 src/ 经 esbuild 无 new Function,该债随 gamedef 废而可收紧"]:::debt end subgraph SO["② 同源红线 HJ-AUDIT-001(当前=过渡态)"] direction TB diff --git a/docs/architecture/架构/产物执行沙箱.md b/docs/architecture/架构/产物执行沙箱.md index 15fd1eee..8c81e9fb 100644 --- a/docs/architecture/架构/产物执行沙箱.md +++ b/docs/architecture/架构/产物执行沙箱.md @@ -66,7 +66,7 @@ flowchart TB B1["build 段 scanLogic 静态门
编译前拦 Function/eval/import/fetch/window/while(true)…"] -.->|出厂前已净化| G ``` -**第一层在 build 段,不在 runtime。** `game-runtime/src/host/build-from-source.mjs` 的 `scanLogic`(:73)在把 gameDefinition 装配成可玩工厂、交 esbuild 打包**之前**,对模型产出的 `behavior.code` 和 `rule.condition` 做静态扫描。`LOGIC_BANS`(:42-63)是实际的拦截清单:沙箱逃逸类拦 `process`、`require`、动态 `import(`、`globalThis`、`eval(`、`.constructor`、`Function(`;DOM 与网络类拦 `document`、`window`、`fetch(`、`XMLHttpRequest`、`addEventListener`、`requestAnimationFrame`;死循环类拦 `while(true)`、`while(1)`、`for(;;)`;还有确定性逃逸类拦 `Math.random`、`Date.now`、`new Date`、`performance.now`(取证要可复现,逻辑里只许用 `rt.random` / `rt.time.now`)。`rule.condition` 另有专属禁则 `CONDITION_BANS`(:65-70):它必须是一个无副作用的布尔表达式,所以拦 `;`(不许是语句)、拦赋值 `=`、拦调世界变更方法 `addScore/setScore/spawn/destroy`、拦 `win()/lose()`。命中任何一条就转成 `validationError` 回灌给 repair 反馈,而不是靠 prompt 自觉。这层为什么必须在 build 边界做:同步 JS 没法在进程内硬中断,死循环和逃逸一旦执行就晚了,所以在执行前的校验边界把危险模式拦掉(:13-15 的信任模型注释)。 +**第一层在 build 段,不在 runtime——但它属已废 gamedef 路的 build 段机制。** `game-runtime/src/host/build-from-source.mjs` 的 `scanLogic`(:73)在把 gameDefinition 装配成可玩工厂、交 esbuild 打包**之前**,对模型产出的 `behavior.code` 和 `rule.condition` 做静态扫描。这套扫描是 gamedef 专属的:它针对的 `behavior.code` / `rule.condition` 串字段只存在于 gameDefinition,而 A-model 写真 src/ 多文件没有这类逻辑串字段,故随 gamedef 废弃而不再是现行路径。`LOGIC_BANS`(:42-63)是实际的拦截清单:沙箱逃逸类拦 `process`、`require`、动态 `import(`、`globalThis`、`eval(`、`.constructor`、`Function(`;DOM 与网络类拦 `document`、`window`、`fetch(`、`XMLHttpRequest`、`addEventListener`、`requestAnimationFrame`;死循环类拦 `while(true)`、`while(1)`、`for(;;)`;还有确定性逃逸类拦 `Math.random`、`Date.now`、`new Date`、`performance.now`(取证要可复现,逻辑里只许用 `rt.random` / `rt.time.now`)。`rule.condition` 另有专属禁则 `CONDITION_BANS`(:65-70):它必须是一个无副作用的布尔表达式,所以拦 `;`(不许是语句)、拦赋值 `=`、拦调世界变更方法 `addScore/setScore/spawn/destroy`、拦 `win()/lose()`。命中任何一条就转成 `validationError` 回灌给 repair 反馈,而不是靠 prompt 自觉。这层为什么必须在 build 边界做:同步 JS 没法在进程内硬中断,死循环和逃逸一旦执行就晚了,所以在执行前的校验边界把危险模式拦掉(:13-15 的信任模型注释)。 **第二层是 iframe 的 CSP。** `inject.ts`(:80-81)把 CSP 硬编码进 srcdoc 的 `` 标签,内容是 `default-src 'none'; script-src 'unsafe-inline' 'unsafe-eval'; style-src 'unsafe-inline'; img-src data: blob: https:; connect-src 'none';`。`connect-src 'none'` 是这层最关键的一条——它禁掉一切网络出站。引擎 bundle 不在 iframe 内 fetch,而是由宿主层 fetch 后内联进来,所以 `connect-src 'none'` 不会卡死引擎装载(:72-73)。`default-src 'none'` 兜底封掉其余所有未显式放开的资源类型。这里有一处和文档对不上的真实债:`script-src` 实际是 `'unsafe-inline' 'unsafe-eval'`,不是文档写的 `'self'`,原因和承接见 §8 漂移①。 @@ -143,7 +143,7 @@ bundle 是可执行脚本,内联进 `