docs(arch-atlas): 收口单一全量主档——删冗余导览式apex+7域图说

创始人裁定'删冗余只留全量主档':
- 删 系统全景图说.md(导览式apex)+ 7 域图说(产品/架构/沙箱/后端/前端/运营/运维),内容已全部 inline 进 系统全图说.md;SVG 与各域 README 保留不动。
- 系统全图说.md 防漂移门改指真实设计档(6域README + 13模块/契约总览/产物执行沙箱/数据模型/鉴权/观测/k8s/生成引擎README)的 commit hash,非已删的中间图说;每图具体映射见图脚注。
- 顶层 README 加'看图入口'指向全量主档;.agents/skills 配方 + plan 同步为'单一全量主档'口径(多文件跨子目录不渲染→合并一篇引子目录assets)。
复核:35 图嵌入零缺失、36 Mermaid 完好、目录锚零断链。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
zizi 2026-06-22 15:07:50 +00:00
parent 799ec6790f
commit 28e70d7d7b
12 changed files with 16 additions and 1633 deletions

View File

@ -9,7 +9,7 @@
## 产物形态
- **混合**:复杂/跨域图 = 手绘 **SVG** 大图(高保真、矢量、GitHub 直渲);简单/线性图 = **Mermaid** 内联。
- 每张 SVG 另在 **mini-desktop** 批量转 PNG 入仓(6c6g 禁 chrome、无转换器)。SVG 只在 6c6g 出。
- 每域一份 `<域>图说.md` + 同级 `assets/`;总图叙 = `docs/architecture/系统全景图说.md` + `docs/architecture/assets/`
- **最终产物 = 单一全量主档** `docs/architecture/系统全图说.md`(总图 + 目录 + 全部图说 inline 在一篇)。**为什么不分多文件**(2026-06-22 创始人反馈纠偏):多文件形态下,顶层/某文档跨子目录引用另一子目录里的 SVG,在部分渲染环境**不显图**;故合并成一份顶层文档。SVG 仍按域留各子目录 `assets/`(产出阶段如 `运维/assets/``架构/assets/`),主档经**顶层相对路径**(`运维/assets/xx.svg``架构/assets/arch-xx.svg`,apex 系统级图在 `assets/xx.svg`)引用,全部 inline 渲染。各域 `README.md` 是既有设计档、不动
## SVG house style(逐条照做,违一条图废)
- 头:`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1480 H" font-family="-apple-system,'PingFang SC','Microsoft YaHei',Segoe UI,sans-serif">`,H 按内容 700~960。
@ -35,7 +35,7 @@
## 编排配方(按域并行)
- **每域一个 opus agent**(`agentType: general-purpose`,可 Write),克隆金样板:读 计划稿+金样板 md+2 张金样板 SVG+本域源档 → 逐图产出(SVG/Mermaid/引用)→ 自检 → 汇编 md。结构化返回 `{docFile, svgFiles, figureCount, svgOk, statusDisciplineNote, singleSourceNote, selfCheck, flagsForReview}`
- 多域 = `parallel()` 扇出(不同域不同文件夹、零碰撞,无需 worktree 隔离)。同域两份图说共享 `assets/` 时用文件名前缀区分(如 `arch-` / `sbx-`)。
- **总图叙 apex 单独产**(导览要引用已建成的各域图说,放最后做)。
- **合并成单一全量主档**(放最后,关键收尾):各域产出 + 系统级图 → 合进 `系统全图说.md`。规则:逐字保留各域散文、SVG 改顶层相对路径、「引」图 inline 其 README 的 Mermaid(带「(图源:…)」小注)、顶部生成目录锚(GitHub-slug 算法,逐个核命中零断链)。生成引擎子树只链接不并入。**各域中间产物(per-domain `<域>图说.md`)是临时件,合并后删除**(避免与全量主档双份漂移),SVG 留子目录;主档防漂移门改记真实设计档 hash(非中间图说)。
- **分两期降风险**:先六域(自包含、可立全局轮廓),后生成引擎子树(最厚、且常被另一 session 在飞建——**第二期前必先跨 session 对齐边界、只链不双写**)。
## 复验脚本(主会话亲验,不轻信 agent 自检)

View File

@ -3,6 +3,7 @@
> **这是什么**:绘境AI 全部设计文档的**唯一入口**。无论你是产品、工程师、运营,还是外部评审,都从这里开始。
> **读它 = 当前真相**。这套文档是项目的策展层(curation layer)——经过收敛、只保留一份真值;过程稿、评审记录、历史留痕在别处(见文末"其它去哪找")。
> **怎么用**:先看下面这张全景图认门,再按你的角色跳到对应领域的主文档,需要细节时层层下钻。
> **看图入口(架构图集)**:全部架构图(系统级 + 七领域 ≈ 71 张图 + 讲解)已合并为一篇 → **[系统全图说](系统全图说.md)**——打开一篇、看图加讲解读懂整个系统、据图 review 设计有没有缝。
---

View File

@ -1,216 +0,0 @@
---
date: 2026-06-22
topic: 产品域图说——把「绘境AI 对用户提供什么」画成一套图 + 讲解(架构图集第一期·产品域)
status: 全图状态 = 现(产品定义层;个别元素含 future-state 注脚,已就元素级标注)· 防漂移门记五份源档 commit hash
映射源档:
- docs/architecture/产品/README.md @ 366a44b4
- docs/architecture/产品/需求清单.md @ 15b707fd
- docs/architecture/产品/需求模块映射.md @ 7ecd616e
- docs/architecture/产品/商业定位.md @ f4ee2310
- docs/architecture/产品/护城河话术.md @ 5cadf504
---
# 产品域图说
> **这是什么**绘境AI 产品域的「看图入口」。产品域只回答一件事——**这个产品对用户提供什么**WHAT不碰「用什么技术实现」HOW那部分在[架构域](../架构/README.md))。这份图说把产品域五份 canonical 设计档画成一套图:从最顶层的「做得出 → 有人玩 → 赚到钱」闭环,到 19 个产品域如何归拢成五大块,到 155 条需求怎样收敛成 55 条 P0到产品需求与技术模块之间那张唯一的多对多映射表再到创作者与玩家两条旅程最后落到商业定位与护城河。复杂、跨块的用手绘 SVG 大图,简单、线性的用 Mermaid已经内嵌在 README 里的图一律单源引用、绝不复制。
>
> **给谁看**:产品经理、新加入的同事、外部评审、投资人尽调,以及任何想先建立「这个产品到底要给谁、给什么」全局认知的人。判断「这套产品方案是不是想要的那个」看这份图就够建立全局轮廓;逐条需求的字句仍去[需求清单](需求清单.md),每条需求由哪些技术模块实现仍去[需求模块映射](需求模块映射.md)。
---
## 0. 阅读约定与同步纪律
- **映射的设计档**:本图说不另立设计,只把产品域五份 canonical 设计档画出来——产品闭环与 19 域归类出自 [`产品/README.md`](README.md)155 条需求与编号体系出自 [`需求清单.md`](需求清单.md),需求↔模块的多对多映射出自 [`需求模块映射.md`](需求模块映射.md),商业定位与竞争格局出自 [`商业定位.md`](商业定位.md),对外护城河口径出自 [`护城河话术.md`](护城河话术.md)。frontmatter 里记了这五份的当前 commit hash作为**防漂移门**源档一旦变更、hash 对不上,这份图说与对应 SVG 即标「待复核」,由收口脚本比对。
- **同步纪律****设计一变动,本图说与对应 SVG 必须同步更新**,每张 SVG 脚注注明映射源档与状态。已并入 wave 收口清单。
- **本域状态分布**:产品域是**定义层**而非建设层——它描述的是「产品要提供什么」,不是「代码建到了哪一步」,所以**九张图整体状态都是「现」**(即「这是当前认定的产品定义」),与运维域那种「现行/待接/缓做」三态并存的情况不同。但有两处必须用元素级虚线标清楚、绝不能画成已落地的 MVP 范围:一是**第二条生成轨tier2 富游戏轨)**,它是经营/合成/挂机等 premium 品类的承载,目前是待 0 号 spike 验证的假设、未落代码、不在 MVP 的 P0 清单、也不单列正式 P-id二是**控制面 / 管理面治理层**,两条生成线共用、部分有地基、整体待建。这两处在图 2 与图 5 里都用紫色虚线框 + 「待建 / post-spike」小标与「现行已认定」的实心块区分开。**至于这 55 条 P0 各自的真实代码完成度**(哪些真端到端、哪些半真、哪些还是桩),那是建设进度、不是产品定义,以 [`需求模块映射.md`](需求模块映射.md) 的现状快照与 [`docs/mvp/MVP进度总账`](../../mvp/MVP进度总账.md) §2 矩阵为准,本图说不重复承载、不画成产品图的一部分。
- **产物形式**SVG 入仓GitHub 与编辑器直接渲染矢量PNG 在 mini-desktop 转6c6g 禁 chrome、无转换器。本图说只出 SVGMermaid 图 GitHub 直接渲染、无需转换;引用类图只给链接、不产新文件。
## 1. 全图通用图例
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上)。产品域是定义层,不直接谈安全/可观测/可靠这些运行时维度,所以本域只点到其中两个与「产品价值」最相关的:
- **数据**`#475569`19 域全景与需求映射本身就是产品的数据底座;护城河四层里最硬的第一层也是数据壁垒——玩家行为数据 + 质量评分 + 推荐信号。本域里凡是讲「数据回流 / 越用越聪明 / 飞轮」的地方都点这个维度。
- **质量**`#15803d`):⭐ 三个 P0 最密集的域(自定义创作 / 发布分发 / 游戏信息流)串起的正是「能生成、能发、能刷到」的质量闭环;这条闭环每一环都真实跑通,是 MVP 不追求功能多、只追求闭环跑通的体现。
(其余五个维度——安全 `#dc2626`、可观测 `#0ea5e9`、可靠 `#16a34a`、成本 `#16a34a`、伸缩 `#7c3aed`——属于运行时与工程视角,在架构域 / 后端域 / 运维域的图说里点到;产品域刻意不碰,以守住「只讲用户能感知什么」的纪律。唯一例外是图 9 的商业定位,那里「资本效率」天然对应**成本**维度,故在该图点到。)
**复用 / 边界三线语义**
- **实线**`#334155`):现行已认定的产品定义、块间产物的正向流转、★主映射(主要实现一条需求的技术功能)。
- **虚线**`#64748b``stroke-dasharray="6 4"`;待建项用紫色 `#7c3aed`):辅映射(支撑/兜底)、收益与数据的回流路径、以及 future-state第二条生成轨 / 治理层 / 要点燃的护城河)。
- **双线 / 加粗框**:跨侧共享或需要强调的边界——典型是图 5 中间那张 RTM 表,它是产品侧与技术侧之间唯一的耦合隔离面,用加粗框强调「改一侧只动这一张表」。
> 产品域图说里,虚线额外承担一层**诚实纪律**:凡是「未来式 / 待建」的东西(护城河飞轮、第二条生成轨、治理层),一律虚线 + 小标画出,与「现在真有的」实心块一眼区分。这是产品域最该守的纪律点——护城河话术的核心就是「不假装有墙」,任何一处把未来式画成已有,都会击穿信任。
---
## 2. 图集
### 图 1 · 产品闭环全景〔引·现〕
> 单源引用,不复制:产品闭环全景的 Mermaid 已在 **[产品/README.md §1](README.md#1-一句话与一张图绘境ai-是什么)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来——同一张图存两处、改一处漏一处,正是这份图集要消灭的漂移面。
这张图回答最顶层的问题:**绘境AI 到底是什么**。答案是一条闭环——把三件过去彼此割裂的事接成一条链:一个没有任何编程基础的普通人,从一句话出发做出一款能上线、能变现的轻量小游戏(**创作**);玩家在类似短视频的游戏信息流里刷到它、即点即玩(**分发与游玩**平台通过广告、订阅会员、B 端定制三条线变现,收益与行为数据再回流反哺推荐(**变现与数据**)。
读这张图要抓住一句话:**这条闭环就是所有产品功能挂靠的主干**。竞品大多停在「生成工具」这一步——做完没人玩、也不赚钱;绘境的差异化不在生成本身,而在把「生成 + 流量 + 变现」串成一条链。图里那条从「收益 & 行为数据」回到信息流的虚线尤其关键:它是平台「越用越聪明」的来源,也是后面图 9 里数据护城河的产品侧投影。这张图没有现行/远期的灰度,它就是当前认定的产品骨架;它与本图说后面所有图的关系是「图 1 给主干,其余八张图把主干的每一段展开」。
### 图 2 · 19 个产品域 × 五大块SVG新·架·现
![图 2 · 19 个产品域 × 五大块](assets/02-19产品域五大块.svg)
这张图把图 1 那条线性闭环展开成产品的**全貌**155 条需求按「用户能感知的能力」聚成 19 个产品域,再归拢成五大块,让人一眼看清这个产品由哪些可感知的能力块组成、它们之间怎么流转。五大块从左到右就是闭环的五个阶段——**创作侧**把游戏做出来(素材/模板/自定义创作/授权 IP/发布5 个域)、**玩家侧**让游戏被玩到(广场/信息流/社区3 个域)、**变现侧**把钱赚回来(钱包/付费/广告3 个域)、**成长侧**让创作者留下来(数据经营/成长/激励/通知4 个域)、**平台侧**让生态转起来IP 孵化/B 端/运营/账号合规4 个域)。块顶之间的实线箭头画出产物流转的主方向:创作侧产出 → 玩家侧消费 → 变现侧回钱 → 成长侧留人 → 平台侧转生态。
读这张图要抓住三个细节。其一,图上用蓝色高亮块钉死了 **⭐ 三个 P0 最密集的域**:自定义创作、发布分发、游戏信息流——它们是 MVP 闭环的关键环节,「能生成、能发、能刷到」这条最小链全靠它们撑起;其余域多为 P1/P2 的后续加厚。其二每个域卡片右上角标了该域的优先级密度P0 / P1 / P0-P1 混合),让人快速判断哪些域是 MVP 必交、哪些是远期。其三,也是本图最该让人看清的**设计缝**:创作侧底部那个紫色虚线框——**第二条生成轨tier2 富游戏轨)**。当前 19 个域承载的是超休闲档的廉价生成线;经营、合成、挂机这类多系统的 premium 品类不在这条线上,而由第二条生成轨承载,它面向价值更高、产量更低的场景,与超休闲线解耦并存。这一轨目前是**待 0 号 spike 验证的假设、未落代码、不在 MVP 的 P0 范围、也不单列正式 P-id**——所以图上必须用虚线把它和 19 个实心域块严格区分,绝不能让人误以为它已是 MVP 的一部分。它的完整设计在[架构域生成引擎子树](../架构/生成引擎/自治富游戏引擎.md),本图只挂一个边界注脚。
### 图 3 · 155 → 55 P0 收敛〔引·现〕
> 单源引用不复制155 → 55 收敛的 Mermaid 已在 **[产品/README.md §4](README.md#4-mvp-的边界155-选-55)** 内嵌,是该图的唯一来源。这里只链接、不抄。
这张图回答「MVP 到底做多少」。完整产品有 155 条需求分布在 19 个域MVP 阶段不全做,而是聚焦其中 **55 条 P0**——它们刚好串起一条「种子用户可试用的全链路」:创建 → 生成 → 预览 → 发布 → 信息流 → 游玩 → 互动 → 广告 → 收益。这张图最该让人记住的,是它背后那条产品哲学:**MVP 不追求功能多,而追求这条闭环每一环都能真实跑通**P1/P2 是闭环跑通之后的加厚,不是 MVP 的考核项。
这条「155 选 55」的收敛口径是理解整个产品域优先级的总开关——图 2 里 ⭐ 标记的三个 P0 密集域为什么最硬,正是因为它们贡献了这 55 条里最关键的那些环。要注意的设计缝在于55 这个数字是**产品验收口径**(哪些功能 MVP 必须可验收),不是**建设完成度**(这 55 条各自代码建到了哪一步)。两者是两回事——某条 P0 在产品口径上「必交」,不等于它今天已经真端到端;真实完成度以需求映射的现状快照与 MVP 进度总账为准(详见 §0 的纪律说明)。
### 图 4 · 需求编号体系Mer新·讲·现
这张图讲清「怎么读懂一条需求」。需求清单里每一行是一条产品功能,带四个属性;第一次接触的人只要会拆这四个属性,就能读懂整份清单。**编号** `P-{域}-{序号}` 把每条需求挂到它所属的产品域域用三字母缩写MAT 素材 / TPL 模板 / CRT 创作……);**端** 说明这条功能服务谁(创作者 / 玩家 / 经营 / 运营 / B 端 / 通用——其中「经营」特指创作者查看自己作品的数据,与「运营」即平台管理员不是一回事,这是最容易混的一对);**优先级** 区分 P0MVP 必须验收)与 P1/P2后续迭代**来源** 标这条需求是从早期 demo 原型来的、还是延续既有能力v2.0)、还是 demo 暴露出的缺口编号G#)。
```mermaid
flowchart TB
ID["一条需求 = 一行<br/>P-CRT-08 生成结果实时预览试玩"]:::id
ID --> A1["① 编号 P-{域}-{序号}<br/>P-CRT-08 = 自定义创作域第 8 条<br/>域用三字母缩写"]:::attr
ID --> A2["② 端:服务谁<br/>创作者 / 玩家 / 经营 / 运营 / B端 / 通用<br/>⚠️ 经营=创作者看自己数据 ≠ 运营=平台管理员"]:::attr
ID --> A3["③ 优先级<br/>P0 = MVP 必须验收155 里 55 条)<br/>P1 / P2 = 后续迭代"]:::p0
ID --> A4["④ 来源<br/>demo = 早期原型出现过<br/>v2.0 = 延续既有能力 · G# = demo 暴露的缺口"]:::attr
classDef id fill:#eff6ff,stroke:#2563eb,stroke-width:2px;
classDef attr fill:#ffffff,stroke:#475569,stroke-width:1.4px;
classDef p0 fill:#fef9c3,stroke:#ca8a04,stroke-width:1.6px;
```
这张图没有现行/远期边界,它是一份「读法说明」,本身就是当前真相。它和图 2、图 3 是一组:图 4 教你拆单条需求的四个属性,图 2 把这些需求按域聚成全貌,图 3 用「优先级」这个属性把 155 收敛成 55。要点出的一处易错点已经画在图上——**端属性里「经营」和「运营」必须分清**:经营是创作者侧(看自己作品的留存/完玩/广告转化),运营是平台管理员侧(审核/精选/封禁/经营看板两者在需求清单里分属不同的域OPS vs OPN混了就会把功能归错端、排错期。
### 图 5 · 需求 ↔ 模块 M:N 映射RTMSVG新·ER·现
![图 5 · 需求 ↔ 模块 M:N 映射RTM](assets/05-需求模块映射RTM.svg)
这张图回答「一条产品需求由谁实现」——也是产品域与技术域之间唯一的桥。它画的是一张**关系矩阵**(不是面向对象的类图):左侧是产品侧的 155 条需求(按五大块分组的 P-id右侧是技术侧的 13 个模块204 条 T-id中间是这张 RTMRequirements Traceability Matrix需求可追溯矩阵用多对多的连线把两侧关联起来。之所以要单独有这么一张表是因为产品需求和技术模块**各自高内聚、互不引用**——需求清单不认识 T-id架构域不认识 P-id两者之间的多对多对应关系是最容易变动的耦合点把它单独隔离在这一张表里**改产品或改模块,只动这一张表**,另一侧纹丝不动。
读这张图要抓住三层意思。其一,**三个读法标记**:每行一条 P-id标了它的「首要 owner」主要负责的那一个模块问责与排期归属、「★主」主要实现这条需求的技术功能可以是多个 T-id、「辅」支撑或兜底的技术功能常跨模块。图中央用一行放大的样例把这三层讲透——产品需求「生成结果实时预览试玩」P-CRT-08首要 owner 是 runtime 模块,★主靠 T-RT-01 编译 / T-RT-06 渲染容器 / T-RT-07 注入 / T-RT-04 沙箱四个技术功能,辅以 T-STU-07 的 SSE产品侧完全不需要知道这些 T-id技术侧也不需要知道 P-id只有这张表两边都认识。其二**多对多是双向的**:一个产品域会连多个技术模块,一个技术模块也会被多个产品域连——图上的交叉连线刻意画出这种「网状」而非「一一对应」的关系,这正是为什么必须用一张专门的矩阵、而不能把映射塞进任何一侧。其三,本图最该让人看清的**设计缝**画在中间表底部那个紫色虚线框里:**两块「待建 · post-spike」的映射**——第二条生成轨tier2 富游戏轨)和控制面/管理面治理层。这两块设计已经成形、但尚未落地,先在 RTM 里挂上指针、免得它们在产品与技术之间悬空;但它们**还没有正式的 T-id 与映射行**,要等 0 号 spike 验证通过后才展开。所以图上用虚线把这两块和 19 个域的实心映射严格分开——它们是「已挂指针、待建设」,不是「已映射、已实现」。
### 图 6 · 五大块产品域关系Mer新·架·现
这张图把图 2 里五大块之间那几根块顶箭头单独放大,讲清「产物在五大块之间怎么流转」。如果说图 2 是「五大块各装了哪些域」的静态全貌,这张图就是「五大块之间动态怎么咬合」的流转图:创作侧产出可玩游戏,是整条链的源头;玩家侧消费这些游戏,把「有人玩」坐实;玩家的游玩与互动触发变现侧把钱赚回来;赚到的收益与沉淀的数据反哺成长侧,让创作者看到回报、愿意留下来继续创作;而平台侧作为底座,一边给生态提供 IP/B 端/运营/合规的支撑,一边把数据与收益的回流闭合回创作侧——形成「创作产出 → 玩家消费 → 变现回流 → 创作者留存 → 再创作」的飞轮。
```mermaid
flowchart LR
CRT["创作侧<br/>把游戏做出来<br/>素材/模板/创作/授权IP/发布"]:::crt
PLZ["玩家侧<br/>让游戏被玩到<br/>广场/信息流/社区"]:::play
PAY["变现侧<br/>把钱赚回来<br/>钱包/付费/广告"]:::pay
GRW["成长侧<br/>让创作者留下来<br/>数据经营/成长/激励/通知"]:::grow
OPN["平台侧(底座)<br/>让生态转起来<br/>IP孵化/B端/运营/账号合规"]:::plat
CRT -->|"产出可玩游戏"| PLZ
PLZ -->|"游玩+互动触发"| PAY
PAY -->|"收益+数据反哺"| GRW
GRW -.->|"创作者继续产出(飞轮)"| CRT
OPN -.->|"IP/B端/审核/合规 支撑全链"| CRT
PAY -.->|"行为数据回流→推荐优化"| PLZ
classDef crt fill:#eff6ff,stroke:#2563eb,stroke-width:2px;
classDef play fill:#f0fdf4,stroke:#16a34a,stroke-width:2px;
classDef pay fill:#fefce8,stroke:#ca8a04,stroke-width:2px;
classDef grow fill:#fdf4ff,stroke:#a21caf,stroke-width:2px;
classDef plat fill:#f1f5f9,stroke:#475569,stroke-width:2px;
```
这张图没有现行/远期边界,它是当前认定的产品域间关系。它最该让人看出的是两条**回流虚线**——从成长侧回到创作侧的「创作者继续产出」、从变现侧回到玩家侧的「行为数据回流推荐优化」:正是这两条回流把一条线性的价值链弯成了飞轮,也正是它们对应了商业定位里「数据/网络飞轮」这层护城河(见图 9。要点出的设计缝是平台侧被画成「底座」而非链上的一环——它不在主流转线上而是横向给全链提供 IP、B 端、审核、合规的支撑;这与图 2 把平台侧画成第五大块并不矛盾,图 2 讲的是「它装了哪些域」,本图讲的是「它在流转中扮演底座角色」,两个视角互补。
### 图 7 · 创作者旅程Mer新·时·现
这张图从**创作者**的视角,把图 1 闭环的「创作侧 + 成长侧」展开成一条时间线上的旅程:一个创作者从进入平台到看到收益,依次经历哪些步骤、每步落在哪个产品域。它回答的是「一个创作者在这个产品里的一天是怎样的」——这是产品体验的主线之一,也是判断「创作侧的产品设计是否顺畅」的依据。
```mermaid
sequenceDiagram
autonumber
actor C as 创作者
participant MAT as 素材中心(MAT)
participant CRT as 自定义创作(CRT)
participant RT as 实时预览
participant PUB as 发布分发(PUB)
participant OPS as 数据经营(OPS)
C->>MAT: 挑素材 / 选玩法模板(可选)
C->>CRT: 一句话描述要做什么游戏
CRT-->>C: AI 生成可试玩游戏 + 进度实时展示(步骤+百分比)
C->>RT: 预览试玩
alt 不满意
C->>CRT: 带描述迭代 / 一键重新生成
CRT-->>C: 重新生成
end
C->>PUB: 发布前检查(锁风+性能+版权)→ 一键多渠道发布
PUB-->>C: 自有必选 + 抖音/微信/快手/TapTap外部渠道远期
Note over C,OPS: 游戏上线、被玩家刷到、产生收益与行为数据
OPS-->>C: 数据看板 / 留存趋势 / 收益明细 → 看到回报
```
这张图把创作者旅程画成「挑素材 → 一句话生成 → 预览迭代 → 发布 → 看收益」五段。最该让人看出的是**两个体验关键点**:一是生成环节的「进度实时展示 + 预览试玩 + 带描述迭代」闭环——这对应 P0 最密集的自定义创作域它决定创作者第一次用的时候「等得安不安心、改得动改不动」是留存的第一道关二是旅程末端的「看到收益」——OPS 数据经营让创作者看到留存、趋势与收益明细,对应成长侧「让创作者留下来」的产品意图,把一次性创作变成可持续经营。要点出的设计缝是:发布环节的**外部渠道(抖音/微信/快手/TapTap当前是远期**——自有渠道是 MVP 必选且已真端到端,外部渠道在产品口径里是 P1、代码侧基本未建详见需求映射现状快照所以图上把外部渠道标为远期避免让人以为一键多渠道里的每个渠道今天都通了。
### 图 8 · 玩家旅程Mer新·时·现
这张图从**玩家**的视角,把图 1 闭环的「玩家侧 + 变现侧」展开成一条旅程:一个玩家从刷到游戏到产生互动与变现,依次经历哪些步骤。它和图 7 是一对——图 7 是「做游戏的人」的主线,图 8 是「玩游戏的人」的主线;两条旅程在「游戏被发布出来、进入信息流」这一点交汇。
```mermaid
sequenceDiagram
autonumber
actor P as 玩家
participant FED as 游戏信息流(FED)
participant RT as 即点即玩(沙箱运行时)
participant SOC as 社区互动(SOC)
participant ADV as 广告变现(ADV)
participant STU as 同款创作(→工作坊)
P->>FED: 打开游戏信息流 → 竖屏即刷
FED-->>P: 首屏封面(封面/标题/作者/玩法/开始) + 加载进度反馈
P->>RT: 点击即玩(无需下载安装)
RT-->>P: 即点即玩,上下滑/按钮切换下一款
P->>SOC: 点赞 / 收藏 / 分享到社交平台 / 举报
Note over P,ADV: 游玩中触发变现
ADV-->>P: 激励视频(看 30s 换复活/道具) / 插屏广告
opt 玩家被激发想自己做
P->>STU: 「发起同款」跳转工作坊 → 变成创作者
end
```
这张图把玩家旅程画成「刷 feed → 即点即玩 → 点赞分享 → 发起同款」。最该让人看出的是**两处产品设计的巧思**:一是「即点即玩」——首屏封面给足信息、点击就玩、无需下载安装、上下滑就换下一款,这套竖屏短视频式的体验是绘境区别于「下载-安装-启动」传统小游戏的差异化主战场,对应 P0 最密集的游戏信息流域;二是旅程末端的「**发起同款**」——一个玩家如果被某款游戏激发、想自己做一个可以一键跳转工作坊变成创作者P-FED-12。这一步是整个产品最重要的闭环回路它把「玩家」转化成「创作者」让图 7 的创作者旅程与图 8 的玩家旅程**首尾相接**,正是商业定位里「网络效应」护城河(创作者越多→内容越丰富→玩家越多→创作者越多)的产品载体。要点出的设计缝是:广告变现里**真实广告联盟 SDK 当前是待接的**——计费业务逻辑已真mock 可端到端跑通),但接真实广告联盟受日历闸门(广告资质)约束(详见运营域合规闸门与需求映射现状快照),所以这条变现在产品口径上成立、在落地上还卡着外部资质。
### 图 9 · 商业定位与护城河一图SVG新·讲·现
![图 9 · 商业定位与护城河一图](assets/09-商业定位与护城河.svg)
这张图回答「绘境AI 在市场上是谁、靠什么赢」——它把商业定位、竞争格局、资本效率与护城河路径压进一张图,是面向投资人尽调与对外沟通的总览。它也是本图说**最该守诚实纪律**的一张:护城河话术的核心铁律是「**不假装有护城河**——卖的是『不公平起跑 + 飞轮与生态护城河的路径』,任何一处言过其实都会击穿全局信任」;所以图上把「现在真有的」和「要去点燃的」用实心块与紫色虚线框严格分开,绝不让人误以为护城河已经建好。
图分四层来读。**最上一句话定位**:绘境 = 唯一把「做得出 → 有人玩 → 赚到钱」接成一条闭环的 AI 游戏生态平台,竞品停在生成工具,绘境做全链路——并明确点出「生成是入场券,不是壁垒」。**差异化闭环**那一行把三件事接成链,并在右侧钉死一个最容易被误解的点:护城河真正的来源是数据/网络效应/资产/合规四层,**不是生成引擎**——大模型会追平生成,但追不平这四层沉淀。**中段左侧竞争格局**用三家竞品(极逸 SOON 自研最强但无流量无变现、TapTap 制造有流量但封闭分成低、FunloomAI 有付费验证但品类窄无流量)说明绘境的避战策略:不在技术深度上硬碰,而抢「生态完整度」这条没人占的轴,结论是「技术深度认输,生态完整度抢第一」。**中段右侧资本效率**把「现在真有的不公平起跑」量化——约 1/5 成本、约 1/3 时间、钱撑 18-24 月,策略是「能用成熟开源/商用组合的绝不自研,自研只投在必须自掌的控制点 + 数据入口」。
整张图最该让人看清的是**底部那一栏的诚实切分**:护城河的四层(数据壁垒 / 网络效应 / 资产壁垒 / 合规壁垒)全部用紫色虚线框 + 「未来式」小标画出,因为它们是**要在窗口期6-12 个月)里点燃的、而不是已经有的**——短期没有护城河,有的是上面那三样不公平起跑,融资就是点火的燃料钱。这层切分必须看清:如果把飞轮、网络效应、生态资产画成「已有的墙」,就违背了护城河话术的红线。要补充一处源档里的设计缝(图上未展开、读图时一并记住):对外话术与内部判断有一处**刻意的时间差**——护城河话术 B3 对外仍说「复杂引擎用 Cocos / 不自研引擎」,但内部已改判 tier2 富游戏自治轨走 AgentScopePython 自治 ReAct+ Phaser/Pixi 全无头引擎、Cocos 收窄到 3D / 复杂场景 / 渠道导出轴(仍是有效决策、非废弃);因为 tier2 还在 0 号 spike 待验,没验证的东西不对外背书,等 spike 过了再同步对外口径。这处「内外口径暂不一致」是有意为之、有据可查,不是漏洞。
---
## 3. 图清单与状态表
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 产品闭环全景 | 流 | 引(链 README §1 | 现 | 做得出→有人玩→赚到钱 闭环主干 + 数据回流;所有产品功能挂靠的主干 |
| 2 | 19 个产品域 × 五大块 | 架 | SVG新 | 现 | 创作/玩家/变现/成长/平台 五大块归拢 19 域 + ⭐三 P0 密集域 + 块间流转 + tier2 第二轨边界(虚线·待建) |
| 3 | 155 → 55 P0 收敛 | 流 | 引(链 README §4 | 现 | 155 条完整需求 → 55 条 P0MVP 验收口径)→ 覆盖全链路闭环;不追功能多、追闭环跑通 |
| 4 | 需求编号体系 | 讲 | Mer新内联 | 现 | `P-{域}-{序号}` + 端/优先级/来源 四属性怎么读;经营≠运营 易错点 |
| 5 | 需求 ↔ 模块 M:N 映射RTM | ER | SVG新 | 现 | 产品需求(155 P-id) ↔ 技术模块(204 T-id) 多对多矩阵 + 首要owner/★主/辅 读法 + 两块待建映射虚线·post-spike |
| 6 | 五大块产品域关系 | 架 | Mer新内联 | 现 | 创作产出→玩家消费→变现回流→创作者留存 的块间流转 + 两条回流虚线(飞轮)+ 平台侧作底座 |
| 7 | 创作者旅程 | 时 | Mer新内联 | 现 | 挑素材→一句话生成→预览迭代→发布→看收益;生成迭代闭环 + 外部渠道远期标注 |
| 8 | 玩家旅程 | 时 | Mer新内联 | 现 | 刷feed→即点即玩→点赞分享→发起同款即点即玩差异化 + 同款回路接回创作者旅程 + 广告 SDK 待接 |
| 9 | 商业定位与护城河一图 | 讲 | SVG新 | 现 | 一句话定位 + 差异化闭环 + 竞争格局 + 资本效率 + 四层护城河(虚线·未来式,诚实不假装有墙)|
> **状态分布**:九张图整体状态全为 **现**(产品定义层)。其中三处以**元素级虚线**标出 future-state、绝不画成现行 MVP 范围:图 2 / 图 5 的**第二条生成轨tier2与治理层**(待 0 号 spike·未落代码·尚无正式 P-id、图 9 的**四层护城河**(要在窗口期点燃·未来式·非已有)。**防漂移门**:本图说 frontmatter 记五份源档的 commit hashREADME @ 366a44b4、需求清单 @ 15b707fd、需求模块映射 @ 7ecd616e、商业定位 @ f4ee2310、护城河话术 @ 5cadf504源档变更即比对hash 对不上则本图说与对应 SVG 标「待复核」。
>
> **产品定义 ≠ 建设进度**本图说画的是「产品要提供什么」55 P0 = 验收口径不是「代码建到哪一步」。55 条 P0 各自的真实完成度(真端到端 / 半真 / 桩)以 [`需求模块映射.md`](需求模块映射.md) 现状快照与 [`docs/mvp/MVP进度总账`](../../mvp/MVP进度总账.md) §2 矩阵为唯一 SoT本图说不重复承载。
>
> **PNG 后续**9 张图中 3 张为 SVG图 2/5/9SVG 入仓后在 mini-desktop 批量转 PNG6c6g 禁 chrome4 张 Mermaid图 4/6/7/8GitHub 直接渲染、无需转换2 张(图 1/3单源引用 README、不产新图。

View File

@ -1,201 +0,0 @@
---
date: 2026-06-22
topic: 前端域图说——把「绘境AI 有哪两个前端、靠什么撑起一致体验、生成出的游戏怎么在前端真玩」画成一套图 + 讲解(架构图集第一期·前端域)
status: 现行为主(图 18+ 待建一张(图 9 tier2 富游戏前端承载)· 防漂移门记源档 commit hash
映射源档:
- docs/architecture/前端/README.md @ 15b707fd
- docs/architecture/架构/产物执行沙箱.md @ 38357c3d
- docs/architecture/架构/生成引擎/引擎与运行时.md @ 7ecd616e
---
# 前端域图说
> **这是什么**绘境AI 前端域的「看图入口」。前端域回答三件事——绘境AI 有**哪两个前端、各服务谁**、它们靠**一套什么样的设计体系撑起一致的体验**(颜色、间距、字体、组件、主题、多语言这些视觉与交互的共同语言怎么统一沉淀)、以及生成出的游戏**怎么在前端被真正地玩起来**。这份图说把这三件事连同两件跨域的事试玩宿主的安全隔离、tier2 富游戏的前端承载),用一套图加配套讲解画清楚。复杂、跨层的用手绘 SVG 大图,简单、线性的用 Mermaid已有 README 内嵌的 Mermaid 一律单源引用、不复制。
>
> **给谁看**:前端工程师、设计师、产品经理、新加入的同事,以及做技术尽调的人。判断「这套前端方案是不是想要的那个」看这份图就够建立全局轮廓,逐令牌的取值仍去代码里的 `game-studio/src/styles/tokens.css`,逐组件实现去 `.agents/skills/` 下的操作手册。
---
## 0. 阅读约定与同步纪律
- **映射的设计档**本图说不另立设计只把前端域的现行设计画出来。设计体系两个前端、token 两层、组件库四层、三条数据流、三大契约、主题切换、视图地图)全部出自前端域的 canonical 设计主文档 [`前端/README.md`](README.md);试玩宿主那张图(图 8的安全隔离细节交叉引用 [`架构/产物执行沙箱.md`](../架构/产物执行沙箱.md)tier2 富游戏承载那张图(图 9的装载侧细节交叉引用 [`架构/生成引擎/引擎与运行时.md`](../架构/生成引擎/引擎与运行时.md)。frontmatter 里记了这三份的当前 commit hash作为**防漂移门**源档一旦变更、hash 对不上,这份图说与对应 SVG 即标「待复核」,由收口脚本比对。
- **同步纪律****设计一变动,本图说与对应 SVG 必须同步更新**,每张 SVG 脚注注明映射源档与状态。已并入 wave 收口清单。
- **本域状态分布**:前端域的设计体系已全量收口并合入主干 `dev/2.0.0`,所以**九张图里八张是「现」**(现行已建);唯一的例外是图 9——tier2 富游戏的前端承载,归属已定(归前端域)但**代码未建**整图状态是「建」待建全图用虚线画、并在图顶加一条状态约定条绝不画成已建。本域不像运维域那样三态交织但「现」与「建」这条边界仍要看清别因为设计体系本身已收口就误以为第二条生成轨tier2的前端也建好了。
- **产物形式**SVG 入仓GitHub 与编辑器直接渲染矢量PNG 在 mini-desktop 转6c6g 禁 chrome、无转换器。本图说只出 SVG。
## 1. 全图通用图例
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上,前端域主要关心其中三个):
- **质量**`#15803d`):换肤零改组件、向后兼容别名、迁移期新旧共存、三条数据流解耦、业务域分块导航、统一圆角矩形——设计体系的一致性与可维护性是前端域的主轴。
- **数据**`#475569`token 作为「跨端单一事实源」、品牌字符串收敛到 `common.brand` 一个 key、逐令牌权威清单只在 `tokens.css` 一处——同一份事实只有一处权威定义。
- **安全**`#dc2626`):试玩宿主的 iframe 沙箱 + CSP + postMessage 双校验、路由守卫只认真实 token、匿名 `anonId` 衔接未登录态、`Icon` 禁用 emoji。
(前端域很少涉及**可观测** `#0ea5e9`、**可靠** `#16a34a`、**成本** `#16a34a`、**伸缩** `#7c3aed` 这几个维度;它们主要落在后端 / 运维域。tier2 承载那张图会点到一点伸缩——第二条生成轨让 feed 长成承载两类产物的能力。)
**复用 / 边界三线语义**
- **实线**`#334155`):现成直接用、同步消费、同业务域内的跳转。
- **虚线**`#64748b``stroke-dasharray="6 4"`):自建 / 解耦 / 远期铺路 / 待建的目标态、跨业务域的流转。
- **双线 / 加粗框**:跨域共享的公共件或需要强调的边界。
> 前端域图说里,虚线还额外承担一层**状态语义**:图 9tier2 富游戏前端承载)整图是「待建」,所以整张用虚线框画、配状态约定条;而图 2 设计 token 里「跨端使命」那一格虽然在「现」图里,但它本身是远期铺路(当前只服务 Web所以也用虚线单独框出。一眼区分「现行已建的实心块」与「远期 / 待建的虚线框」,是本域要守的纪律点——设计体系本身收口了,但不能让人误以为跨端 App、tier2 富游戏承载也跟着建好了。
---
## 2. 图集
### 图 1 · 两个前端定位〔引·现〕
> 单源引用,不复制:「两个前端定位」的 Mermaid 已在 **[前端/README.md §1](README.md#1-绘境ai-有两个前端)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来——同一张图存两处、改一处漏一处,正是这份图集要消灭的漂移面。
这张图回答「绘境AI 到底有几个前端、各是给谁的」。答案是**两个独立的前端应用**,刻意拆开,因为服务的人和承载的能力截然不同。**game-studio** 是产品前端,同时服务**创作者**(一句话生成游戏、预览迭代、发布、看收益)和**玩家**(刷短视频式的竖屏游戏信息流、点赞分享评论),用 **Vue3 + Vant**——Vant 是移动优先的 Vue 组件库,天然适配游戏流的滑动交互。**game-admin** 是管理后台前端,服务**平台运营**和**管理员**(内容审核、用户管理、数据看板、合规处置),用 **Vue3 + Element Plus**——这是绘境AI fork 的开源 Java 后台框架 Huijing 官方主推的桌面端组件库,二次开发友好。
读这张图要抓住一条范围边界:设计体系的建设**当前聚焦 game-studio**因为它直面大众市场、卖相与一致性要求最高、投入产出比也最高game-admin 是内部后台工具,沿用 Element Plus 默认体系即可,只在品牌色这一层与 studio 对齐。所以下面图 2 到图 7 讲的「设计体系」,除非特别标注 admin默认都是 studio 的。这张图没有现行 / 远期的灰度,它就是当前真相;它和这份图集里别的域的关系是——「前端域只讲两个前端长什么样、靠什么撑起一致体验」,产品对用户提供什么记在[产品域](../产品/README.md)、系统用什么技术搭起来记在[架构域](../架构/README.md),各司其职、互不重复。
### 图 2 · token 两层 + 组件库四层前端域最核心SVG升·架构·现
![图 2 token 两层 + 组件库四层](assets/02-token两层与组件库四层.svg)
这是整个前端域**最核心的一张架构图**,它由两条主线组成,理解了它就理解了设计体系为什么这么搭。左边是**设计 token 的两层结构**`primitive 原始层`只描述「物理事实」(`--cyan` 是某个青色、`--sp-3` 是 12px它只是调色板和尺子不带含义`semantic 语义层`描述「用途」(`--bg` 是页面背景、`--accent` 是强调色、`--danger` 是危险色、`--surface-1..3` 是从底到顶的层叠表面)。右边是**组件库的四层封装**`L0 token`把令牌落地成 CSS 变量、`L1 Vant 适配`把 Vant 的 `--van-*` 变量映射到我们的语义层、`L2 品牌基元`封装一批带绘境AI 气质的基础组件AppButton/Field/Icon/Card/Chip/EmptyState/NavHeader/TabBar/Skeleton/Toast`L3 业务组合`把基元拼成 GameCard/InteractBar/FilterTabs 这些业务组件。两条主线在**语义层交汇**——图上用最深的蓝色把语义层高亮出来,因为它是整个体系的支点。
这张图最该让人看出的,是 token 为什么要分两层、组件库的纪律是什么。**分两层的关键好处是「换肤时零改组件」**:组件只准引用语义令牌、绝不直接碰原始层;主题切换只需在语义层重新指向不同的原始色(暗色主题下 `--bg` 指向深色、浅色下指向浅色),组件因为只认 `--bg` 这个语义名,会自动跟着变,一行组件代码都不用动。图上把这条写进了高亮的语义层框里。**L1 那层的价值是「白嫖 Vant」**换的只是皮肤变量Vant 社区打磨多年的交互、无障碍、键盘支持原样吃下,不必自研——这是「复用现成」(实线)而非「自建」的典型。这张图里有一处刻意用虚线画的设计缝:左下角「跨端使命」那一格是**远期铺路、当前只服务 Web**——同一份 token 现在只喂 Web 的 CSS 变量,未来桌面 App 复用 Web 技术栈直接沿用、移动 App 把同一份 token 导出 JSON 喂 React Native / Flutter但这些都还没做。所以它虽然画在「现」图里本身却是远期用虚线框 + 「远期」小标单独标出,免得有人以为跨端 App 也建好了。
### 图 3 · 三条数据流token / theme / i18nSVG新·流·现
![图 3 三条数据流 token/theme/i18n](assets/03-三条数据流.svg)
这张图回答「设计体系在运行期是怎么动起来的」。如果说图 2 是设计体系的**静态结构**,那图 3 就是它的**三条单向数据流**,把那张静态图里的层「跑活」。**① token 流**`L0 token → L1 vant-theme → L2 品牌组件 → L3 业务面`,自底向上逐层消费——这是图 2 组件库四层在运行期的数据走向,组件只认下层语义名,所以换肤、跨端只动语义层一处。**② theme 流(换肤)**`localStorage(studio.theme) → <html data-theme> → 语义层覆盖 → 全组件自动反应`,源头是用户在设置里的选择(持久化在 `localStorage`,无值时一律回落暗色),`[data-theme]` 只覆盖语义层、不碰原始层。**③ i18n 流(国际化)**`main.ts 注册 vue-i18n → 组件用 useI18n($t) 取文案 → localStorage(studio.lang) 与 <html lang> 同步`,硬约束是禁组件内出现裸中文、缺失 key 回退 `zh-CN`、数字日期货币走原生 `Intl` 本地化。
这张图最该让人看出的,是三条流**互不耦合、各有清晰的源头与终点**正是这种解耦让「换肤」和「换语言」都做到零改组件。图上还点出两处共享theme 流和 i18n 流**共用同一套 `localStorage` + `<html>` 属性机制**——首屏内联脚本一并把 `data-theme``lang` 设好(这一步既是 theme 流防 FOUC 的关键,也是 i18n 流的语言初始化,图 6 会把这个时序单独放大);而 token 流的「为何单向」框里写明了一条贯穿全域的纪律——每层只认下层语义名所以无论换肤、跨端还是长期演进都只动语义层一处。i18n 流终点那个「品牌字符串收敛一处」(`common.brand` 一个 key值 = 「绘境AI」改名只改一处和 token 的「跨端单一事实源」是同一种思路:同一份事实只有一处权威定义,这是前端域「数据」徽章的由来。
### 图 4 · demo 取舍〔引·讲·现〕
> 单源引用不复制「demo 取舍」的 Mermaid 已在 **[前端/README.md §3](README.md#3-一个核心判断学-demo-的设计语言不学它的布局范式)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来。
这张图回答「设计体系从哪里起步、为什么是现在这个形态」。绘境AI 手上有一份早期的投资人路演原型 `docs-design/huijing-ai-demo.html`(简称 demo对它做了一个**决定整个前端形态的取舍判断****保留** demo 的「设计语言」token 体系、`cyan→green` 的品牌渐变、暗色玻璃质感,这套视觉语言有辨识度、值得沿用),**否决** demo 的「布局范式」(它是一个桌面产品外壳——固定 236px 宽的左侧栏 + 1140px 宽的工作台,把短视频流硬塞进一个 390×660 的模拟手机框里展示,这是投资人路演用的「控制台」叙事,不是真正给大众用户的消费级界面)。
读这张图要抓住一个产品判断:现行定位因此是**响应式优先的消费级 Web**——移动端做沉浸式全屏体验、桌面端做居中放大,一套组件适配两端;原生桌面 App、原生移动 App 都是更远期的层级,现在不做,但设计 token 提前为它们铺好了路(正是图 2 那个虚线的「跨端使命」)。这张图的设计缝在于:它是一份**记录型结论**,目的是防止后人把 demo 当成目标、反而削弱了 studio 已有的真实能力——README §7 专门列了一份「勿误砍 / 勿误判清单」,比如 studio 比 demo 多出来的「真实试玩宿主」(图 8 那套是护城河命门、绝不能因为「demo 里没有」就砍掉,而「首页门户 / 素材中心 / 玩法模板市场屏」这些是有意的 MVP descope、不是缺陷、别去返工。看这张图时把这条边界记住demo 给的是设计语言,不是产品蓝图。
### 图 5 · 三大契约token / 组件 / i18nSVG新·类·现
![图 5 三大契约 token/组件/i18n](assets/05-三大契约.svg)
这张图回答「设计体系对外暴露哪些不能私自破坏的约定」。它把三套契约并排画出来,每套是一个 `contract`(跨人协作时大家都遵守的约定)。**契约① token**:命名空间是 CSS 自定义属性,旧令牌(`--cyan`/`--green`/`--radius`/`--shadow`)全保留、其中 `--cyan` 被设为新语义令牌 `--accent` 的**向后兼容别名**,新增 primitive 原始层 / semantic 语义层 / 尺度令牌三组。**契约② 组件**`AppButton` 的 props`type/size/block/loading/disabled`保持不变、向后兼容primary 主按钮恢复了品牌签名渐变并补齐全部交互态focus 焦点环 / disabled 0.5 透明 / active 按压),`Icon` 组件禁用 emoji。**契约③ i18n**:用 `vue-i18n@10`,文案按业务域划分命名空间,品牌字符串收敛到 `common.brand` 一个 key。
这张图最该让人看出的,是三套契约**共守一条 additive增量式原则**——图顶用一条绿色总纲条钉死只增不毁旧引用零破坏各页面在迁移期新旧共存、逐面切换绝不一刀切。这条原则是设计体系能平滑落地、不把现有页面改崩的根本。图上还标了两条与别的图呼应的纪律token 契约里「三档主题 `[data-theme=light|dim]` 只覆盖语义层、不碰原始层」呼应图 2 / 图 3 的换肤机制;组件契约里那条用虚线框出的「圆角铁律」(禁药丸 / 椭圆 / 正圆混用,半径按尺寸分级 `xs/sm/md/lg/xl = 4/6/8/12/20`,默认 `md=8px`,唯一例外是 loading 旋转环保留圆形)单独立了一份规则文档 `.agents/rules/ui-uniform-rounded-rectangles.md` 约束,是创始人拍板的硬约束。这张图的设计缝提示在于:逐令牌的权威清单不在图里、以代码 `tokens.css` 为准——图只画契约的骨架与命名空间,别拿它当令牌字典用。
### 图 6 · 主题切换 [data-theme] + 防 FOUCMer新·时序·现
这张图把图 3 里 theme 流那条线**单独放大成一个时序**,讲清「用户切了主题,从点击到全屏变色,中间经过哪几步、为什么首屏不会闪」。它要解决的核心问题是 **FOUC**Flash of Unstyled Content即页面首帧闪现未应用样式的难看瞬间如果等到 Vue 应用挂载后才读用户的主题偏好那首屏会先用默认色画一帧、再「啪」地跳成用户选的色很难看。绘境AI 的解法是在 `index.html` 的首屏渲染**之前**内联一段脚本,先从 `localStorage``data-theme``lang` 设到 `<html>` 上,这样浏览器画第一帧时主题就已经是对的。
```mermaid
flowchart TB
CLICK["用户在设置内切主题<br/>(暗 / 浅 / 柔 三档)"] --> WRITE["写 localStorage<br/>studio.theme = light/dim/(暗=不写)"]
WRITE --> ATTR1["设 &lt;html data-theme&gt;<br/>运行期立即生效"]
ATTR1 --> COVER["语义层 [data-theme] 覆盖<br/>--bg/--surface/--accent… 重指向"]
COVER --> REACT["全组件自动反应<br/>(组件只认语义名 · 零改代码)"]
RELOAD["下次刷新 / 首次进入"] -.->|首屏渲染前| INLINE["index.html 内联脚本<br/>读 localStorage 先设 data-theme + lang"]:::boot
INLINE -.->|第一帧就是对的色| ATTR1
DEFAULT["无持久化值"] -.->|一律回落| DARK["暗色 (:root · 不写 data-theme)"]:::boot
RELOAD -.-> DEFAULT
classDef boot fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.5px,stroke-dasharray:5 4;
```
这张图最该让人看出的,是**防 FOUC 靠的是「首屏内联脚本」这个时机点**——图上用紫色虚线把这条「下次刷新 / 首次进入」的引导路径单独画出,它不是主交互流(实线那条是「用户当场切主题」),而是页面加载时的初始化路径,两条路殊途同归地把 `data-theme` 设对。还有一处产品默认值要记住:**首次进入默认暗色**`:root`,不写 `data-theme`),之后才由用户在设置内显式切换;无持久化值时一律回落暗色,图上用虚线标出这条回落。这张图的设计缝只有一个:跟随系统的 `prefers-color-scheme` 信号是远期增强、当前尚未接入——代码只读 `localStorage`、不读系统信号,所以现在「暗 / 浅 / 柔」三档纯由用户手动选,不会跟着系统深浅色自动变。这条边界别误判成缺陷,它是有意的现行口径。
### 图 7 · studio 视图地图SVG新·架构·现
![图 7 studio 视图地图](assets/07-studio视图地图.svg)
这张图回答「studio 到底有哪些页面、怎么按业务组织、怎么导航」。它把 studio 的全部路由视图按**五个业务域**布局:**玩家消费**Feed 游戏信息流 / ZoneFeed 专区流 / Play 试玩宿主 / Share 分享落地页)、**创作**Create 入口 / Task 生成进度 / Preview 预览 / Project 我的项目 / Detail 详情 / Publish 发布门禁)、**平台与成长**Login / Profile / Message / Dashboard / CreatorHome、**studio 专区**Material 素材中心 / Template 玩法模板中心)、**B 端定制**BizLeads / BizCreate / BizLeadDetail。底部 4 个 tab 标签栏(游戏流 / 创作 / 消息 / 我的)是主导航,其余视图经卡片点击、详情跳转、深链进入。
这张图最该让人看出的,是**视图按业务域聚类后的导航脉络与准入边界**。玩家侧有一条主消费回路Feed → 点卡片 → Play → 点分享 → Share消费域到创作域之间有一条跨域流转玩家「发起同款」从消费走向创作图上用虚线标出。准入边界是这张图的安全主轴路由守卫只认真实 token`isRealLogin`),匿名 `anonId` 衔接未登录态——Feed / ZoneFeed / Play / Share 匿名可达(即刷即玩不挡门、玩家无需登录就能消费,图上用绿框标),而 Create / Project / Publish / Biz / Dashboard 必须登录(未登录访问跳 `/login` 并带 redirect 回跳图上用红框标。这张图有两处刻意钉住的口径看图时别误判其一studio 专区里的「玩法模板中心」是**品类框架入口**,与 demo 那块已被 W-CLEAN 废除的「填参式模板市场」是两回事,图上专门注明、勿混;其二,**视图计数口径**——图列了 20 个有独立路由的视图,而 README §8 写「19 视图」,差的那 1 个是 U9 新增的 CreatorHome 公开聚合主页,本图以 `router/index.ts` 实际路由为准、并把 `StatusBadge.vue`Project 域内的子组件、非独立路由明确排除在外。这个「20 vs 19」的小漂移是真实的、据实标出不臆造对齐。
### 图 8 · 真实试玩宿主Mer新·时序·现
这张图回答「玩家点了一款 AI 生成的游戏,它怎么在浏览器里真正跑起来——而不是像 demo 那样只弹个 toast」。这是 studio 比 demo 多出来的、**护城河命门**级别的能力:真实试玩宿主。它是一条时序——`GamePlayer.vue` 先按 `versionId` 取运行包清单、对 manifest 算 sha256 与后端写包时的 checksum 严格比对(不过就退 demo 兜底),再用 `inject.ts` 把游戏代码 + SDK + 引擎 bundle 拼成 srcdoc 注入一个带 `sandbox` 属性的 iframe挂上 `HostBridge`iframe 内 `boot()` 启动后经 postMessage 把 `game_loaded` / `game_start` 回流给宿主、宿主再 emit 给上层 Feed/Play。
```mermaid
sequenceDiagram
participant FE as Feed / Play (上层)
participant GP as GamePlayer.vue (宿主)
participant IJ as inject.ts (srcdoc 注入)
participant IF as iframe (sandbox · origin=null)
participant BR as HostBridge (桥)
FE->>GP: 点游戏卡片 → 进 /play/:gameId/:versionId
GP->>GP: 取包清单 → 对 manifest 算 sha256 严格比对 checksum
Note over GP: 校验不过 / 取包出错 → 退 demo 兜底(不向上 emit error
GP->>IJ: buildIframeSrcdoc(包 + SDK + engineBundle)
Note over IJ: 函数序列化注入 + 硬编码 CSP 写进 srcdoc meta<br/>connect-src none 禁网络出站
IJ-->>GP: 完整 HTML 文本
GP->>IF: &lt;iframe sandbox srcdoc&gt; 挂载
GP->>BR: attachBridgeorigin 白名单 + schema 双校验)
IF->>IF: boot() 启动引擎 / 兜底
IF->>BR: postMessage(game_loaded / game_start · 经双校验)
BR->>FE: emit('ready') / emit('start')
IF->>BR: postMessage(game_end · 宿主轮询 latch 代发)
BR->>FE: emit('end')
```
这张图最该让人看出的,是**前端域在这里只画「宿主容器 + 桥」这一侧,安全隔离的纵深防御交叉引用沙箱图说**。前端域要关心的是:游戏与宿主之间**只有 postMessage 一条通道**,而桥把 iframe 来的每条消息当不可信边界——先过 origin 白名单(空白名单默认拒绝)、再过 schema 逐字段校验(`channel` 必须等于 `wanxiang-game-sdk``type` 必须在 8 个枚举内),任一不过就丢弃、绝不分发。这套**双校验**是前端这一侧的安全支点。图上还点出一个有意的过渡口径:游戏没有自己的 emit 通道发 `game_end`,所以**宿主轮询 `host.state().phase`、到 `gameover` 就 latch 一个 `game_end` 代发**(图上标「宿主轮询 latch 代发」)——这是 ref 游戏纯引擎工厂、内部没 SDK 的现实下的过渡桩W-G1 生成主线落地后改由各品类标准信号产出。
这张图的设计缝必须看清,且**别误判成已合规**iframe 的 CSP、sandbox 属性、sha256 校验这套机制都已建成、真跑通过,但**整套现在跑在「同源过渡态」**(同源 srcdoc + `allow-same-origin`还有三处真实债——CSP 文档口径与代码对不上(文档写 `script-src 'self'`、代码实际是 `'unsafe-inline' 'unsafe-eval'`)、`sandbox` 属性三处不一致、后端下发的 `sandboxAttr` 前端根本没接线。这些债的 file:line 与收敛方向(游戏包迁独立 usercontent 子域、CSP 改 HTTP 响应头下发、sandboxAttr 前端真接线)逐条记在沙箱图说与 **[`架构/产物执行沙箱.md`](../架构/产物执行沙箱.md) §8**,是这张图的权威细节来源。看这张图时记住:机制建成 ≠ 合规收口,安全隔离的完整故事在沙箱域,本图只画前端宿主侧的装载与桥。
### 图 9 · tier2 富游戏前端承载Mer新·架构·建归属已定·待建
这张图回答「第二条生成轨tier2 富游戏)落地后,前端要多做哪两件事」——也是本域**唯一一张状态非「现」的图**。它整体是**建**待建绘境AI 除了现行的 Tier0/1 超休闲廉价线SAA + LittleJS产物是单包另起了第二条生成轨 tier2AgentScope Python 自治 agent 造多系统富游戏,产物是真 Phaser 多文件源工程。tier2 给前端域带来两件**现在还没做、但归属已定(归前端域)**的事,所以整张图用虚线画、图顶加一条状态约定条说明整图状态。
```mermaid
flowchart TB
subgraph BAR["状态约定:整图 = 建(待建)· 虚线框 = 归属已定、代码未建 · 等 tier2 临近过 0 号 spike 再展开设计"]
end
FEED["game feed 信息流<br/>(现行:承载 LittleJS 单包)"]:::now
subgraph LOAD["① feed 双轨装载分发(待建·归前端域)"]
direction LR
T1["现有轨LittleJS engineBundle 单包<br/>随 manifest 内嵌 · 已建"]:::now
T2["第二轨tier2 Phaser 多文件工程<br/>经独立源项目契约构建出 bundle"]:::todo
end
subgraph ENTRY["② studio 创作端第二轨入口(待建·归前端域)"]
direction LR
E1["超休闲廉价线入口<br/>(现行 Create)"]:::now
E2["富游戏 premium 线入口<br/>(待建)"]:::todo
end
FEED --> LOAD
T1 -.->|两轨共用同一套 iframe+CSP+桥<br/>都暴露 __GameBundle / 都调 bootGameHost| SANDBOX["执行沙箱(公共件·不随轨变)<br/>详见图 8 + 沙箱图说"]:::shared
T2 -.-> SANDBOX
ENTRY -.->|创作端体现两条生成线分轨| LOAD
classDef now fill:#dcfce7,stroke:#16a34a,stroke-width:1.6px;
classDef todo fill:#faf5ff,stroke:#7c3aed,stroke-width:1.5px,stroke-dasharray:5 4;
classDef shared fill:#e2e8f0,stroke:#0f172a,stroke-width:2px;
```
这张图最该让人看出的,是**前端域在 tier2 这件事上「钉归属、不预先设计」的克制**。两件待建的事是:其一,**feed 双轨装载分发**——feed 要同时承载两种产物(现有 LittleJS 单包 + tier2 Phaser 多文件工程),按产物类型分发到不同装载路;其二,**studio 创作端的第二轨入口**——创作端要体现「超休闲廉价线 / 富游戏 premium 线」两条生成线,给富游戏一个独立入口。图上用绿色实心块画现行已建的部分(现有 feed、LittleJS 单包轨、现行 Create 入口用紫色虚线画待建的部分第二轨、premium 入口),一眼区分。
这张图有一条最关键的边界要看清,它决定了前端域的工作量没有想象中大:**两条装载轨共用同一套执行沙箱**——不管哪条轨出来的 bundle都暴露 `window.__GameBundle` 全局名、都调 `bootGameHost`、都跑在同一套 iframe + CSP + 桥里图上用深色实心块把「执行沙箱」画成公共件两轨都虚线指向它。tier2 换的是「游戏内容怎么造出来」,换不掉「造出来之后怎么被关进笼子跑」。所以前端域要补的只是**运行时容器的双轨分发 + 创作入口**,装载与渲染的 how 在架构域、见 **[`架构/生成引擎/引擎与运行时.md`](../架构/生成引擎/引擎与运行时.md)**(其 §7.3 把「tier2 第二装载分支」列为待开项)与 `架构/生成引擎/tier2实现详设.md`。这张图的设计缝就是它的状态本身:**整套是待建**,详细前端设计要等 tier2 临近过 0 号 spike 再展开,现在只钉归属、不预先设计——绝不能因为图画出来了,就误以为第二条生成轨的前端已经建好。
---
## 3. 图清单与状态表
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 两个前端定位 | 架 | 引(链 README §1 | 现 | game-studio创作者+玩家·Vue3+Vant/ game-admin运营+管理员·Vue3+Element Plus+ 设计体系聚焦 studio 的范围边界 |
| 2 | token 两层 + 组件库四层 | 架 | SVG升 | 现 | primitive→semantic→component 两层 + L0/L1/L2/L3 四层,语义层交汇 + 换肤零改组件 + 跨端使命(远期虚线) |
| 3 | 三条数据流 token/theme/i18n | 流 | SVG新 | 现 | token 自底向上 / theme localStorage→data-theme 换肤 / i18n vue-i18n 文案,三流解耦 + 共用一套 localStorage 机制 |
| 4 | demo 取舍 | 讲 | 引(链 README §3 | 现 | 留设计语言token+渐变+暗色玻璃)/ 弃布局范式(桌面侧栏控制台)→ 响应式优先消费级 Web + 勿误砍清单 |
| 5 | 三大契约 token/组件/i18n | 类 | SVG新 | 现 | additive 共守原则 + 向后兼容别名(--cyan→--accent+ AppButton props 不变 + Icon 禁 emoji + 圆角铁律 + common.brand 单一源 |
| 6 | 主题切换 [data-theme]+防 FOUC | 时 | Mer新内联 | 现 | localStorage→首屏内联脚本→data-theme→语义层覆盖→组件自动反应首次默认暗色 + 无值回落暗色prefers-color-scheme 远期未接 |
| 7 | studio 视图地图 | 架 | SVG新 | 现 | 20 路由视图按五业务域布局(玩家消费/创作/平台成长/studio 专区/B 端)+ 4 tab 导航 + 匿名可达/必须登录准入边界 + 20vs19 计数口径 |
| 8 | 真实试玩宿主 | 时 | Mer新内联 | 现 | 取包→sha256 校验→srcdoc 注入→iframe sandbox→桥双校验→postMessage 回流game_end 宿主轮询 latch 代发;同源过渡态 + 三债交叉引沙箱 §8 |
| 9 | tier2 富游戏前端承载 | 架 | Mer新内联 | **建** | feed 双轨装载分发 + studio 第二轨创作入口(归前端域·待建);两轨共用同一套沙箱(公共件);钉归属不预先设计,等 0 号 spike |
> **状态分布**:现 ×8图 18设计体系已全量收口合入 `dev/2.0.0`)、建 ×1图 9tier2 富游戏前端承载归属已定但代码未建·整图虚线)。**防漂移门**:本图说 frontmatter 记三份源档的 commit hash前端/README @ 15b707fd、产物执行沙箱 @ 38357c3d、引擎与运行时 @ 7ecd616e源档变更即比对hash 对不上则本图说与对应 SVG 标「待复核」。
>
> **PNG 后续**9 张图中 4 张为 SVG图 2/3/5/7SVG 入仓后在 mini-desktop 批量转 PNG6c6g 禁 chrome3 张 Mermaid图 6/8/9GitHub 直接渲染、无需转换;图 1/4 单源引用 README、不产新图。

View File

@ -1,216 +0,0 @@
---
date: 2026-06-22
topic: 后端域图说——把「这 13 个业务模块在工程上怎么落地、数据怎么跨域连、谁能做什么」画成一套图 + 讲解(架构图集第一期·后端域)
status: 全域现行(现 ×8· 防漂移门记源档 commit hash
映射源档:
- docs/architecture/后端/README.md @ 38357c3d
- docs/architecture/后端/数据模型.md @ 38357c3d
- docs/architecture/后端/鉴权与权限.md @ 38357c3d
- docs/architecture/架构/13模块.md @ 7ecd616e
---
# 后端域图说
> **这是什么**绘境AI 后端域的「看图入口」。后端域回答的是服务实现视角的几个问题——这 13 个业务模块在工程上**怎么摆**(包结构、两段式、端前缀、错误码分段)、全平台的数据**长什么样、怎么跨域连**、以及「谁能做什么」这条鉴权约束在代码里**如何强制**。这份图说把这几件事,用一套图加配套讲解画清楚。复杂、跨模块的用手绘 SVG 大图,简单、线性的用 Mermaid已有的图一律单源引用、不复制。
>
> **给谁看**:要动后端代码的工程师、做后端或数据侧 code review 的人、排查跨模块依赖与鉴权边界的人。判断「这套后端结构是不是想要的那个」看这份图就够建立全局轮廓;逐个 T-id、逐列字段、逐条依赖仍去文末三个权威源13模块.md / game-cloud `.agent` / 各源档)。
---
## 0. 阅读约定与同步纪律
- **映射的设计档**:本图说不另立设计,只把后端域四份 canonical 设计档画出来——工程落地(分层、两段式、端前缀、错误码、单体形态)出自 [`后端/README.md`](README.md),全平台数据模型出自 [`数据模型.md`](数据模型.md),鉴权与权限出自 [`鉴权与权限.md`](鉴权与权限.md),模块边界与业务链路另引架构域的 [`13模块.md`](../架构/13模块.md)。frontmatter 里记了这四份的当前 commit hash作为**防漂移门**源档一旦变更、hash 对不上,这份图说与对应 SVG 即标「待复核」,由收口脚本比对。
- **同步纪律****设计一变动,本图说与对应 SVG 必须同步更新**,每张 SVG 脚注注明映射源档与状态。已并入 wave 收口清单。
- **本域状态分布**:后端域八张图**全部是「现」(现行已建)**——它们画的都是已落代码、已 e2e 验证过的工程结构与数据形态不存在「设计已出待接线」或「远期目标态」的图。这一点和运维域不同运维域有观测待接、k3s 缓做两类)。但「现行已建的结构」里仍有几处**设计缝与桩**必须照实标出contracts 的 DB 镜像已漂移、compliance 检测原子恒返回 pass、feed 游标分页是桩、网关双重校验是未来态而非现状——这些图上都用文字或虚线如实点出,绝不因为整体是「现」就把桩画成真。
- **产物形式**SVG 入仓GitHub 与编辑器直接渲染矢量PNG 在 mini-desktop 转6c6g 禁 chrome、无转换器。本图说只出 SVG。
## 1. 全图通用图例
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上,后端域主要关心其中三个):
- **数据**`#475569`):跨表软关联而非物理外键、两个 quality_score 口径不互灌、play_count 三处口径只有一处权威、金额一律 BIGINT 以分计——这是图 5 / 图 6 的主轴。
- **安全**`#dc2626`权限只在后端可信边界强制、B 端 RBAC 与 C 端归属隔离两套并存、创作白名单必须在后端、mock 后门生产关死——这是图 7 / 图 8 的主轴。
- **可靠**`#16a34a`):幂等键四范式、资金守恒不变式、统一发布编排的跨表原子事务、契约与实现解耦让模块独立演进。
(另四个维度 **可观测** `#0ea5e9`、**成本** `#16a34a`、**伸缩** `#7c3aed`、**质量** `#15803d` 在后端域不是主轴,本域图基本不点。)
**复用 / 边界三线语义**
- **实线**`#334155`):现成直接用、同步主调、链内逐步推进、主干强关系。
- **虚线**`#64748b``stroke-dasharray="6 4"`):自建 / 解耦 / 软关联 / 异步回灌 / 未来态。
- **双线 / 加粗框**:跨模块共享的公共件,或需要强调的边界(如越界红线、可信边界单点)。
> 后端域图说里,**虚线主要承担「软关联」与「异步回灌」两层语义**:图 5 的跨表连线全是逻辑软关联(代码里一根物理外键都没有),用虚线画;图 6 的飞轮回路是异步回灌,用绿虚线画,与同步主调的实线区分开。红色虚线框另外标「越界红线」——依赖图里本不该存在、画出来是为了强调禁止的边(如图 2 里 studio 不可依赖别人的 -server
---
## 2. 图集
### 图 1 · 后端分层与依赖(实现视角)〔引·现〕
> 单源引用,不复制:后端分层与依赖的 Mermaid 已在 **[后端/README.md §1](README.md#1-边界声明本域--13-个后端业务模块的服务实现视角)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来——同一张图存两处、改一处漏一处,正是这份图集要消灭的漂移面。
这张图回答「后端是什么形状」。它把后端的实现视角浓缩成三层:最下面是 **Huijing fork 提供的基座**system 用户/权限/OAuth2、infra 文件/任务/日志、bpm 工作流,以及 pay——pay 是 Huijing 原生模块MVP 阶段还没接入这套单体),中间是 **13 个 game 业务模块**(本域主体),每个模块再拆成 **-api / -server 两段式**工程结构。
读这张图要抓住两个后端实现上的特殊归属README 在图注里专门点了出来:其一,**pay 单独画在基座里**,因为它是 Huijing 原生模块、当前未接入单体;其二,**ip 不独立建模块,而是作为一条 seam接缝/横切能力)寄宿在 compliance 里**。这两点不是疏漏,是有意的工程取舍,后面图 5 的数据视角会再次印证——库里确实没有独立的 `game_pay_*` / `game_ip_*` 迁移落地。
这张图的边界声明很清晰后端域只回答「模块在工程上怎么实现HOW**不回答「每个模块各管什么领域、彼此怎么依赖WHAT」——那是架构域的职责**,在 [13模块.md](../架构/13模块.md) 里。两者各守一摊、互不重复,这样无论改架构还是改代码,都只有一处需要更新。所以这张图刻意薄;要看 13 模块各自的职责边界与依赖方向,去架构域,本图说不重画一份会过期的副本。
### 图 2 · 两段式模块:-api 契约面 / -server 实现面SVG新·类·现
![图 2 两段式模块 -api/-server](assets/02-两段式模块.svg)
这张图把图 1 里「每个模块的两段式工程结构」放大讲清。它回答的是后端低耦合到底靠什么落地——答案是一道很硬的边界:**每个 game 模块都拆成 `-api``-server` 两个 Maven 子模块,跨模块只准依赖对方的 `-api`,绝不许直接碰 `-server`**。
图左半边是单个模块的剖面(以 project 为范例,所有模块同构)。`-api` 是契约面,只声明、不实现:里面放枚举(状态机取值、业务常量)、错误码常量(本模块独占段,见图 4、跨模块 DTO模块间传输对象、以及 Feign 接口或 `@Primary` 本地 bean远程调用声明——单体内同进程直调拆微服务才换真 Feign`-server` 是实现面放真正干活的代码controllerapp/admin 双端、service业务逻辑、`@Transactional` 只加这层、归属校验在此强制、dalDO + Mapper、convertDO↔VO↔DTO 转换)。
图右半边讲清这道边界为什么值钱。当 studio 这样的上游要调 project / aigc / runtime 时,**它的 pom 只声明依赖各模块的 -api编译期就根本拿不到对方的实现类**——越界在构建期就被挡死,而不是靠人自觉。好处是任一模块都能独立演进、独立测试,后续从单体拆成独立仓时不被实现耦合绊住:契约稳定、实现可换。图里特意用红色虚线框标出「这些模块各自的 -server 对 studio 不可见」,强调依赖图里**根本不存在**指向 -server 的边——这条红线画出来是为了让人一眼记住禁止什么。
要补充三个工程上的硬约束图右侧也钉住了DTO/VO/DO 三层语义不可混用DTO 在 -api 跨模块共享、VO 在 -server controller 面向前端、DO 在 -server dal 映射表错位会出问题契约不放后端API/DB/SDK/event 等 8 类跨端契约的单一事实源是仓根的 `contracts/`后端只引用、不另立DB schema 的 Flyway 执行副本要和 contracts 源 diff 一致);双包同名 controller 必须显式 bean 名(`controller.admin``controller.app` 下同简单类名的控制器,裸 `@RestController` 会 bean 名相撞、整个 context 启动失败这是踩过两次的坑。物理形态上13 模块是逻辑划分,**全部以 jar 聚合进 huijing-server 单体进程运行**Nacos/RocketMQ 是框架自带的远期形态、MVP 未部署。
### 图 3 · 包名 → 端前缀自动生效Mer新·流·现
这张图讲一个很容易被当成「魔法」的机制app 控制器和 admin 控制器的代码里**都不写 `/app-api``/admin-api` 前缀**,但请求进来却能各自落到对的端上。它的原理不是魔法,而是 Huijing 框架按**包路径通配**:控制器放在 `controller.app.*` 包下,框架自动给它套 `/app-api` 前缀;放在 `controller.admin.*` 包下,套 `/admin-api`。这条规则的前提,正是图 2 里那条统一包名约定——所有业务代码都在 `com.wanxiang.huijing.game.module.{模块}.{层}` 之下,框架才能据此通配。
```mermaid
flowchart LR
DEV["控制器源码<br/>@RequestMapping('/project')<br/>(不写端前缀)"]:::src
subgraph SCAN["Huijing 框架按包路径通配"]
direction TB
APP{"包在<br/>controller.app.*<br/>之下?"}
ADM{"包在<br/>controller.admin.*<br/>之下?"}
end
DEV --> APP
DEV --> ADM
APP -->|是| PAPP["自动套 /app-api<br/>→ /app-api/project"]:::app
ADM -->|是| PADM["自动套 /admin-api<br/>→ /admin-api/project"]:::adm
PAPP --> UT1["URL 前缀反推 userType<br/>/app-api → MEMBER (C 端)"]:::note
PADM --> UT2["URL 前缀反推 userType<br/>/admin-api → ADMIN (B 端)"]:::note
classDef src fill:#eff6ff,stroke:#2563eb,stroke-width:2px;
classDef app fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.5px;
classDef adm fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px;
classDef note fill:#f1f5f9,stroke:#475569,stroke-width:1.2px;
```
这张图最该让人看出的,是它和鉴权的衔接——**端前缀不只是路由,还反推用户类型**。框架据 URL 前缀实时推导 userType`/app-api` 推出 MEMBERC 端创作者+玩家),`/admin-api` 推出 ADMINB 端运营+管理员。userType 不在登录时记死、而是按前缀实时算,这正是图 7 鉴权双模型的入口:一个 C 端 token 去打 `/admin-api`会因为「token 携带的 userType 与 URL 推导出的不一致」在 TokenAuthenticationFilter 那一步就被拒。所以这张看似只讲路由的图,其实是鉴权链路的第一段。它没有现行/远期的灰度,就是当前真相。
### 图 4 · 错误码分段各模块独占一段Mer新·讲·现
这张图回答「全平台的错误码怎么不打架」。规则很简单:错误码格式是 `1-{模块段}-{业务}-{细分}`**每个模块独占一段、互不重叠**,新增模块在自己 `-api` 的错误码常量类里登记自己那一段。这样任意两个模块各自演进、各自加错误码,都不会撞号。
```mermaid
flowchart TB
FMT["错误码格式1-{模块段}-{业务}-{细分}<br/>各模块独占一段,禁止冲突"]:::fmt
subgraph BASE["Huijing 基座段(源档明确给出)"]
direction LR
B1["1-001 system"]
B2["1-002 infra"]
end
subgraph GAME["13 game 业务模块段"]
direction LR
G1["1-100 project"]
G2["1-101 aigc"]
G3["1-102 runtime"]
G4["1-103 feed"]
G5["1-104 telemetry"]
end
subgraph INFER["顺延分配(源档未逐一给出·按『每模块一段顺延』推断)"]
direction LR
I1["1-105 pay"]
I2["1-106 trade"]
I3["1-107 community"]
I4["1-108 ip"]
I5["1-109 compliance"]
I6["1-110 biz"]
I7["1-111 ad"]
end
FMT --> BASE
FMT --> GAME
FMT --> INFER
classDef fmt fill:#fefce8,stroke:#ca8a04,stroke-width:2px;
```
读这张图要注意一处诚实标注:**源档只明确给出了 system / infra / project / aigc / runtime / feed 六段**图上前两组其余模块pay/trade/community/ip/compliance/biz/ad的段号是**按「每模块一段顺延」规则推断分配的**(图上第三组单独框出、标「顺延·推断」),不是源档逐一写死的。这处推断照实标,是为了不把推论当成已核实的事实——真要给某模块定错误码段,以该模块 `-api` 的错误码常量类登记的为准。举两个图 7 会再次出现的真实锚点project 的归属守卫抛 `PROJECT_NOT_OWNER(1_100_000_001)`,落在 project 的 100 段;创作白名单拒绝抛 `PLAYER_CREATE_NOT_IN_WHITELIST(1_002_090_003)`,落在 passport 寄宿的 system/infra 段——这也印证了 passport 身份层物理上寄宿在基座、不在 13 模块清单里这件事。
### 图 5 · 全平台数据模型跨域 ERcanonicalSVG新·ER·现
![图 5 全平台数据模型跨域 ER canonical](assets/05-数据模型跨域ER.svg)
这张图回答「全平台的数据长什么样、怎么跨域连」——也是**全仓唯一的 ER 权威**,其它图说(如总图说、运维图说)要画数据都引用它、不另起一份。它据 Flyway V1V25 真实落库的约 40 张表画出来,按五条业务链分块:① 创作链路studio+aigc+project+source、② 编译发布与合规闸门runtime+compliance、③ 分发与数据回路feed+telemetry、④ 钱财闭环ad+trade、⑤ 身份关联community+biz最上面一条是所有创作的归属起点 passport 身份层。
这张图最该先记住的是图顶那条**全图铁律**:所有连线都是逻辑「软关联」,**代码里一根物理外键都没有**。这是单体内有意的解耦——模块之间只经各自的 `-api` 包用 DTO 软关联,归属隔离靠 Service 的可信边界Mapper 强制带 `eq(userId)` 谓词),而不是靠 DB 约束。代价是数据一致性要 Service 自己保,收益是模块能各自演进、后续拆独立仓时不被外键绊住。所有 `game_*` 表里的 `creator_user_id` / `user_id`,数值上都等于 `game_player.id`OAuth2 的 userId但代码层一根外键都没有。图上因此用实线画主干强关系、虚线画软关联与回灌二者一眼区分。
图右下角用三个框钉住了三处**最容易误读的真相**,读图时务必一并记住。第一处是**必须知道的数据语义坑**(踩错会出真 bug两个 quality_score 不能互灌aigc 的是 01 衡量生成质量、telemetry/feed 的是 0100 衡量运营质量play_count 有三处口径但只有一处权威试玩会话不计、telemetry 聚合才是权威源、project 的是回灌的物化字段);金额一律 BIGINT 以「分」计、禁浮点;业务归属列 `creator_user_id` 与审计列 `creator` 是两回事。第二处是**contracts 镜像已漂移**——执行权威是 huijing-server 里的 25 个迁移 V1V25但 contracts/db-schemas/ 只含 18 个(单模块 additive 的 V14V20 不进 contracts**只读 contracts 会漏掉** aigc 的 level/trace/source/modify 列、source_project 的并发幂等唯一键、feed 的 exposure_limit。这是个真实的漂移面图上诚实画出、不掩盖。第三处是**两套身份数值与代码路径都分开**C 端玩家创作者用 `game_player`(物理寄宿 huijing-module-system、不在 13 模块清单B 端管理员用 `system_users`;而 pay/ip 当前没有独立迁移落地,赋余额走 trade 的 grant、素材登记走 studio 的 `game_material`——这和图 1 的「pay 未接单体、ip 寄宿 compliance」从数据侧对上了。
还有一个贯穿全图、最该让评审看出的设计意图是**源与产物两个存储面解耦**`game_source_project` 存源source_json`game_version` 存产物package_url 指向的包「改源不改包」指的是改了源要重新构建才生成新产物、不是直接动包源构建失败时会留下孤儿源status=2而不污染产物面。这正是生成主线「游戏是长生命周期项目、改源重建」范式在数据层的落点。迁移只增不改——新增表或列要回 [数据模型.md](数据模型.md) 补节点,逐列细节以迁移头注为准。
### 图 6 · 五条业务链路跨模块调用SVG新·时·现
![图 6 五条业务链路跨模块调用](assets/06-五条业务链路.svg)
如果说图 5 是数据的静态结构,这张图就是它的动态——把「一句话到能赚钱」拆成**五条链**,看每条链怎么跨模块串起调用。五条链分别是:链 1 创作(一句话→可试玩草稿)、链 2 发布(草稿→已发布入流)、链 3 试玩(刷流→取包→沙箱跑→互动)、链 4 广告收益(曝光/激励→计费→分账→入钱包)、链 5 数据回路遥测→聚合→质量分→feed 重排)。每条链左侧标该步的主调模块,实线是同步主调、绿虚线是异步回灌。
读这张图要抓住几条最该看出的设计意图。**链 2 发布是全仓唯一一处真正的跨表原子发布**project 的统一发布编排把 compliance 裁决、runtime 出包、feed 入流串成一个事务,任一步失败就整体回滚、不留半截状态——这是脊柱级的可靠性能力,图上用事务边界框单独强调。**链 5 数据回路里 telemetry ↔ feed 是 13 模块里唯一一处双向依赖**feed 消费 telemetry 算出的质量分来排序telemetry 回收 feed 上的互动信号来计算,这条唯一的双向边正是平台「越用越聪明」飞轮的机制所在,图上用一条绕回的绿虚线画出来。**链 4 广告收益的两段靠 source_ref 对账锚点串起**ad 的 `revenue.id` 就是 trade 的 `income.source_ref`trace_id 从 ad 一路透传到 trade 串起对账链,金额全程 BIGINT 以分计——这条边界不容含糊,是钱的事。
这张图也照实标出了几处**设计缝与桩**(用 📌 标在对应步骤上),绝不把桩画成真:链 3 的游标分页目前是桩(永远返回第一页)、`packageUrl` 字段恒为 null真实取包要走 `GET /runtime/package/{vid}`);链 4 的真广告联盟 SDK 是桩、被 mock 挡在审核闸门前compliance 的检测原子目前也是桩。这些缺口的共同特点是**逻辑已建、卡在不可压缩的日历闸门**ICP 备案、支付进件、广告审核)或 W-G1 质量门,而不是代码没写——策略是先把逻辑建好、闸门到位即接。最后一个衔接点:这五条链正是运维冒烟门验的五条端到端闭环(见运维图说图 4冒烟门按链分组点检每条链的关键 API 是否都在岗。
### 图 7 · 鉴权 OAuth2 / RBAC 双模型SVG新·类·现
![图 7 鉴权 OAuth2/RBAC 双模型](assets/07-鉴权双模型.svg)
这张图回答「谁能做什么」。它要先记住图顶那条**铁律**:权限只在后端可信边界强制,前端拦截一律不算数;当前 MVP 是单体,可信边界就是服务侧那一个点(不是网关)。权限基座是 Huijing fork 自带的 Spring Security + OAuth2 + RBAC全仓没有引入 sa-token。
这张图的核心是**两类用户、两套权限模型并存**这是它最该让人看清的一件事。系统只有两类用户MEMBERC 端,创作者+玩家同型)和 ADMINB 端,运营+管理员userType 按 URL 前缀实时推导(接图 3。一个请求穿过服务侧 TokenAuthenticationFilter取 token 换登录态、校验 userType 与端前缀一致)和 URL 准入后,按端类型分流到两套截然不同的强制机理:
- **B 端走声明式 RBAC**(图左):后台所有 admin 控制器统一用 `@PreAuthorize("@ss.hasPermission('模块:资源:动作')")` 声明所需权限位,真正的裁决在 `PermissionServiceImpl` 按「角色→角色拥有的菜单」求交集,超管短路、严格模式(权限点找不到 Menu 即判无权限),落在 RoleDO/MenuDO/RoleMenuDO/UserRoleDO 四张表上。强制点是方法级的注解。
- **C 端走 Service 层归属隔离**图右黄金范式app 控制器**完全不用 `@PreAuthorize`**——这是此前文档最大的认知缺口。它的范式是控制器取 `getLoginUserId()` 透传给 ServiceService/Mapper 用 `eq(creatorUserId/userId)` 把当前用户钉进 WHERE 谓词,从数据层强制只能碰本人数据。落地靠一个黄金归属守卫 `validateProjectOwner`(不是本人就抛 `PROJECT_NOT_OWNER`「无权操作他人的游戏项目」),后续 C 端写域直接克隆它。强制点是数据层的谓词,不是角色权限。
图底还叠了一层**创作白名单**A2 内测准入C 端虽创作者与玩家同型,但「能不能创作」由 `validateCreator` 卡住,`creator_flag≠1` 就拒。这道白名单最该记住的是——**前端守卫挡不住直连 API所以它必须在后端强制**。图右下角的「现状 vs 未来态」是这张图的纠偏点:控制器注释里多处写的「网关+服务端双重校验」是**微服务拆分后才成立的未来态**,当前单体下网关根本不在请求路径上、权限强制 100% 在服务侧单点图上用实心绿块画现状、虚线框画未来态把这处与现状不符的旧说法如实标清。mock 后门是 staging 现状、生产必须关死的红线,它和 `validateCreator` 查无行放行是配套的内测豁免。这张图配合图 8 一起看:图 7 讲两套强制机理,图 8 讲哪些端点落哪一档。
### 图 8 · 匿名 / 登录态的准入矩阵Mer新·讲·现
这张图把图 7 的两套机理落到「具体端点该走哪一档」的速查上。平台的端点按准入要求分四档匿名公开读、登录态、B 端 RBAC 权限位、C 端归属隔离。匿名读端点用 `@PermitAll` 由框架扫描注解自动转成免登 URL 列表,其余端点落到 `anyRequest().authenticated()` 的兜底(未登录即 401
```mermaid
flowchart TB
REQ["请求到达服务侧"] --> Q1{"端点带<br/>@PermitAll?"}
Q1 -->|是| ANON["① 匿名公开读<br/>任何人无需 token<br/>(app 端共 34 处匿名读)"]:::anon
Q1 -->|否| Q2{"已登录?<br/>(userType 须匹配端前缀)"}
Q2 -->|否| E401["401 未登录"]:::deny
Q2 -->|是| Q3{"端类型?"}
Q3 -->|"/admin-api · B 端"| RBAC["③ RBAC 权限位<br/>@PreAuthorize + PermissionServiceImpl<br/>持对应角色-菜单权限的 ADMIN"]:::rbac
Q3 -->|"/app-api · C 端"| OWN["④ 归属隔离<br/>Service eq(userId) + validateProjectOwner<br/>MEMBER 且是数据归属人"]:::own
RBAC -->|无权| E403["403 无权限"]:::deny
OWN -->|非本人| E403
ANON -.->|"匿名读三纪律"| RULE["只暴露公开字段·裁剪 PII<br/>公开读靠手动 eq 谓词隔离(不假定 DataPermission 自动生效)<br/>跨租户读显式收敛"]:::rule
classDef anon fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px;
classDef rbac fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px;
classDef own fill:#ede9fe,stroke:#7c3aed,stroke-width:1.5px;
classDef deny fill:#fee2e2,stroke:#dc2626,stroke-width:1.5px;
classDef rule fill:#fff7ed,stroke:#d97706,stroke-width:1.3px,stroke-dasharray:5 4;
```
这张图最该让人看出的,是匿名读这一档**不是「无所谓」、而是有三条必须守的纪律**图上用橙色虚线框单独标出出自安全规则、P-OPN-08 已实证):只暴露公开字段、把 PII 裁剪掉;公开读靠手动 `eq` 谓词隔离,**不能假定框架的 DataPermission 会自动生效**(它只注册在 AdminUserDO 等业务表上);跨租户读要显式收敛。这三条是匿名读端点最容易踩的坑——以为放了 `@PermitAll` 就完事,结果把私有数据或 PII 漏出去。一个要记住的细节是**登录端点本身免登**C 端的 send-sms-code / sms-login / invite-register 三个带 `@PermitAll`(不然没法登录),但 `me` 走登录态sms-login 是「已注册即登录、未注册自动注册」一体,成功后发真 OAuth2 token。这张图没有现行/远期边界,就是当前每个端点准入的真相速查表。
---
## 3. 图清单与状态表
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 后端分层与依赖(实现视角) | 架 | 引(链 README §1 | 现 | 基座 + 13 模块 + 两段式三层pay 未接单体 / ip 寄宿 compliance 两处特殊归属WHAT 归架构域、本域只讲 HOW |
| 2 | 两段式模块 -api/-server | 类 | SVG新 | 现 | 单模块剖面(-api 枚举/错误码/DTO/Feign · -server controller/service/dal/convert+ 跨模块只依赖 -api 的越界红线 + DTO/VO/DO 三层 + 单体形态 |
| 3 | 包名 → 端前缀自动生效 | 流 | Mer新 | 现 | controller.app/admin 包路径如何自动套 /app-api、/admin-api + 前缀反推 userType 接鉴权 |
| 4 | 错误码分段 | 讲 | Mer新 | 现 | `1-{模块段}-***` 各模块独占段;六段源档给出 + 七段顺延推断(诚实标推断)|
| 5 | 全平台数据模型跨域 ERcanonical | ER | SVG新 | 现 | 五链路约 40 表跨域 ER + 全图无物理外键铁律 + 三处真相框(数据语义坑 / contracts 镜像漂移 / 两套身份)+ 源↔产物解耦 |
| 6 | 五条业务链路 | 时 | SVG新 | 现 | 创作/发布/试玩/广告收益/数据回路 跨模块调用;唯一真原子发布 + 唯一双向边 + source_ref 对账锚点;游标/联盟SDK/检测原子桩照实标 |
| 7 | 鉴权 OAuth2/RBAC 双模型 | 类 | SVG新 | 现 | 两类用户两套权限并存B 端 @PreAuthorize RBAC + C 端 Service 归属隔离 + 创作白名单 + 网关双重校验=未来态纠偏 + mock 后门红线 |
| 8 | 匿名/登录准入矩阵 | 讲 | Mer新 | 现 | 四档准入(匿名/登录/RBAC/归属)速查 + 匿名读三纪律 + 登录端点本身免登 |
> **状态分布**:现 ×8后端域全部现行已建无接/缓/建/future。但「现行已建的结构」里照实标出了若干**设计缝与桩**——contracts DB 镜像漂移(图 5、compliance 检测原子恒 pass / feed 游标分页桩 / 真联盟 SDK 桩(图 6、网关双重校验是未来态而非现状图 7——绝不因整体为「现」就把桩画成真。**防漂移门**:本图说 frontmatter 记四份源档的 commit hashREADME/数据模型/鉴权与权限 @ 38357c3d、13模块 @ 7ecd616e源档变更即比对hash 对不上则本图说与对应 SVG 标「待复核」。
>
> **PNG 后续**8 张图中 4 张为 SVG图 2/5/6/7SVG 入仓后在 mini-desktop 批量转 PNG6c6g 禁 chrome3 张 Mermaid图 3/4/8GitHub 直接渲染、无需转换;图 1 单源引用 README、不产新图。

View File

@ -1,198 +0,0 @@
---
date: 2026-06-22
topic: 产物执行沙箱图说——把「一款 AI 生成的不可信游戏,怎么在玩家浏览器里被隔离着安全跑起来」画成一套图 + 讲解(架构图集·架构域)
status: 现行已建(机制全建成·真跑通过)· 同源过渡态债见 §8 诚实标注 · 防漂移门记源档 commit hash
映射源档:
- docs/architecture/架构/产物执行沙箱.md @ 38357c3d
---
# 产物执行沙箱图说
> **这是什么**绘境AI「产物执行沙箱」的「看图入口」。生成主线已经从「禁代码、填参数」迁到「让 agent 写码」,于是注入面就是模型现写的 JavaScript 本体——平台必须把每一款生成游戏当成有恶意、有 bug 的不可信输入。这份图说把「这段不可信代码怎么在玩家浏览器里被隔离着安全跑」画清楚取包、sha256 完整性校验、srcdoc 注入、iframe + CSP 隔离、postMessage 双向桥双校验、SDK 受控能力面、加载/失败/销毁的生命周期,一条端到端链路。复杂、跨层的用手绘 SVG 大图,简单、线性的用 Mermaid。
>
> **给谁看**:要改宿主 / 桥 / CSP / 校验逻辑的前端工程师,做安全审计的人,以及想搞清「生成出来的游戏能调什么、不能碰什么」的产品与架构。判断「这套隔离方案是不是想要的那个」看这份图就够建立全局轮廓,逐行的 file:line 仍去源档 [`产物执行沙箱.md`](产物执行沙箱.md) 与对应前端源码。
---
## 0. 阅读约定与同步纪律
- **映射的设计档**:本图说不另立设计,只把架构域里 [`产物执行沙箱.md`](产物执行沙箱.md) 这一份 canonical 设计档画出来。frontmatter 记了它的当前 commit hash`38357c3d`),作为**防漂移门**源档一旦变更、hash 对不上,这份图说与对应 SVG 即标「待复核」,由收口脚本比对。
- **同步纪律****设计一变动,本图说与对应 SVG 必须同步更新**,每张 SVG 脚注注明映射源档与状态。已并入 wave 收口清单。
- **本域状态分布**这套机制iframe + 桥 + 双校验 + sha256**已全部建成、真跑通过**,所以七张图的整图状态都是**现**。但「机制建成不等于合规收口」——源档 §8 逐条带 file:line 记了四处真实债CSP 文档口径与代码对不上、sandbox 属性三处不一致、后端下发的 sandboxAttr 前端没接线、HJ-AUDIT-001 同源红线当前是过渡态)。这些**现状债**不是「待建」,而是「现行机制里的已知缺口」,图上一律用**橙色虚线框 + 文字小标**与「现行已建的实心块」一眼区分开(图 1 右下、图 2 注记里能看到),绝不能因为机制都建了就误判它已经安全收口。
- **产物形式**SVG 入仓GitHub 与编辑器直接渲染矢量PNG 在 mini-desktop 转6c6g 禁 chrome、无转换器。本图说只出 SVGMermaid 图 GitHub 直接渲染、无需转换。
## 1. 全图通用图例
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上,沙箱域主要关心其中两个):
- **安全**`#dc2626`这是本域的主轴。三层封堵build 段静态门 / iframe CSP / sandbox 属性)、桥的 origin + schema 双校验、storage 四道闸、sha256 取包完整性、bundle 内联前的 `</script>` 消毒——全是为了把不可信代码关在笼子里。
- **质量**`#15803d`):受控面那条「异常绝不向游戏抛、超时就降级、写类 fire-and-forget」的降级铁律根源是玩家验收门五条 AND 里的「无错」——游戏运行期一旦抛未捕获错误就判不过,所以受控面任何意外都得自己吞掉。隔离做得再硬,也不能把能正常试玩的游戏因为一次可恢复失败而误报「加载失败」。
(其余维度 **可观测** / **可靠** / **成本** / **数据** / **伸缩** 在本域不是主轴,故图上基本不点。)
**复用 / 边界三线语义**
- **实线**`#334155`):现成直接用、同步动作、调用或发消息。
- **虚线**:承担两层语义——一是**状态语义**,凡是「现状债 / 过渡态」的元素一律用橙色虚线框 + 文字小标画出(与现行已建的实心块区分);二是**边界语义**,图 5 里两条信任边界都用虚线框表达「壳」(红虚线=沙箱壳、紫虚线=受控面壳)。
- **双线 / 加粗框**:跨域共享的公共件或需要强调的边界。**绿色实线箭头**在本域特指「唯一放行通道」postMessage**红色虚线**特指「被封死的逃逸面」。
> 本域图说最该守的纪律点是:**别把「机制已建」当成「已经安全」**。iframe、桥、双校验、sha256 这套都真跑通过了,但它现在跑在**同源过渡态**(同源 srcdoc + `allow-same-origin`HJ-AUDIT-001 那条「独立源就绪前禁用 `allow-same-origin`」的红线在代码里并未强制。读图时凡见橙色虚线框,就是「这里还有债、别当已合规」。
---
## 2. 图集
### 图 1 · 不可信代码隔离全景SVG新·架·现
![图 1 不可信代码隔离全景](assets/sbx-01-不可信代码隔离全景.svg)
这张全景图回答整份文档的总问题:**一段模型现写的不可信 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`(条件必须是无副作用的纯布尔表达式)的实际拦截清单都列了出来,让人看清这层拦的不是抽象的「危险代码」,而是一份具体的黑名单。
中间是 iframe 这层壳,它叠了两道:**CSP** 硬编码进 srcdoc 的 `<meta>`,其中 `connect-src 'none'` 是最关键的一条——它禁掉一切网络出站,所以即便游戏代码想把玩家数据 `fetch` 出去也发不出去;引擎 bundle 不在 iframe 内 fetch而是由宿主层 fetch 后内联进来,所以这条不会卡死引擎装载。**sandbox 属性**则封死宿主 DOM 逃逸、顶层导航与弹窗,并把游戏与宿主之间的通道收窄到只剩 postMessage 一条。这条收窄直接决定了产品形态:广告、支付、存储这些要碰平台资源的事,游戏在 iframe 内根本办不了(没网络、碰不到宿主 DOM只能经 postMessage 抛给宿主侧去办、办完再回包——这就是为什么 SDK 的 ad/pay/storage 都是「游戏发请求 → 宿主执行 → 回包」的形状,而不是游戏直接调。
这张图必须让人看出的「设计缝」画在右下角那个橙色虚线框里:**机制建成 ≠ 合规收口**。当前整套跑在同源过渡态(同源 srcdoc 配 `allow-same-origin`HJ-AUDIT-001 的同源红线在代码里没强制CSP 的文档口径写的是 `script-src 'self'`、代码实为 `'unsafe-inline' 'unsafe-eval'`sandbox 属性在 DB 默认值、前端硬编码、文档示例三处不一致;后端下发的 `sandboxAttr` 前端压根没消费。这四条债的收敛要一起做(迁独立 usercontent 子域、CSP 改 HTTP 响应头下发、sandboxAttr 真接线)才闭合,详见图 2 注记与源档 §8。把这块诚实画出来正是为了不让人看到「三层都建了」就以为已经安全了。
### 图 2 · 取包 → sha256 校验 → iframe + CSP → 注入 时序SVG新·时·现
![图 2 取包校验注入时序](assets/sbx-02-取包校验注入时序.svg)
这张时序图把一款不可信游戏「从后端取包到在玩家面前可玩」的全过程展开成六条泳道之间的一串动作。它的叙事主线是:**每一环都假设上一环的产物可能有问题**,所以取包之后必有完整性校验、注入之时必带 CSP、建桥之后所有消息必过双校验。
取包这一步并不是一条直线,而是 `resolvePackage` 分四态走,图上方用橙色虚线框列了出来:创作者预览时 `props.manifest` 直接传一个内存里的包进来、不走网络;玩家试玩时按 `versionId` 取运行包清单、清单里带 `manifestUrl` 就去拉真包做 sha256 校验;清单没有 `manifestUrl`mock 阶段后端还没回填)就退 demo 兜底;取包或校验中途出任何错,也退 demo 兜底。这里有一个关键且有意的设计:可恢复的失败**只 `console.warn`、不向上 emit error**。原因是父级 `Play` 把 error 当致命态处理、会用 `v-else-if` 把宿主整个隐藏掉显示「加载失败」,而 demo 兜底本可以正常试玩,两者冲突,所以宁可降级也不上抛。
中段是这张图的安全支点——**sha256 双通道校验**图中绿色块。manifest 从后端拉下来后要确认传输途中没被篡改、和后端写包时算的 checksum 一致。校验走双通道安全上下文https / localhost优先用原生 `SubtleCrypto`,性能最好;非安全上下文回退一份纯 JS 的 SHA-256 完整实现。为什么需要这份纯 JS 回退?因为创始人用局域网 IP 明文 http例如 `http://100.64.0.7:4173`)跨内网机访问时,浏览器判定为「非安全上下文」、`crypto.subtle` 直接是 `undefined`,旧实现这时会抛错、导致校验失败退 demo 兜底,最终页面误报「游戏加载失败 / 网络波动」——真因是上下文不安全,根本不是网络。回退纯 JS 后,完整性校验在明文 IP http 和安全上下文下行为一致。后端这一端也对齐了字节一致性:取 manifest 的端点返回的是原始 JSON 文本(返回类型 `String``GlobalResponseBodyHandler` 只拦 `CommonResult` 不拦它),保证前后端对同一份字节算摘要。
后段是注入与回流。`buildIframeSrcdoc` 用一个不常见的手法叫「函数序列化注入」:`createWanxiangSDK``startRuntime` 都是不依赖模块外部符号的纯工厂函数,用 `Function.prototype.toString()` 取源码文本拼进 iframe 内联 `<script>` 重新求值——这样同一份 TS 源既被宿主工程类型检查、又在 iframe 内真跑,不用为它们单独配打包产物。引擎 bundle 则作一个独立内联 `<script>` 注入、暴露契约冻结的全局名 `window.__GameBundle`,并经 `escapeBundleForInlineScript` 断掉 `</script>` 变体防止它越出脚本块。最后一条回流值得记住:**游戏没有自己的 emit 通道发 game_end**,所以宿主 `watchGameEnd` 每 500ms 轮询 `host.state().phase`、到 `gameover` 就 latch 一个 `game_end` 代发——这是过渡口径ref 游戏是纯引擎工厂、内部没 SDK自发不出终态等 W-G1 生成主线落地后改由各品类标准信号产出、这个轮询桩可下线。图右侧旁注还点出加载超时按装载路分流(引擎包 12s、旧 demo 路 5s因为引擎冷启动是旧路的 4.8~5.3 倍、内联 bundle 解析会逼近甚至超过 5s放宽到 12s 是为了防误杀,而首屏 P75<3s `perf_first_screen` 单独监测与这个防挂死上界正交
### 图 3 · postMessage 双向桥与双校验Mer新·时·现
下面这张流程图把桥(`bridge.ts``HostBridge` 类)处理一条 iframe 来消息的判定过程画清楚。桥的设计立场是:**把 iframe 来的每一条消息都当不可信边界处理**——先过 origin 闸、再过 schema 闸,任一不过就丢弃、绝不分发;过了两道闸还要分辨它是不是宿主先前请求的回包,是回包就消费掉、不是才往上分发。
```mermaid
flowchart LR
M["iframe postMessage 来一条消息"] --> O{"① origin 在白名单?<br/>isOriginAllowed"}
O -->|"否(空白名单默认拒绝)"| R1["onReject('origin_not_allowed')<br/>丢弃"]:::deny
O -->|是| S{"② schema 逐字段校验?<br/>validateEnvelope"}
S -->|否| R2["onReject(reason)<br/>丢弃"]:::deny
S -->|是| P{"是宿主请求的回包?<br/>requestId 配对命中 pending"}
P -->|是| RP["消费 pending 回调<br/>clearTimeout + resolve"]:::ok
P -->|否| D["onMessage 分发给上层 GamePlayer"]:::ok
classDef deny fill:#fee2e2,stroke:#dc2626,stroke-width:2px;
classDef ok fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px;
```
第一道是 **origin 白名单**`isOriginAllowed` 对空白名单**默认拒绝**——白名单为空视为不允许任何来源,这是安全默认而非疏忽。因为 srcdoc 文档的 origin 是 `null`,建桥时 `buildOriginAllowlist``includeNull` 时会把字符串 `'null'` 连同宿主自身 origin 一起加进白名单(这也正是 §8 同源债的一个落点:过渡态下白名单含 `'null'`)。第二道是 **schema 逐字段校验** `validateEnvelope``channel` 必须严格等于固定标识 `wanxiang-game-sdk`(否则是噪声或伪造),`type` 必须在 8 个枚举的 `VALID_TYPES` 内(即图 4 那张 type 表的全集),`direction` 必须合法,`traceId` 必须是字符串(贯穿链路必备),`payload` 必须存在,`requestId` 若带则必须是字符串。这里有个有意的细节:`validateEnvelope` **不抛异常、只返回判定结果**——源码注释写得明白,「异常本身也是一种攻击面」,所以校验器自己绝不制造可抛路径。
过了两道闸之后的回包识别,是为了支撑「请求-响应」语义:宿主往游戏发消息用 `post``targetOrigin``'*'`,因为 srcdoc 的 origin 是 `null` 没法精确指定),而 `request` 是 Promise 化的请求-响应、带 5s 超时(`REQUEST_TIMEOUT_MS`**超时就以 `undefined` 兜底 resolve、绝不 reject**——向上抛 reject 会打断游戏,所以宁可降级。卸载时 `dispose` 移监听、清所有挂起请求的定时器防泄漏。这张图没有现行/远期边界,它就是现行桥的真实判定流;要注意的「设计缝」只有一处,且不在桥本身而在它的输入侧——白名单含 `'null'` 是同源过渡态的产物,独立源落地后这一项会随 §8 收敛一起收紧。
### 图 4 · 受控面SDK bridge能力面SVG新·类·现
![图 4 受控面能力面](assets/sbx-04-受控面能力面.svg)
这张类图回答「平台到底向不可信游戏注入了什么能力、又是怎么注入的」。结论是iframe 内的游戏只能经一个全局对象 `window.WanxiangGameSDK`(加上引擎装载契约)与外界打交道,受控面之外一律被 CSP 和 sandbox 封死——没有这个 SDK平台就只是个静态文件托管。图把受控面拆成 Core 层和 Plugin 层,并把另一条并列的入口(引擎装载契约)单列在右栏。
**Core 层内联进游戏入口、压缩后小于 8KB、首屏即在**,暴露 `init` / `on` / `track` / `reportError` / `ad` / `pay``init` 注入 `traceId` 贯穿「生成 → 运行 → 上报」全链路;`track` 是 10 条 / 5s 的批量缓冲、写类 fire-and-forget`ad` / `pay` 经桥的 `request` 走 5s 超时降级。**Plugin 层按需懒加载、首屏不付代价**,其中 storage 这个面尤其要小心,因为它直接写宿主的真 localStorage——图上把它的四道闸列全了闸①只放行恰好等于 `idle:gameId:versionId` 的 keytycoon 这类无离线态的模板根本不发 storage、白名单也不含它的前缀闸②挡 4KB 以上的 valueidle 存档实际不到 200B闸③在写入前用 `JSON.parse` 校验、回读时只接受对象形态(防有人手工篡改 localStorage 注入脏数据),闸④落盘时加 `wxgame:` 前缀做命名空间隔离。这里有个设计点值得点出:回包给游戏的是宿主侧**已经解析好的对象**、不是原始字符串解析在宿主这道受信边界做、runtime 侧零 `JSON.parse`,守住「游戏代码不引可抛路径」的红线。
整张图最该让人记住的是那条贯穿所有受控面的**降级铁律**:异常绝不向游戏抛、超时就降级、写类操作 fire-and-forget。它的根源不是工程洁癖而是玩家验收门那五条 AND 里的「无错」——游戏运行期一旦抛出未捕获错误就判不过,所以受控面任何意外都得自己吞掉。右栏的引擎装载契约(`window.__GameBundle.bootGameHost` / `render(mainContext)` / `ctx.getEngine()`)是**与 SDK 并列的第二条受控入口**,但它属于另一条正交边界(详见图 5图上特意提醒软著 `ruanzhu-5` 和专利 `01-受控插件引擎` 写的是这条受控插件面、不是 iframe 产物沙箱,引用时别张冠李戴。图下方的 8 种 postMessage type 表是桥 schema 闸的枚举全集,把每个 type 的方向和用途列清,让人对照图 3 看清「双校验放行的到底是哪 8 类消息」。
### 图 5 · 两条正交边界别混SVG新·架·现
![图 5 两条正交边界](assets/sbx-05-两条正交边界.svg)
这张图专治一个最容易混的概念:系统里有**两条信任边界**,它们方向正交、位置嵌套,必须分清。边界① 是**沙箱边界**——「整个 iframe 这层壳」与「外面的宿主平台」之间的隔离,它活在 iframe 壳本身,是本档(产物执行沙箱.md的主轴边界② 是**受控面**——iframe 内部、「游戏代码」与「引擎能力」之间的约束(`api.d.ts``PluginContext`),它管「游戏代码调引擎时只能走公开 API」是 [`引擎与运行时.md`](生成引擎/引擎与运行时.md) 的主轴。一句话记牢:**受控面在沙箱里面,沙箱在受控面外面。**
图用嵌套的方框把这个关系画成可视:红色虚线大框是沙箱壳、紫色虚线框嵌在里面是受控面、最内层才是不可信游戏代码——它被两层边界一起关着。右上角的「同心嵌套示意」是这张关系的速记版。之所以强调它们「正交」,是因为两条边界各管一段、不互为替代、缺一不可,而且任何一条被破时另一条仍在兜:如果沙箱边界破了(比如同源过渡态 `allow-same-origin` 下游戏触到了宿主 DOM受控面拦不住它——这正是 §8 同源债的要害;反过来如果受控面破了(游戏绕开公开 API 去抓引擎内部),外层沙箱壳仍兜得住,不致让数据外泄或出网。把这层「破了一条还有另一条」的纵深关系画出来,就能解释为什么两条边界都不能省。
这张图右下角把「最容易混的三处」钉死,都是实际踩过或容易踩的坑:一是引用知识产权时别张冠李戴(软著/专利写的是受控插件面=边界②,不是 iframe 产物沙箱=边界①);二是关联档分工别串(`引擎与运行时.md` 讲装载 + 引擎能力=边界②,本档讲执行隔离 + 安全边界=边界①,两者正交不重叠);三是收敛各管各的(沙箱债 §8 的同源/CSP/sandboxAttr 属边界①,受控面的血统债 random/time/input 属边界②,别合并谈)。这张图没有现行/远期边界,它讲的是一个**当前就成立的概念结构**;它和图 1 的关系是图 1 给「三层封堵的全景」、图 5 给「两条边界的嵌套关系」,一个讲手段、一个讲概念分层。
### 图 6 · CSP / 同源红线 / 产物消毒Mer新·讲·现
下面这张讲解图把沙箱里「与外界资源打交道」最硬的三条红线集中起来CSP 的 `connect-src 'none'`、HJ-AUDIT-001 的 `allow-same-origin` 同源红线、以及 bundle 内联前的产物消毒。它们分别管「不准出网」「同源下不准用 same-origin」「注入的脚本不准越界」是沙箱安全性的三块基石也是 §8 现状债集中的地方。
```mermaid
flowchart TB
subgraph CSP["① CSP硬编码进 srcdoc &lt;meta&gt;"]
direction TB
C1["default-src 'none' —— 兜底封掉一切未显式放开的资源类型"]
C2["connect-src 'none' —— 禁一切网络出站(最关键)<br/>引擎 bundle 由宿主层 fetch 后内联,不在 iframe 内 fetch故不被卡"]
C3["script-src 'unsafe-inline' 'unsafe-eval'<br/>gamedef 运行时用 new Function 编译逻辑串,必需 'unsafe-eval'"]:::debt
end
subgraph SO["② 同源红线 HJ-AUDIT-001当前=过渡态)"]
direction TB
O1["红线allow-same-origin 只有当游戏包托管在独立源<br/>usercontent 子域·与宿主不同源)时才可用"]
O2["现状债:现行同源 srcdoc + allow-same-origin红线代码里未强制<br/>origin 白名单还含字符串 'null'"]:::debt
end
subgraph SAN["③ 产物消毒"]
direction TB
N1["escapeBundleForInlineScript&lt;/script&gt;(含大小写/空白变体)和 &lt;!--<br/>让 bundle 文本无法越出 &lt;script&gt; 边界"]
N2["纵深防御bundle 来自后端 engineBundle、整包 sha256 已覆盖完整性<br/>消毒是额外一层、不是唯一依赖"]
end
DEF["纵深承接:'unsafe-eval' 的风险由三重边界一起兜——<br/>逻辑串先经 build 段 scanLogic 静态拦危险面 + connect-src 'none' 无出网 + iframe sandbox 隔离"]:::ok
C3 --> DEF
O2 --> FIX["收敛方向(三件一起做才闭合):<br/>① 迁独立 usercontent 子域(让 allow-same-origin 真安全)<br/>② CSP 从 srcdoc meta 改 HTTP 响应头下发<br/>③ sandboxAttr 这条 DB→VO→前端链真接线"]:::fix
classDef debt fill:#fff7ed,stroke:#d97706,stroke-width:1.5px,stroke-dasharray:5 4;
classDef ok fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px;
classDef fix fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px;
```
读这张图要抓住一个反复出现的张力:**`'unsafe-eval'` 看着危险,但它是 gamedef 运行时必需的、且风险被纵深防御承接住了**。声明式 gameDefinition 的 behaviors / rules 各带逻辑 JS 串,`gd-runtime.js``new Function` 编译执行,缺 `'unsafe-eval'` 会抛 `EvalError` 被静默吞进 errors[]、tickBehaviors 空转、游戏只渲首帧静态、世界永不演进(这是 2026-06-21 实证过的 bug加上之后 errCnt 从 7 降到 0、score 从 0 开始演进)。它的风险承接是一条纵深链:逻辑串先在 build 边界经 `scanLogic` 静态拦掉危险面,再加 `connect-src 'none'` 断网络出站,再加 iframe sandbox 隔离——三重边界使它不扩大真实攻击面。所以图上把 `'unsafe-eval'` 标成债色、但用一条绿线指向「纵深承接」,表达「它是有意的、不是漏洞」。这里也要诚实记一笔文档漂移:`.agents/rules/security-and-reliability.md` §1.1、skills 手册、契约注释都写 `script-src 'self'`,但代码实为 `'unsafe-inline' 'unsafe-eval'`、且硬编码在 srcdoc meta 里,**以代码为准、文档口径已过期**。
第二块同源红线是本域最该警惕的过渡态。HJ-AUDIT-001 说 `allow-same-origin` 只有当游戏包托管在独立源时才能用,因为同源下 iframe 能触宿主 DOM / 存储、甚至自己移除 sandbox沙箱铁律就失效了但代码现状是同源 srcdoc 配 `allow-same-origin`、origin 白名单还含 `'null'`,红线在代码里没强制。这是已知的、独立源落地前的过渡态,不是已合规。图把它和收敛方向连在一起,强调三件事(迁独立 usercontent 子域、CSP 改 HTTP 响应头下发、sandboxAttr 真接线)必须一起做才闭合——只做一件不解决问题。第三块产物消毒相对干净:`escapeBundleForInlineScript``</script>``<!--` 防 bundle 越出脚本块,而且 bundle 来自后端、整包 sha256 已覆盖完整性,消毒只是纵深里额外的一层、不是唯一依赖。
### 图 7 · 三容器加载 / 失败 / 销毁态机Mer新·状·现
下面这张状态图回答 feed 里「上下滑动切游戏」时沙箱容器的生命周期怎么管。绘境AI 的 feed 是短视频式的游戏流,玩家上下滑会连续切换游戏,所以沙箱容器不是一个、而是逻辑上的三个角色在轮转:**当前正在播放的、前一个正在销毁的、后一个正在预加载的**。这张图把这三态的流转、以及「加载失败怎么降级」画清楚。
```mermaid
stateDiagram-v2
direction LR
[*] --> Preload : 进入可视区前预取
Preload : 后一个 · 预加载
Preload : 取包 + sha256 校验 + buildIframeSrcdoc<br/>iframe 挂载但未掌帧
Current : 当前 · 播放中
Current : boot 掌帧 · game_loaded→phase=ready<br/>game_start · watchGameEnd 轮询终态
Disposing : 前一个 · 销毁中
Disposing : dispose 移监听 + 清挂起请求定时器<br/>iframe 卸载 · 防泄漏
Preload --> Current : 滑到它(成为当前)
Current --> Disposing : 滑走(被下一个取代)
Disposing --> [*] : 释放完成
Current --> Fallback : 加载失败 / sha256 不过 / 超时
Fallback : 降级 demo 兜底<br/>只 console.warn · 不向上 emit error
Fallback --> Disposing : 滑走时照常销毁
note right of Current
加载超时按装载路分流:
引擎包 12s · 旧 demo 路 5s
(引擎冷启动 4.8~5.3×
end note
```
读这张图要抓住两个设计点。其一,**三容器轮转是为了让「即点即玩」成立**:如果每次滑到一款游戏才开始取包、校验、注入、冷启动引擎,玩家会看到明显的等待;提前在「进入可视区之前」就把后一个容器预加载好(取包 + sha256 + 挂载 iframe、但还不掌帧滑到时才 `boot` 掌帧,等待就被藏进了滑动的过程里。与此对称,前一个滑走的容器进入销毁态,`dispose` 必须移监听、清掉所有挂起请求的定时器——这一步不能省,否则切几十款游戏后会积累一堆未清理的监听和定时器、内存泄漏。其二,**加载失败是一条降级支路、不是终止**sha256 校验不过、取包出错、或加载超时,都不让宿主整个隐藏显示「加载失败」,而是降级到 demo 兜底、只 `console.warn`、不向上 emit error原因同图 2——父级 `Play` 把 error 当致命态会隐藏宿主,而 demo 本可正常试玩)。这条降级支路汇回正常的销毁流:滑走时它照常被 `dispose`
这张图没有现行/远期边界,它是现行 feed 容器生命周期的真实形态;唯一的过渡口径在「终态怎么来」——`watchGameEnd` 轮询 `host.state().phase``gameover` 才 latch 一个 `game_end` 代发,是因为 ref 游戏自己没有 emit 通道,等 W-G1 落地后改由各品类标准信号产出、轮询桩可下线(与图 2 同源)。
---
## 3. 图清单与状态表
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 不可信代码隔离全景 | 架 | SVG新 | 现 | 三层封堵build 段 scanLogic / iframe CSP / sandbox 属性)+ 唯一放行通道 postMessage + 封死逃逸面 + 同源过渡态四债§8诚实标注 |
| 2 | 取包 → sha256 校验 → iframe + CSP → 注入 时序 | 时 | SVG新 | 现 | resolvePackage 四态 + sha256 双通道Web Crypto / 纯 JS 回退)+ 字节一致性 + 函数序列化注入 + __GameBundle + 加载超时分流 + game_end latch 代发 |
| 3 | postMessage 双向桥与双校验 | 时 | Mer新内联 | 现 | origin 闸(空白名单默认拒绝·含 'null'+ schema 逐字段闸 + 回包 requestId 配对 + request 5s 超时降级不 reject + 校验不抛异常 |
| 4 | 受控面SDK bridge能力面 | 类 | SVG新 | 现 | Core 层 &lt;8KBinit/on/track/reportError/ad/pay+ Plugin 层懒加载storage 四闸)+ 引擎装载契约(第二条入口)+ 降级铁律 + 8 type 表 |
| 5 | 两条正交边界 | 架 | SVG新 | 现 | 沙箱边界iframe 壳 vs 宿主边界①vs 受控面(游戏↔引擎,边界②)嵌套关系 + 破一条另一条仍兜 + IP/关联档/收敛三处别混 |
| 6 | CSP / 同源红线 / 产物消毒 | 讲 | Mer新内联 | 现 | connect-src 'none' + 'unsafe-eval' 纵深承接(漂移①以代码为准)+ allow-same-origin 同源红线过渡态HJ-AUDIT-001+ escapeBundle 消毒 + 收敛三件一起做 |
| 7 | 三容器加载 / 失败 / 销毁态机 | 状 | Mer新内联 | 现 | 当前播放 / 前一销毁 / 后一预加载 三态轮转 + dispose 防泄漏 + 加载失败降级 demo不上抛+ 加载超时分流 + game_end latch 过渡口径 |
> **状态分布**:现 ×7机制全建成、真跑通过。本域无「待接 / 待建 / 缓做 / future」整图——但**现行机制内有四处已知债**CSP 文档口径漂移、sandbox 属性三处不一致、sandboxAttr 半孤儿、HJ-AUDIT-001 同源红线过渡态),在图 1 / 图 6 中用橙色虚线框 + 文字小标与「现行已建实心块」区分,绝不画成「已合规收口」。**防漂移门**:本图说 frontmatter 记源档 `产物执行沙箱.md @ 38357c3d`源档变更即比对hash 对不上则本图说与对应 SVG 标「待复核」。
>
> **PNG 后续**7 张图中 4 张为 SVG图 1/2/4/5SVG 入仓后在 mini-desktop 批量转 PNG6c6g 禁 chrome3 张 Mermaid图 3/6/7GitHub 直接渲染、无需转换。
>
> **单源说明**本域所有图均为新作SVG新 / Mer新无「引」类。源设计档 `产物执行沙箱.md` 自身在 §1/§2/§3 内嵌了三段 Mermaid端到端时序、三重边界、桥双校验本图说**不复制它们**——图 2 是把 §1 时序升保真为 SVG更细、含四态与双通道、图 3 的桥流程按「桥判定流」单独框选重画(横向、突出双闸 + 回包配对,与源档 §3 的纵向块图视角不同)、图 1/4/5 则是源档没有的新视角(全景 / 类图 / 边界嵌套)。源档那三段 Mermaid 仍是它自己叙述的一部分、各居其位,本图说在散文里指向源档对应章节,不在两处各存一份同图。

View File

@ -1,195 +0,0 @@
---
date: 2026-06-22
topic: 架构域图说——把「这套系统用什么技术、怎么搭起来、关键选型为什么这么选、13 个模块怎么分工与依赖、一条生成请求怎么跑通、契约族长什么样」画成一套图 + 讲解(架构图集·架构域)
status: 现行为主(含决策史对照与契约现实缝)· 防漂移门记源档 commit hash
映射源档:
- docs/architecture/架构/README.md @ 38357c3d
- docs/architecture/架构/13模块.md @ 7ecd616e
- docs/architecture/架构/契约总览.md @ 38357c3d
---
# 架构域图说
> **这是什么**绘境AI 架构域的「看图入口」。架构域回答的是 HOW——**这套系统用什么技术、怎么搭起来**:分层怎么分、关键选型为什么选 A 不选 B、13 个后端模块各管什么又怎么依赖、一条「一句话生成游戏」的请求怎么跑通、游戏怎么安全地跑在玩家面前、契约族长什么样又在哪些地方已经漂了。这份图说把这些用一套图加配套讲解画清楚:复杂、跨模块的用手绘 SVG 大图,已经在各 README 里画好的 Mermaid 一律单源引用、绝不复制。
>
> **给谁看**CTO、技术合伙人、首席架构师、新加入的工程师、做模块边界与契约评审的人、外部技术尽调。判断「这套架构是不是想要的那个、哪里有设计缝」看这份图就够建立全局轮廓某个子系统的更深细节生成引擎 SAA 拓扑、沙箱、运维部署)去对应子文档与子域图说。
---
## 0. 阅读约定与同步纪律
- **映射的设计档**:本图说不另立设计,只把架构域三份 canonical 设计档画出来——整体分层、关键决策的「为什么」、模块依赖、生成时序、安全运行时、推荐打分出自 [`架构/README.md`](README.md)13 模块的逐个职责 / 边界 / 依赖 / 建设状态出自 [`架构/13模块.md`](13模块.md);契约族导航与口径收口出自 [`架构/契约总览.md`](契约总览.md)。frontmatter 里记了这三份的当前 commit hash作为**防漂移门**源档一旦变更、hash 对不上,这份图说与对应 SVG 即标「待复核」,由收口脚本比对。
- **同步纪律****设计一变动,本图说与对应 SVG 必须同步更新**,每张 SVG 脚注注明映射源档与状态。已并入 wave 收口清单。
- **单源原则**:本图集要消灭的就是「同一张图存两处、改一处漏一处」的漂移面。所以**凡 README 已内嵌的 Mermaid一律不复制进来**——图说在叙述里链接到「见 README 第 X 节」,只新作 README 没有的图SVG新 / Mer新。本域 12 张图里有 7 张是这种单源引用(图 1/3/4/5/6/7/8它们的图形本体在 README这里只讲「这张图让人看出什么、有没有设计缝」。
- **本域状态分布**:架构域绝大多数是「现行已建/已实测」,但有两类内容必须看清状态、绝不能画成纯现行——**决策史**(图 2/3 里被推翻的 Dify / OpenGame / 自研壳,是演进对照、不是现行架构)和**契约现实缝**(图 11 里 DB 镜像已漂移、CI 防漂移门缺位等,是声明与代码不符的待决策位)。每张图内部还会用实心块 / 虚线框 + 「废·决策史」「现实缝」小标把状态再标一层。
- **产物形式**SVG 入仓GitHub 与编辑器直接渲染矢量PNG 在 mini-desktop 转6c6g 禁 chrome、无转换器。本图说只出 SVG引用类不产新图Mermaid 类 GitHub 直接渲染。
## 1. 全图通用图例
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上,架构域按图点其中几个):
- **成本**`#16a34a`):选 Huijing 买现成后台、便宜模型直出、单 key 入计费台账、不硬凑组件——都是「用 5 人小团队 + ¥4,300/月 跑起来」的取舍。
- **质量**`#15803d`harness 九门兜底、三层约束框架、error_rate 硬降权保可玩底线——质量是设计进去的,不是 LLM 自评。
- **数据**`#475569`):契约即跨端数据边界、推荐用信号驱动排序、生成成本可对账——数据口径对不对,是这套系统能不能闭环的根。
- **可靠**`#16a34a`):幂等矩阵、最终一致 + 补偿、SLO + Error Budget、多通道兜底——涉及外部模型 / 异步 / 支付,可靠性必须前置。
- **可观测**`#0ea5e9`四路信号Metrics/Traces/Logs/Errors+ SAA 节点 observation——但落地态是「接」详见运维域。
- **安全**`#dc2626`iframe 沙箱 + CSP 红线、契约防漂移门缺位是真实风险、脱敏——前端单点挡不住,必须在可信边界强制。
(另两个维度 **伸缩** `#7c3aed`、**可观测** `#0ea5e9` 在生成/治理图上点到。)
**复用 / 边界三线语义**
- **实线**`#334155`):现成直接用、同步动作、单向依赖或数据流。
- **虚线**`#64748b``stroke-dasharray="6 4"`):自建 / 解耦 / 远期 / 待接线 / 决策史的目标态或对照态。
- **双线 / 加粗框**:跨域共享的公共件或需要强调的边界。
> 架构域图说里,虚线还额外承担一层**状态语义**:凡是「废·决策史」(图 2/3 被推翻的旧方案)、「待接线」(图 10 可观测落地)、「现实缝」(图 11 已漂移的契约)的元素,一律用虚线框 + 文字小标画出,与「现行已建」的实心块在视觉上一眼区分。这是本域最该守的纪律点——决策史和现实缝都极易被误读成「现在就是这样、而且没问题」,画得再好看也不能让人误判。
---
## 2. 图集
### 图 1 · 六层技术分层〔引·现〕
> 单源引用,不复制:整体六层分层的 Mermaid 已在 **[架构/README.md §1](README.md#1-一张图看懂整体分层)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来。
这张图回答「整套系统怎么搭起来」。绘境AI 的后端基于 Huijing Cloud一套基于 Spring Cloud Alibaba 的开源 Java 企业级后台框架,我们 fork 它做二次开发)搭建,在它提供的基座能力之上叠加 13 个游戏业务模块。整套系统自上而下分六层:用户从浏览器进来,经**接入层**CDN / Nginx和**网关层**Spring Cloud Gateway统一路由 / 限流 / 鉴权 / 灰度),落到**业务服务层**13 个游戏业务模块);业务服务依赖 Huijing 原生的**基础设施层**system 用户权限 / infra 文件任务 / bpm 工作流),并向上调用一个独立的 **AI 生成层**来产出游戏SAA 裸图编排 → new-api 网关 → 便宜 LLM配 LittleJS + Runner v2 引擎);所有这些都坐在**中间件层**MySQL / Redis / MinIO之上由旁路的**可观测性层**监控。
读这张图最该抓住的是它那条贯穿始终的设计取向:**先简后扩、能复用就不自研**。后端复用 Huijing 现成的 60% 后台能力,生成不自研大模型而接通用模型,引擎不自研而用成熟的 LittleJS——这条取向直接决定了系统能用很小的团队和很低的成本跑起来。要注意图里有一处必须按状态读的设计缝中间件层画了 `Nacos · RocketMQ`,但旁边明写「框架自带 · MVP 未部署」——它们是 Huijing 框架自带的依赖、yaml 也在仓里,但 MVP 运行时并没有启动 broker / registry凡涉及「异步 MQ」「服务注册发现」的设计在 MVP 阶段都以「进程内调用 / 本地配置」落地。这是 future-state别当现行已部署。
### 图 2 · 关键选型决策树SVG新·讲解·现+史〕
![图 2 关键选型决策树](assets/arch-02-关键选型决策树.svg)
这张图回答「架构里那几项最关键的选型,为什么选 A 不选 B」——架构里真正值钱的不是组件清单而是这些决策背后的理由。图把对整体形态影响最大的四项决策横排每项给出**现行选定**(绿色实心)、**同期落选候选**(灰框)、以及它击败对方的理由:① 后端框架选 Huijing Cloud60%+ 后台开箱即用),击败缺企业级基础设施的 NestJS 和缺 RBAC/BPM 现成方案的 Go② 生成主线分两条线、按品类各选其形:现行的 Tier0/1 廉价线选 new-api 网关 + 便宜 LLM + SAA 裸图Java编排由三次裁定 C2 / HJ-GEN-001 / HJ-AGI-002 逐步锚定),远期的 tier2 富游戏线选 AgentScopePython 自治 ReAct独立 service——一条用确定性图把便宜模型框住、一条放开 agent 自治去啃富交互,两种范式各管各的品类(详见图 3③ 运行时引擎也随这两条线分轴Tier0/1 廉价线用 LittleJS 增强发行版Tier1 唯一交付层tier2 富游戏自治轨用 Phaser/Pixi 全无头引擎(远期),而 Cocos 收窄到「3D / 复杂场景 / 渠道导出」这一轴(编辑器 + 人在环离线作者),三者击败启动重的 Unity、导出不含快手的 LayaAir——**注意 Cocos 不是被废弃,而是被收窄到它真正适配的那一档,仍是有效决策**;④ AI 素材工具链选 mmx-cli免 GPU、免训练ComfyUI 退备选。
这张图最该让人看清的是底部那条橙色虚线的**决策史带**——也是本图最该守状态纪律的地方。Dify可视化 LLM 工作流平台、OpenGame现成游戏生成 agent、自研轻量 Canvas Runtime <15KB自研壳这三项在早期蓝图里都是省自研时间开箱即用的首选但随后的技术验证把它们逐一推翻Dify+OpenGame 直连便宜模型 + 固定运行时更轻就达标 spike 证伪降为远期增强从未部署对应契约 #6 dify-workflow-io 同步作废自研壳被 LittleJS 85/82 spike 比分击败 15KB 红线也一并废除改为三层约束框架)。把它们画出来不是说现在还在用而是为了理解为什么现在是这样」——这是据图做架构 review 时最容易踩的坑把演进中被推翻的旧方案误当现行所以它们一律虚线框 + ·决策史与绿色现行块一眼区分现行 vs 决策史在生成主线上的更细对照见图 3
### 图 3 · 生成主线 现行 vs 决策史〔引·流·现+废〕
> 单源引用,不复制:生成主线「现行 ✅ vs 蓝图原案 ❌」的两个 Mermaid现行 SAA 链路 + 决策史 Dify/OpenGame已在 **[架构/README.md §2.2](README.md#22-生成主线--new-api-网关--便宜-llm--saa-裸图编排现行)** 内嵌,是该图的唯一来源。这里只链接、不抄进来;选型层面的「击败了谁」总览见本域图 2。
这张图把生成主线这一处「演进最剧烈、也最关键」的决策单独放大,讲清现行那条链路到底长什么样、又是怎么从蓝图原案走过来的。**现行主线**(已后端实测)是一条:创作者 Prompt → SAA 裸 `StateGraph` 编排16 节点 / 7 条件边)→ new-api 网关OpenAI 兼容、多模型)→ 便宜 LLMDeepSeek-v4 / MiniMax-M2.7·M3→ harness 九门兜底(校验 / 构建 / 真玩)→ GamePackage 出包。几个术语一句话记住:**new-api 网关**让「换模型/多通道兜底」变成网关层的配置事、业务代码无感,且单 key 自动入计费平面接入坑baseUrl 要剥掉末尾 `/v1`**harness 九门**意味着 done 由这些确定性门判定、不让 LLM 给自己打分,门不过就不出包;**SAA 图的唯一布线源**是 `SaaStudioGraph.assemble()`,生产派发与回归测试共用同一份 assemble、避免布线漂移。还有一处范式校正必须看清这条线的**终态产物定为一份可维护的 `src/` 源项目**(配置驱动 / 模块化 / 资产分离的长生命周期项目,改源不改包、改完重新构建;改数值 / 换美术走确定性编辑免 LLM改逻辑才让 LLM 重生成对应模块——创始人 2026-06-20 定调)。当前 generate 节点产出的 **gameDefinition 是结构化中间表示、不是合格终态产物**——声明式数据壳把逻辑核塞进 JSON 字符串、运行时用 `new Function` 解释,这只是「通往 `src/` 工程的中间脚手架」、属已知偏离终态的债;产线正把它迁成「直接生成 `src/` 源项目」plan `2026-06-18-001` U1U4仍在落地以生成引擎子树最新裁定为准
这张图要让人看出的设计缝在于「现行」与「决策史」的硬分界:蓝图原案 Dify + OpenGame 那一组(图里 ❌ 标「从未部署·降远期」)和现行 SAA 线之间没有渐变——不是「先用 Dify 后来换 SAA」而是 Dify/OpenGame 从未部署、直接被验证更轻的路径取代。除此之外还有一条**两条生成线**的边界要一并记住(深度在生成引擎子树展开):现行这条 SAA + LittleJS 廉价线是为超休闲轻游戏Tier0/1量身打造的可靠产线经营 / 合成 / 多系统富交互那一档富游戏它结构性地够不着,由远期的 **tier2 富游戏自治轨**承载——那条轨换的是整套生成范式AgentScope Python 自治 ReAct + 独立 service + Phaser/Pixi 引擎 + 三层校验地板 + 人工终审),与廉价线解耦并存、只经公共件交汇。两条线**远期有可能收敛为一条**——把 SAA + LittleJS 也并入 AgentScope 自治范式(登记为未来方向,当前不做、不预先设计)。读这张图时若想看「为什么是 SAA 而不是 Dify」的选型理由回到图 2 的决策史带;若想看 SAA 16 节点拓扑、加节点方法、救场阶梯、dispatcher 契约、tier2 详设这些更深的实现细节,去生成引擎子文档与 `.agents/skills/saa-graph-orchestration.md`——本图只承载「现行主线轮廓 + 与决策史的边界」,深度留生成引擎子树。
### 图 4 · 13 模块聚类〔引·架·现〕
> 单源引用不复制13 模块按业务闭环位置归成四簇的 Mermaid 已在 **[架构/README.md §3](README.md#3-13-个后端业务模块总览)** 内嵌(与 [13模块.md §1](13模块.md) 同源),是该图的唯一来源。这里只链接、不抄进来。
这张图回答「13 个后端模块怎么分工」。绘境AI 把全部业务能力按领域边界(一类职责归一处)切成 13 个模块,追求高内聚、低耦合;它们物理上以 jar 聚合进 Huijing 单体一起运行MVP 单体启动、Spring Profile 控制加载逻辑上各自独立、可被未来拆分。按在业务闭环里的位置13 个模块归成四簇:**创作链路**studio 创作编排 / aigc 无状态生成原子 / runtime 编译沙箱发布 / project 项目生命周期)把游戏做出来;**分发与数据**feed 游戏流推荐 / telemetry 事件聚合质量评分)让游戏被玩到、被看清;**变现链路**pay 收单 / trade 分账结算 / ad 广告)把钱赚回来;**平台与合规**community 社交通知 / ip 素材授权 / compliance 内容安全锁风门 / biz B端定制让生态转得起来、守得住。
读这张图要记住一条配套口径:图里画的是「应该怎么切」(结构权威),不是「实际建成多少」。每个模块有一个三字母前缀,技术功能用 `T-{模块}-{nn}` 编号(全平台共 204 项,是结构注册表,只增不改号)。**真/桩/未建的实时状态以 `docs/mvp/MVP进度总账.md` 为准,冲突时口径是「状态 > 实现 > 结构」**——例如 ip 模块在结构上独立成簇实际却是「seam 寄宿在 compliance 里」有意不独立建pay 是 Huijing 原生模块但当前未接入单体启动器。这张图给的是空间感和职责边界,看「这块功能落在哪个模块」用它,看「这块建到哪了」要去 13模块.md §4 的状态总表或进度总账。
### 图 5 · 13 模块单向依赖〔引·架·现〕
> 单源引用不复制13 模块单向依赖方向图(箭头 A→B 表示 A 依赖 B已在 **[架构/README.md §4](README.md#4-模块依赖为什么是这个方向)** 内嵌(与 [13模块.md §2](13模块.md) 同源),是该图的唯一来源。这里只链接、不抄进来。
这张图回答「模块之间为什么是这个依赖方向」。模块间是单向、低耦合的依赖——A 依赖 B、B 绝不反向依赖 A且只通过每个模块的 `-api` 包(只声明 DTO + Feign 接口、不含实现)交互。读这张图有四条主线:**创作侧 studio 站在最上游**,把活分派给 aigc生成、runtime编译、ip素材、project落库、compliance安全裁决它自己几乎不被别人依赖——这是「工作台」该有的位置**生成原子 aigc 保持无状态**,只向下依赖 compliancePrompt 安全)和 project写结果无状态意味着它天然可重放、可横向扩容**数据回路 telemetry ↔ feed 互相依赖**——这是图里唯一一处双向边feed 消费质量分来排序、telemetry 回收互动信号来计算),正是平台「越用越聪明」的机制所在;**资金侧 trade 向下收口**,依赖 pay收单和 ad广告收入拿原始数据自己只管分账结算。
这张图最该让人看出的是「为什么单向切分值得」:这种切法让任何一个模块都能独立演进、独立测试,也是未来从单体拆成微服务时的天然切割线——依赖方向就是拆分边界。要注意图里还藏着两处「风格-版权」与「专区」的跨模块协作环路compliance ↔ ip ↔ aigc它们不是普通的模块依赖而是横切关注点单独由图 12 讲清 owner 与聚合关系这里只需先记住「telemetry↔feed 那条双向边是有意的、不是设计漏洞」。
### 图 6 · 一条生成请求时序〔引·时·现〕
> 单源引用,不复制:「一句话生成游戏」的完整时序图(创作者 → studio → Gateway → aigc → SAA → new-api → LLM → 九门 → project已在 **[架构/README.md §5](README.md#5-一条生成请求是怎么跑通的)** 内嵌,是该图的唯一来源。这里只链接、不抄进来;生成任务状态机见本域图 7。
这张图回答「把分层、生成主线、模块依赖串起来,一次生成到底怎么跑通」——这是创作链路的核心路径。时序从创作者输入 Prompt + 选风格开始game-studio 发 `POST /app-api/aigc/generate` 经 Gateway 鉴权转发到 aigc 模块aigc 创建生成任务(由 `GenerationDispatcher` 派发)后**立即返 202 Accepted + taskId**、前端转去轮询/SSE 监听真正的生成在后台展开——aigc `dispatch(job)` 进入 SAA 裸图编排,按 render→classify→design→generate 等 16 节点跑,各节点经 new-api 的 OpenAI 兼容接口调模型(单 key 自动入 newapi_cost 计费),模型产出 GameConfig / 游戏代码后过 harness 九门done 由确定性门定、不过则走修复回环),通过才出 GamePackage、回调写入 project 草稿版本、通知前端任务完成。
读这张图要抓住两个关键设计:其一,**生成是异步的**——202 + taskId + 轮询这套,是因为外部模型调用耗时不可控(生成 P50<60sP95<180s不能让创作者的请求线程一直挂着其二**派发走 `GenerationDispatcher`生成态藏在 job/callback 契约后**——http worker 与进程内 SAA 图二选一单写这层抽象让现在用进程内 SAA将来换 http worker变成可替换的实现细节调用方无感这正是图里把 SAA 编排画在 dispatcher 之后的原因它不是直接被 controller 而是被 dispatcher 按契约派发
### 图 7 · 生成任务状态机〔引·状·现〕
> 单源引用不复制生成任务状态机QUEUED→RUNNING→SUCCEEDED/FAILED/TIMED_OUT + 重试/取消迁移)已在 **[架构/README.md §5](README.md#5-一条生成请求是怎么跑通的)** 内嵌(紧接时序图后),是该图的唯一来源。这里只链接、不抄进来。
这张图回答「生成任务自己的生命周期怎么管」。生成任务是一个有明确状态机的对象,它给「超时/失败/重试/取消」都定义了清楚的边:任务创建即 QUEUED被消费/派发进 RUNNINGRUNNING 有三个出口——生成完成且质量通过 → SUCCEEDED生成失败或质量不达标 → FAILED超时120s→ TIMED_OUTFAILED 可重试 ≤2 次回 QUEUEDTIMED_OUT 可重试 ≤1 次回 QUEUED超过重试次数才终态 FAILED用户取消则从 QUEUED 或 RUNNING 进 CANCELED。
这张图最该让人看出的,是它把「任何涉及外部模型调用的链路都必须考虑的可靠性设计」具象化了——状态机不是为了好看,而是为了把「模型可能慢、可能失败、可能要让用户取消」这些现实约束变成代码里可执行、可观测的边。配套的硬指标钉在状态机外:生成成功率 ≥80%MVP 验收线,远期蓝图 ≥85%)、队列最大积压 500 任务、超过返回 429。读这张图时要把它和图 6 配着看:图 6 给「一次成功生成怎么跑」的正路,图 7 给「失败/超时/取消怎么收口」的全路径——正路只是状态机里 QUEUED→RUNNING→SUCCEEDED 那一条主干。
### 图 8 · 游戏安全运行时序〔引·时·现〕
> 单源引用,不复制:游戏在 iframe 沙箱里安全加载运行的时序图(请求 manifest → 校验 → 并行取 entry+assets → 创建 iframe+CSP → 注入 GameConfig+SDK → 执行 → postMessage 回报)已在 **[架构/README.md §6](README.md#6-游戏怎么安全地跑在玩家面前)** 内嵌,是该图的唯一来源。这里只链接、不抄进来;沙箱与受控面两条正交边界的更深拆解见 [产物执行沙箱.md](产物执行沙箱.md) 及其图说。
这张图回答「生成出来的游戏怎么安全地跑在玩家面前」。生成出来的游戏运行在 iframe 沙箱(浏览器内嵌的隔离框架)里,与平台彻底隔离;平台能力靠 WanxiangGameSDK 注入进去——这是平台向游戏注入能力的**唯一通道**,没有它平台就只是个静态文件托管。时序从 game-studio 请求 manifest.jsonhash 缓存)开始:拿到 `{entry, assets[], checksum}` 后先校验 manifest 完整性,再并行请求 entry.js + 关键 assets创建带 CSP + sandbox 的 iframe注入 GameConfig + Game SDK bridge沙箱内执行 entry.js 初始化游戏、回 postMessage `game_loaded`,游玩中 SDK bridge 持续上报生命周期事件、结束回报 `game_complete + score`。加载用三容器策略(参考抖音预加载):当前播放的容器之外,前一个在销毁、后一个已预加载完成,上滑切换无缝。
这张图最该让人看清的是几条不能破的安全红线——它们是安全与合规可控的根,画在时序之外但比时序更重要:**iframe 沙箱**用 `sandbox="allow-scripts allow-same-origin"`,但有一条 2026-06-10 审计补的红线——`allow-same-origin` 仅当游戏包部署在独立源(与宿主不同源的 usercontent 子域)时才可用,同源下 iframe 能触宿主 DOM/存储甚至自己移除 sandbox沙箱铁律就失效所以独立源就绪前禁用 `allow-same-origin`**CSP** 是 `script-src 'self'; connect-src 'none'`,即游戏内无任何网络请求,且必须经游戏包托管侧的 HTTP 响应头下发、不能只靠 meta 标签;**LLM 产物消毒**——GameConfig 文案字段入库前做白名单字符集 + 长度校验,渲染侧一律转义后绘制,禁 innerHTML/eval。底线原则是创作者通过配置不是写代码驱动游戏行为平台对运行时代码拥有完全控制权。
### 图 9 · 推荐打分公式SVG新·讲解·现
![图 9 推荐打分公式](assets/arch-09-推荐打分公式.svg)
这张图回答「好游戏怎么被刷到」。MVP 阶段的推荐是规则 + 信号、不上机器学习(那是增长期的事)。每款游戏的曝光排序由一个打分公式决定,图把这个公式拆成三类信号画清楚:**正向信号加分**quality_score 综合质量分 / freshness 新鲜度 / interaction_rate 互动率,让好游戏浮上来)、**负向信号减分**skip_rate 跳过率 / error_rate 错误率 / report_rate 举报率,让差游戏沉下去)、**调节项**bonus_new_creator 新人保底曝光 + bonus_featured 运营精选加分,给生态公平起点和运营调控手)。候选集存在 Redis Sorted SetTTL 60scursor 分页Sorted Set 天生按分排序适配无限流),由 feed 读取下发成竖屏游戏流。
这张图最该让人看出的有两点。其一,**error_rate 是唯一的「硬」降权**(图上用红框单标)——加载失败/试玩次数高的游戏直接沉底,因为可玩性是底线,技术上跑不动的游戏一票否决排序,这条把「好不好玩」之前先卡住「能不能玩」。其二,**这套规则为什么够用**:右下角那条飞轮回路画出了「玩家在 feed 玩/互动 → telemetry 回收信号算 quality_score → 回喂 Score 重排候选集」的闭环——质量好 + 爱玩的游戏自然浮上来,数据回流持续校准推荐,这正是平台护城河的来源,不需要 ML 模型在 MVP 阶段就能把排序做对。要按状态读的设计缝在「MVP 现实形态」那个橙虚线框里:候选集**当前可直查 MySQL、Redis 缓存是增长期形态,且游标分页目前是桩(永远返回第一页)**——公式和飞轮是设计真相,但 Redis 候选集与真游标分页的落地仍是增长期的事,别当已全建。
### 图 10 · 工程治理(幂等 / SLO / 可观测SVG新·讲解·现
![图 10 工程治理 幂等/SLO/可观测](assets/arch-10-工程治理.svg)
这张图回答「可靠性和质量怎么被钉死」。这套系统涉及外部模型、异步任务、支付,所以可靠性不是事后补的、而是设计进去的。图把三条贯穿的硬约束并排画出:**① 幂等矩阵**——重复点「生成」靠 idempotency_keyRedis 5 分钟去重)、支付回调重复靠订单状态机 + 乐观锁、发布重复提交靠 project_version 唯一约束,配套原则是尽量避免分布式事务、改用最终一致 + 补偿、并用定时任务扫「中间态超 5 分钟」的记录兜底;**② SLO + Error Budget**——游戏流 API 99.5%(预算 3.6 小时/月、AI 生成 99%(预算 7.2 小时/月,外部模型不可控故给得宽)、支付 99.9%(预算 43 分钟/月,钱相关最严),整体可用性 ≥99.5%MVP**③ 四路可观测**——业务服务把 Metrics/Traces/Logs/Errors 分送 Prometheus/Jaeger/Loki/Sentry汇到 Grafana。
读这张图要抓住一个状态分界:**幂等机制与 SLO 目标是现行(写进设计、代码已落),但右侧四路可观测的「落地手段」整体是「接」(待接线)**——图上把四路信号都画成橙虚线 + 「接」小标只有「SAA 编排节点 observation + new-api 调用埋点」是已就位的实心块,落地状态以运维域观测体系图为准。这是本图最该守的纪律:可观测的「设计意图」是真的,但「后端真接上 Prometheus/Grafana」大半还没做不能因为 README §9 写了四路就以为监控已建好。图底那条红色风险带也值得记住——它列的不是假想风险而是设计里钉死的应对:**LLM 网关单点通道批量失效**2026-06 已真实发生:二厂系通道全废,应对是多通道健康巡检 + key 监控 + 降级抽检 + 批跑冻结阀new-api 网关正是为此设计)、**LLM 成本失控**(应对是限频限额 + 日预算熔断 + 显式 max_tokens、以及**监管与上游平台风险**(非纯技术,由合规专项承载、登记在此防失踪)。
### 图 11 · 8+2 类契约族总览(声明 vs 现实SVG新·架·现
![图 11 8+2 类契约族总览](assets/arch-11-契约族总览.svg)
这张图回答「契约族到底有哪几类、各落哪、各算第几」——也是本域**最该据图做评审**的一张,因为它不只画理想的「应该怎样」,更如实标出已经漂掉的地方。图按三个物理落点组织:**落点① contracts/ 顶层**(跨三仓五工位 SSOT含跨仓 8 类 + agent-loop/ + templates/)、**落点② game-runtime/src/ 内部接线面**(第 9 类 game-host.d.ts 装载契约 + 第 10 类 runtime-api-2d.d.ts 运行时访问约定,不落 contracts 是因为落了会让跨仓 SSOT 反向 import、拆仓即断、**落点③ Java 镜像 -api 包**contracts 的代码镜像,每模块一份,同步序单向:后端先写 -api、前端据此定 TS。主编号轴只有一条README 的 18 类 + 后来 additive 的第 9/第 10。
这张图的价值全在底部那条红色的**五处现实缝**带——这是《契约总览》自陈、也是据图 review 最该揪的:**缝① DB 镜像已漂移**README §41 声称 contracts/db-schemas 是授权源、要求 diff 一致,实情是执行副本 25 个 V*.sql、contracts 只有 18 个、缺 V14V20真授权源其实是执行副本那 25 个全集);**缝② CI 防漂移门缺位**(文档把 flyway validate / contracts↔migration diff / prompt 四道闸写成 CI 自动拦截,核到代码:全仓唯一 CI 是 yudao fork 继承件、on push to master 在本仓 dev/2.0.0 永不触发、还跳测、无任何 diff 步——它们是文档承诺不是机器门);**缝③ Dify #6 已废**dify-workflow-io 对应被推翻的蓝图原案,是 8 类里唯一一个「废」,留 DEPRECATED 墓碑,读到别当现行);**缝④「第 9 契约」五套编号相撞**(跨仓主轴第 9 类装载契约才是真正的第 9其余「第 9 契约组 9a9g」「9c」「生成主线 8 契约①–⑧」都是局部上下文,撞数字不撞语义,引用契约要认上下文不认数字);**缝⑤ agent-loop / templates 在 README 目录图漏登**(那张图只画了跨仓 8 类,新人 ls 到这两目录无从对应本图与《契约总览》补登它们。把这五处诚实画出来正是为了让评审者据图就能发现「声明与代码不符」的待决策位——要么补一道真门wave-close 或 pre-commit 加 contracts↔migration 的 cmp漂移即拦截要么裁定执行副本为唯一源、把 contracts/db-schemas 降只读快照,无论哪条都得先让 README §41 的口径和代码实情对上。
### 图 12 · 专区 Zone + 锁风门 GateMer新·讲解·现
这张图回答「两个跨模块概念的 owner 与聚合关系」。有些能力不属于单一模块,而是横跨多个模块协作完成;为避免「人人都管、结果没人管」的灰色地带,每个横切关注点都指定唯一的 owner责任主。MVP 阶段有两个这样的概念,图把它们的 owner、原料供给方、消费方画成一张概念图**锁风门 Gate**T-CMP-12一道「风格-版权一致性」门owner 是 compliance它本身不检测风格而是聚合 aigc 的风格检测原子T-AGC-19和 ip 的 IP 风格校验原子T-IP-04综合裁决出 pass / review / block挂在 project 的发布前检查T-PRJ-05**专区 Zone**T-PRJ-07运营双轨分区授权 IP 区 / UGC 用户原创区owner 是 projectfeed 据它分区推荐T-FED-15、ip 据它做素材双轨归类T-IP-10、studio 决定创作去向。
```mermaid
flowchart TB
subgraph GATE["锁风门 Gateowner = compliance · T-CMP-12"]
direction TB
AGC19["aigc 风格检测原子<br/>T-AGC-19"]:::raw
IP04["ip · IP 风格校验原子<br/>T-IP-04"]:::raw
CMP12["compliance 聚合裁决<br/>pass / review / block<br/>(标准 / 严格 / 人工复核)"]:::owner
PRJ05["project 发布前检查<br/>T-PRJ-05消费裁决"]:::consume
AGC19 -->|供原料| CMP12
IP04 -->|供原料| CMP12
CMP12 -->|挂载| PRJ05
end
subgraph ZONE["专区 Zoneowner = project · T-PRJ-07"]
direction TB
PRJ07["project · Zone 实体 / 归属 / 运营位<br/>授权 IP 区 ‖ UGC 区"]:::owner
STU["studio<br/>决定创作去向"]:::consume
FED15["feed 据 Zone 分区推荐<br/>T-FED-15双区独立候选"]:::consume
IP10["ip 据 Zone 双轨归类<br/>T-IP-10"]:::consume
STU -.->|写入归属| PRJ07
PRJ07 -->|分区依据| FED15
PRJ07 -->|归类依据| IP10
end
classDef owner fill:#dcfce7,stroke:#16a34a,stroke-width:2px;
classDef raw fill:#eff6ff,stroke:#2563eb,stroke-width:1.5px;
classDef consume fill:#f1f5f9,stroke:#475569,stroke-width:1.5px;
```
这张图最该让人看出的是「owner 模式怎么消灭灰色地带」:锁风门由 compliance 当 owner因为它是全平台的内容安全与裁决中枢但它**不自产**风格检测原子——原料来自 aigc 和 ip裁决挂到 project三方各司其职、没有谁越界。这正是图 5 模块依赖里那条 compliance ↔ ip ↔ aigc 环路的真实含义。要按状态读的设计缝有一处:**专区 Zone 在 MVP 阶段还没有独立的数据库实体,是用字段承载的**(有意简化),所以图里 Zone 实体那一格画的是「逻辑归属」、不是一张独立表——这是 project 模块已知的、有意为之的缺口不是设计漏洞。锁风门则有一处真实的合规债虽不在本概念图的范围内、但读图时该知道compliance 的核心检测原子目前全是桩、恒返回 pass意味着锁风门框架虽真、自动拦截能力还没硬化这是放量/接广告/上渠道前必须补的。
---
## 3. 图清单与状态表
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 六层技术分层 | 架 | 引(链 README §1 | 现 | 接入→网关→业务→基座→AI→中间件 + 旁路可观测先简后扩取向Nacos/RocketMQ = future-state 未部署 |
| 2 | 关键选型决策树 | 讲 | SVG新 | **现+史** | 框架(Huijing)/生成两线(廉价 new-api+SAA ‖ tier2 AgentScope)/引擎分轴(LittleJS ‖ Phaser/Pixi ‖ Cocos 收窄 3D+渠道导出)/素材(mmx-cli) 四选定击败谁;废弃候选 Dify/OpenGame/自研壳作决策史Cocos=收窄非废弃 |
| 3 | 生成主线 现行 vs 决策史 | 流 | 引(链 README §2.2 | **现+废** | 现行 SAA+LittleJS 廉价线 16 节点链路 vs 蓝图原案 Dify/OpenGame终态产物=src 源项目gameDefinition JSON 为中间脚手架·迁移中);两条生成线边界 + tier2 远期可能收敛入 AgentScope |
| 4 | 13 模块聚类 | 架 | 引(链 README §3 | 现 | 四簇 13 模块 + T-id 注册表;结构权威 vs「状态>实现>结构」口径 |
| 5 | 13 模块单向依赖 | 架 | 引(链 README §4 | 现 | 单向 -api 依赖四主线telemetry↔feed 唯一双向边;依赖方向=未来微服务切割线 |
| 6 | 一条生成请求时序 | 时 | 引(链 README §5 | 现 | 202+taskId 异步派发 + SAA 编排 + 九门 + 回调写库dispatcher 契约可替换 |
| 7 | 生成任务状态机 | 状 | 引(链 README §5 | 现 | QUEUED→RUNNING→SUCCEEDED/FAILED/TIMED_OUT + 重试/取消成功率≥80%/积压500/429 |
| 8 | 游戏安全运行时序 | 时 | 引(链 README §6 | 现 | manifest 校验→iframe+CSP→注入 SDK→三容器allow-same-origin/CSP/产物消毒三红线 |
| 9 | 推荐打分公式 | 讲 | SVG新 | 现 | Score 正负信号加权 + 调节项 + Redis 候选集error_rate 硬降权;飞轮回路;候选集/游标桩现实形态 |
| 10 | 工程治理(幂等/SLO/可观测) | 讲 | SVG新 | 现 | 幂等矩阵 + 三服务 SLO/Error Budget + 四路可观测(落地态=接)+ 三关键技术风险及应对 |
| 11 | 8+2 类契约族总览 | 架 | SVG新 | 现 | 三落点 + 主编号轴;诚实标出 5 缝DB 漂移/CI 门缺位/Dify#6 废/第9契约五套相撞/agent-loop+templates 漏登 |
| 12 | 专区 Zone + 锁风门 Gate | 讲 | Mer新内联 | 现 | 两横切概念 owner 与聚合Gate=compliance 聚合 AGC19+IP04 挂 PRJ05Zone=project ownerZone 无独立实体(字段承载) |
> **状态分布**:现 ×10、现+史 ×1图 2决策史对照、现+废 ×1图 3含废弃蓝图。**注**:图 2/3 的「史/废」指其中**并列的决策史/废弃候选**部分Dify/OpenGame/自研壳),现行选定部分仍是「现」;图 9/10/11 虽整体「现」,但各含一处必须按状态读的缝(候选集桩 / 可观测落地=接 / 5 处契约现实缝),已在散文与图内标清。**防漂移门**:本图说 frontmatter 记三份源档的 commit hashREADME/契约总览 @ 38357c3d、13模块 @ 7ecd616e源档变更即比对hash 对不上则本图说与对应 SVG 标「待复核」。
>
> **PNG 后续**12 张图中 4 张为 SVG图 2/9/10/11SVG 入仓后在 mini-desktop 批量转 PNG6c6g 禁 chrome1 张 Mermaid图 12GitHub 直接渲染、无需转换7 张(图 1/3/4/5/6/7/8单源引用 README 已有 Mermaid、不产新图。

View File

@ -2,22 +2,22 @@
date: 2026-06-22
topic: 系统全图说——绘境AI 架构图集的单一全量主档(总图 + 目录 + 全部图说 inline 在一篇,所有图经顶层相对路径引用故全部真渲染),取代原导览式 系统全景图说.md 与分散各域图说
status: 单一全量主档(系统级 7 图 + 七领域全部图说 inline)· 跨多档,frontmatter 记全部源档的 commit hash · 防漂移门
映射源档(8 份图说):
- docs/architecture/系统全景图说.md @ f9d6baa5
- docs/architecture/产品/产品图说.md @ 7fff6518
- docs/architecture/架构/架构图说.md @ 7fff6518
- docs/architecture/架构/产物执行沙箱图说.md @ 7fff6518
- docs/architecture/后端/后端图说.md @ 7fff6518
- docs/architecture/前端/前端图说.md @ 7fff6518
- docs/architecture/运营/运营图说.md @ 7fff6518
- docs/architecture/运维/运维图说.md @ 891a5777
映射源档(6 份 README · 引图 Mermaid 来源):
映射源档(本文据各域设计档可视化而来;每图的具体映射见正文该图脚注 / 内联小注):
- docs/architecture/产品/README.md @ 366a44b4
- docs/architecture/架构/README.md @ 38357c3d
- docs/architecture/架构/README.md @ ae7d78dd
- docs/architecture/后端/README.md @ 38357c3d
- docs/architecture/前端/README.md @ 15b707fd
- docs/architecture/运营/README.md @ 3e71715a
- docs/architecture/运维/README.md @ 15b707fd
- docs/architecture/架构/13模块.md @ 7ecd616e
- docs/architecture/架构/契约总览.md @ 38357c3d
- docs/architecture/架构/产物执行沙箱.md @ ae7d78dd
- docs/architecture/后端/数据模型.md @ 38357c3d
- docs/architecture/后端/鉴权与权限.md @ 38357c3d
- docs/architecture/运维/观测体系.md @ 3e71715a
- docs/architecture/运维/k8s迁移.md @ 15b707fd
- docs/architecture/架构/生成引擎/README.md @ 37f5eddb
# 产品/运营 的细分设计档(需求清单·需求模块映射·商业定位·护城河话术 / 变现与单位经济·变现端到端·渠道发行·合规闸门·审核台运营)经各域 README 导航,具体映射见各图脚注
---
# 系统全图说
@ -1718,4 +1718,4 @@ flowchart LR
---
> **全文防漂移门汇总**:本文 frontmatter 记了全部 8 份图说源档(系统全景图说 @ f9d6baa5、产品/架构/产物执行沙箱/后端/前端/运营 6 份图说 @ 7fff6518、运维图说 @ 891a5777)+ 6 份 README(引图 Mermaid 来源:产品 @ 366a44b4、架构 @ 38357c3d、后端 @ 38357c3d、前端 @ 15b707fd、运营 @ 3e71715a、运维 @ 15b707fd)的 commit hash;任一源档变更、hash 对不上,本文与对应 SVG 即标「待复核」,由收口脚本比对。**SVG 不动**:本文不动任何 SVG 文件,只经顶层相对路径引用它们;PNG 后续在 mini-desktop 批量转(6c6g 禁 chrome),Mermaid 图 GitHub 直接渲染、无需转换。
> **全文防漂移门汇总**:本文 frontmatter 记了各域设计档(6 域 README + 架构 13模块/契约总览/产物执行沙箱、后端 数据模型/鉴权与权限、运维 观测体系/k8s迁移、生成引擎 README 等)的 commit hash;每图的具体映射源档另见正文该图脚注 / 内联小注。任一源档变更、hash 对不上,本文与对应图即标「待复核」,由收口脚本比对。**SVG 不动**:本文不动任何 SVG 文件,只经顶层相对路径引用它们;PNG 后续在 mini-desktop 批量转(6c6g 禁 chrome),Mermaid 图 GitHub 直接渲染、无需转换。

View File

@ -1,247 +0,0 @@
---
date: 2026-06-22
topic: 系统全景图说——绘境AI 架构图集的顶层总图叙(导览式 apex):读它一遍即建立全局认知,并据它下钻到任一领域、据图 review 全局设计有没有缝
status: 现行为主(系统级 7 图 + 七领域导航)· 跨多档,frontmatter 记主要几份源档的 commit hash · 防漂移门
映射源档:
- docs/architecture/README.md @ ec7fda2c
- docs/architecture/架构/README.md @ 38357c3d
- docs/architecture/产品/README.md @ 366a44b4
- docs/architecture/运营/README.md @ 3e71715a
- docs/architecture/运维/README.md @ 15b707fd
- docs/architecture/后端/数据模型.md @ 38357c3d
- docs/architecture/后端/鉴权与权限.md @ 38357c3d
- docs/architecture/架构/契约总览.md @ 38357c3d
- docs/architecture/架构/生成引擎/README.md @ 37f5eddb
---
# 系统全景图说
> **这是什么**:绘境AI 架构图集的**顶层总图叙**,整套图集的 apex。它的目标只有一个——让一个人**读它一遍**(看图加讲解)就建立起对整个系统的全局认知:这是个什么系统、分几层、有几条生成轨、数据怎么流、钱怎么转;读完之后,既能据它**下钻**到任意一个领域的图说去看细节,也能据它**做全局 review**,发现现行与远期的边界、跨域的裂缝、失败路径有没有兜住。
>
> **它不是什么**:它不是把全图集一百多张图都塞进来的"大杂烩"。它只内联**系统级、跨域、没有任何单个领域拥有**的那几张新图,然后对七个领域各写一段导览散文,把人领到对应的领域图说门口。领域已经画过的图(产品闭环、13 模块依赖、生成请求时序、全平台 ER、契约现状、护城河、部署拓扑、生成引擎深度)在这里**一律只链接、不重画**——同一张图绝不在两处各存一份。
>
> **给谁看**:第一次接触这个项目、想先建立全局轮廓的任何人;要据图做全局架构评审、找设计缝的技术负责人;以及想知道"系统每一块在哪、各自的命门是什么"的产品、运营与投资尽调读者。
---
## 0. 阅读约定:这是什么、怎么读
**这份总图叙的形态,是"先定向、再下钻"。** 它分两段功能:第 2 章是**系统定向图集**,用七张系统级大图把整个系统的轮廓自顶向下讲清楚;第 3 章是**领域导航**,对七个领域各写一段散文,告诉你那个域的图在讲什么故事、最该据图 review 的关键设计缝在哪、链接到哪份图说。建议的读法是:**先把第 2 章七张图连讲解读完**(建立全局轮廓),**再按你的角色或当前任务,选第 3 章某一两个领域下钻**(第 4 章给了按角色推荐的路径)。读完第 2 章,你应该能回答"这是个什么系统、分几层、两条生成轨现行 vs 远期怎么切、数据怎么回流、钱怎么转";读完第 3 章对应段,你应该知道"这块的图在哪、它的命门是哪条缝"。
**单源纪律(本图集的硬约束)。** 这份图集要消灭的就是"同一张图存两处、改一处漏一处"的漂移面。所以本总图叙只**内联**第 2 章那七张系统级新图——它们都是跨域才画得出来、没有任何单个领域拥有的图。凡是某个领域已经画过的图,本文一律**只在散文里链接、不复制**:产品闭环全景在产品图说、13 模块依赖与一条生成请求时序在架构图说、全平台数据模型 ER 在后端图说(图 5,全仓唯一 ER 权威)、契约现状在架构图说(图 11)、四层护城河与三线变现在运营图说、部署拓扑与观测在运维图说、生成引擎的深度(SAA 16 节点拓扑、九门、tier2 详设)在生成引擎子树。本文的系统级图与领域图**互补、不重复**:领域图回答"这一块内部长什么样",系统级图回答"这些块如何跨域串成一个整体"。
**同步纪律 + 防漂移门。** 设计档一变动,本图说与对应 SVG 必须同步更新。系统级图跨多份源档,frontmatter 记了主要几份的当前 commit hash 作为防漂移门:源档一旦变更、hash 对不上,本图说与对应 SVG 即标"待复核",由收口脚本比对。每张 SVG 脚注都注明了它的映射源档与状态。
**现行 vs 远期 / 已废,严格标注。** 系统级图里凡涉及未来式或被推翻的方案,一律用虚线框 + 文字小标画出,与"现行已建"的实心块一眼区分。三类边界必须看清:**远期·待 spike**(tier2 富游戏自治轨 = AgentScope + Phaser,见图 3——只有设计、未落代码,绝不画成现行已建)、**future-state**(Nacos / RocketMQ 框架自带但 MVP 未部署、k3s 缓做、观测体系待接线、两条生成线远期可能收敛为一条)、**已废**(Dify / OpenGame 从未部署降远期、玩法填参式模板与 15KB 红线已废除)、**终态迁移中**(廉价线产物的终态定为 `src/` 源项目,现行的声明式 gameDefinition JSON 只是通往它的中间脚手架、正迁移成直接生成 `src/`)。把这些诚实画出,正是为了让据图 review 的人不会把演进中或已废的方案误当现行。
**产物形式。** 系统级 SVG 入仓(GitHub 与编辑器直接渲染矢量),PNG 在 mini-desktop 批量转(6c6g 禁 chrome、无转换器),本文只产 SVG 与本 md;角色×端那张是 Mermaid,GitHub 直接渲染、无需转换。
---
## 1. 全图通用图例
整套图集(含本总图叙)共用一套视觉约定,读任何一张图都按这套理解。
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上)。七个维度对应七种"这套设计在为什么负责":
- **安全**(`#dc2626`):iframe 沙箱 + CSP 红线、权限只在后端可信边界强制、打款 fail-fast 绝不发假钱、上游 API key 不裸暴露。
- **可观测**(`#0ea5e9`):四路信号(Metrics / Traces / Logs / Errors)+ SAA 节点 observation——但落地态是"接"(待接线),详见运维域。
- **可靠**(`#16a34a`):幂等矩阵、最终一致 + 补偿、SLO + Error Budget、多通道兜底——涉及外部模型 / 异步 / 支付,可靠性必须前置。
- **成本**(`#16a34a`):复用 Huijing 买现成后台、便宜模型直出、单 key 入计费台账、内网物理机不上云——都是"5 人小团队 + ¥4,300/月"跑起来的取舍。
- **数据**(`#475569`):契约即跨端数据边界、推荐用信号驱动排序、行为数据回流"越用越聪明"——数据口径对不对,是系统能不能闭环的根。
- **伸缩**(`#7c3aed`):单体平滑长成微服务、Redis 候选集适配无限流、声明式编排平滑长多节点。
- **质量**(`#15803d`):harness 九门兜底、三层约束框架、error_rate 硬降权保可玩底线——质量是设计进去的,不是 LLM 自评。
**复用 / 边界三线语义**:
- **实线**(`#334155`):现成直接用、同步动作、单向依赖或数据流的正向推进。
- **虚线**(`#64748b`,`stroke-dasharray="6 4"`):自建 / 解耦 / 远期 / 待接线 / 决策史的目标态或对照态;远期·待建项用紫色 `#7c3aed`,失败 / 资金红线分支用红色 `#dc2626`
- **双线 / 加粗框**:跨域共享的公共件,或需要强调的硬边界(如两条生成轨唯一交汇的公共件、资金硬边界)。
**状态码**(贯穿全图集):**现** = 现行已建 / 已实测 · **接** = 现行待接线(设计已出、代码未接) · **建** = 待建 · **缓** = 缓做(排在 W-G1 之后) · **F / future** = future-state(框架自带未部署 / 远期轨) · **废** = 决策史对照(被推翻的旧方案)。系统级图里,凡远期 / 待接 / 缓做 / 已废的元素一律虚线框 + 小标,绝不画成现行。
---
## 2. 系统定向图集
下面七张图是这份总图叙的核心。它们都是**跨域才画得出、没有任何单个领域拥有**的系统级图。按"先看全局形状、再看两条生成轨、再看数据与钱与可靠性与边界"的顺序读下来,就能自顶向下建立对整个系统的认知。
### 图 1 · 六域生命周期全景SVG·架·现
![图 1 六域生命周期全景](assets/01-六域生命周期全景.svg)
这张图回答最顶层的问题:**绘境AI 是个什么系统,它的六个领域如何串成一条主线**。设计文档按产品生命周期的六个领域组织——产品(用户要给谁、给什么)、架构(用什么技术、怎么搭)、后端与前端(并列的实现层,同受架构约束)、运营(合规上线、变现、发行)、运维(部署、健康、可用性)。这六域不是六个互不相干的孤岛,而是一条**接力链**:产品定义出"做什么",架构据此定"怎么搭",前后端把它实现出来,运营让它合规变现,运维让它持续跑得住。
读这张图要抓住三件事。其一,**它是一条闭环、不是六个孤岛**——判断"系统有没有缝",就是看相邻两域的交接处对不对得上;一个具体的例子是后端定义的五条业务链(创作 / 发布 / 试玩 / 广告收益 / 数据回路)恰好就是运维冒烟门按链分组点检的那五条,两域在这个接口上必须严丝合缝。其二,**它不是瀑布,是带回流的循环**——图上方那条贯穿全宽的大虚线,是玩家行为加收益数据回流、反哺产品优先级与生成质量的飞轮;正是这条回流把一条线性的价值链弯成了一个循环,也正是数据与网络效应护城河的来源(它的机制细节在图 4 展开)。其三,**单源纪律**——本图只画"六域如何串成一条生命周期",六域各自内部的图都在各自的图说里,本系统图绝不重画任何一张领域已有的图。看完这张图,你就知道了整个系统的骨架和"每一块在哪";接下来六张图把这条骨架的关键段一段段放大。
### 图 2 · 六层技术分层总图SVG·架·现 + F
![图 2 六层技术分层总图](assets/02-六层技术分层总图.svg)
这张图回答"这套系统在技术上**怎么搭起来、分几层**"——是系统级的权威分层视图。一个用户从浏览器进来,自上而下穿过六层:**接入层**(CDN / Nginx)→ **前端应用**(studio + admin)→ **网关层**(Spring Cloud Gateway,MVP 下软转发)→ **业务服务层**(13 个游戏业务模块,jar 聚合进 Huijing 单体)→ **基础设施层**(Huijing 原生的 system / infra / bpm,开箱即用)与并列的 **AI 生成层**(SAA 编排 → new-api → 便宜 LLM → 九门,配 LittleJS 引擎)→ 最底的**中间件层**(MySQL / Redis / MinIO);整套之外,一条**旁路可观测层**横向监控。
这张图最该让人抓住的,是它那条贯穿始终的设计取向:**先简后扩、能复用就不自研**。后端复用 Huijing 现成的 60% 后台能力、生成不自研大模型而接通用模型、引擎不自研而用成熟的 LittleJS——正是这条取向让系统能用很小的团队和很低的成本跑起来。同时有两处状态边界必须按标注读、绝不能误当现行已建:**其一,中间件层的 Nacos / RocketMQ 是框架自带、MVP 未部署**(图上虚线 + 「future」),所以凡涉及"异步 MQ""服务注册发现"的设计,在 MVP 阶段都按"进程内调用 / 本地配置"折算;**其二,整条旁路可观测层整体是"接"(待接线)**——唯一已就位的实心块是 SAA 节点 observation,其余 OTel 采集、Prometheus、Grafana、夜莺、admin 观测入口全部待接,落地全貌见运维图说图 6。这张图给的是空间感:看"某块技术落在哪一层、它现行还是 future"用它;看某一层内部的细节(13 模块怎么聚类、生成层怎么编排)去对应领域图说。
### 图 3 · 现行 SAA 廉价线 ‖ 远期 tier2 自治轨 边界SVG·架·现 + F
![图 3 现行 SAA 廉价线 ‖ 远期 tier2 自治轨 边界](assets/03-两条生成轨边界.svg)
这张图是看清"生成引擎现行 vs 远期"的**总闸**,也是本总图叙最该守状态纪律的一张。绘境AI 有两条生成轨:**左轨是现行的 SAA 廉价线**——已实测合入主干,承载超休闲档(打砖块 / 合成 / 挂机 / 答题 / 网格点选),一条流水线从"创作者一句话"经 SAA 裸图编排(Java·16 节点)、new-api 网关、便宜 LLM、harness 九门兜底,到 emit 出包,用 LittleJS 当引擎、产物是一份可维护的 `src/` 源项目;**右轨是远期的 tier2 富游戏自治轨**——待 0 号 spike、未落代码,承载 premium 富游戏(经营 / 合成 / 多系统富交互),走的是与左轨正交的另一套范式:AgentScope(Python)的自治 ReAct agent、作为一个独立 service 跑、用 Phaser / Pixi 全无头引擎、靠三层校验当确定性地板加人工终审兜底,产物是 Phaser 的 `src/` 源工程。两轨**只经公共件交汇**:计费平面、送审 + feed、验收基线 + 执行沙箱、控制 / 管理面治理层。两轨**远期有可能收敛为一条**——把左轨的 SAA + LittleJS 也并入 AgentScope 自治范式(登记为未来方向,当前不做)。
读这张图,**最要紧的是把左轨的实心和右轨的紫色虚线分清**:左轨是"现行已建",右轨是"远期·待 spike",图上用虚线框 + 「远期·待 spike」标死,绝不能因为画出来了就误以为 tier2 已经在跑。还有三层意思必须读到。其一,**左轨的现行真实状态要诚实说清**:骨架立住、控制流确定、九门很硬已合入主干,但生成质量尚未稳定到 80% 门(便宜模型天花板,实测约 60%)、一部分策略被焊进机制代码;范式侧的终态产物定为可维护的 `src/` 源项目(改源不改包),现行 generate 产出的 gameDefinition JSON 只是通往它的中间脚手架、产线正把它迁成直接生成 `src/`(仍在落地,以生成引擎子树最新裁定为准);默认产线切换交 W-G1 把质量做到 80%(dispatcher flag 已存在,一行 flip)。其二,**为什么两轨不合并**:左轨声明式有向图与右轨命令式循环是两种正交范式,硬塞就成项目明令反对的"缝合设计",而且对卡 80% 门,图的确定性本就比口头督促更稳。其三,**它们的唯一交汇面是公共件**——tier2 换的是"游戏内容怎么造出来",换不掉"造出来之后怎么被关进笼子跑、怎么计费、怎么送审发行"。生成引擎的深度(SAA 16 节点拓扑、加节点法、救场阶梯、引擎运行时、tier2 详设)在生成引擎子树,本图只画两轨硬边界。
### 图 4 · 跨域数据流(越用越聪明)SVG·流·现
![图 4 跨域数据流(越用越聪明)](assets/04-跨域数据飞轮.svg)
这张图把图 1 那条"回流大虚线"放大,回答"平台**靠什么越用越聪明**"。它是一条数据飞轮回路:玩家在 feed 玩、互动(①)→ 游戏内 SDK 埋点上报(②)→ telemetry 入库聚合(③,逐事件 uk_event_id 幂等防重)→ 算出 0100 的质量分(④)→ 进推荐打分公式与 Redis 候选集(⑤)→ feed 重排下发(⑥)→ 回到①,玩家刷到更好的游戏。这条回路转一圈,好游戏自然浮上来、差游戏沉下去,数据回流持续校准推荐。
这张图最该让人看清的有三点。其一,**error_rate 是唯一的"硬"降权**——技术上跑不动的游戏直接沉底,这条把"好不好玩"之前先卡住"能不能玩",是可玩性底线。其二,**这条回路就是护城河第一层**——它是数据壁垒加网络效应的产品载体:真实流量积累出来的质量信号无法购买,飞轮转起后追赶成本指数级增长;竞品做生成工具止步于出包,没有这条回流就不"越用越聪明"。其三,**有两处现状要诚实标**:候选集当前可直查 MySQL、Redis 是增长期形态,游标分页目前是桩(永远返回第一页)——公式和飞轮是设计真相,落地仍是增长期的事;而飞轮的第二半(收益 / 留存数据回流成训练语料、反哺生成质量)是远期·待建,现行只覆盖了生成侧自增强这一半,图上用虚线把它和现行回路分开。这张图与图 1 是一对:图 1 点出"有这么一条回流",图 4 把回流的每一站和它的现状画清。
### 图 5 · 失败 / 降级 / 补偿路径全景SVG·流·现
![图 5 失败 / 降级 / 补偿路径全景](assets/05-失败降级补偿全景.svg)
这张图是**据图做评审最容易发现"缝"的一张**。它横切三类不可控调用——外部模型(链路 A)、异步任务 / 跨表(链路 B)、支付 / 打款(链路 C)——把"超时 → 失败 → 重试 → 幂等 → 补偿 → 兜底"这条可靠性主线集中画出来。链路 A 给生成调便宜 LLM 的全路径:超时 120s、状态机显式建 FAILED / TIMED_OUT 边、重试加 repair→escalate 救场阶梯、idempotency_key 去重、giveup 留证据,并标出 2026-06 已真实发生的"二厂系通道全废 → new-api 多通道兜底"。链路 B 给异步与跨表:最终一致 + 补偿(非分布式事务)、唯一一处真原子发布(project 把合规裁决 + 出包 + 入流串成事务)、补偿 job 兜底、幂等四范式。链路 C 给钱的事:账户恒等式永远成立、"发起 ≠ 终态"、双路驱动 + CAS、对账锚点链。
这张图最该让人记住的,是底部那条**关键反差**:打款的降级口径与生成 / 广告**正好相反**——广告渠道缺失降级 mock 可接受(少算收入),但打款渠道缺失若降级 mock 就是吞真钱,必须 fail-fast、绝不发假钱;审核降级则一律朝保守(阿里云超时降到 review、绝不降到 pass)。图底那张"据图 review 的六条检查清单"是这张系统级图存在的意义:每个外部 / 异步 / 资金动作是否都有幂等键、失败是否在状态机里显式建边、补偿 job 是否扫得到、降级方向对不对、抽象是否做对(mock ↔ 真实现可零改业务码切换)、对账锚点链是否端到端串得起来——凡有一格答不上,就是一处可靠性裂缝,据图就能定位,不必逐文件翻。图上也诚实标了打款 mock 桩、订阅自助购买被支付闸门阻塞这些现状缺口。
### 图 6 · 端到端鉴权信任边界总图SVG·架·现
![图 6 端到端鉴权信任边界总图](assets/06-鉴权信任边界总图.svg)
这张图回答"权限在系统的**哪一层、挡什么**",是系统级的信任边界视图。一个请求从前端经网关到业务,三层各管一段:**① 前端**的路由守卫只改善体验(anon_id 让 Feed / Play / Share 匿名可达、即刷即玩不挡门),但它挡不住直连 API——前端守卫形同虚设,任何"前端藏了按钮就安全"的想法都击穿信任;**② 网关**在 MVP 单体下只做软转发(剥除外部伪造的 login-user 头、有 token 才注入可信头、无 token 也放行),它本身没有路径级 RBAC,所谓"网关双重校验"是微服务拆分后的未来态;**③ 业务服务 huijing-server 是权限的唯一真强制点**——TokenAuthenticationFilter 校验 token 的 userType 与 URL 前缀一致,然后 B 端走声明式 RBAC(@PreAuthorize + 角色菜单交集)、C 端走 Service 归属隔离(eq 谓词把当前用户钉进 WHERE),再叠一层创作白名单(A2 内测准入)和匿名读三纪律。
这张图与后端图说图 7 是**互补、不重复**的:后端图 7 是模块类图(讲两套权限模型在代码里的类与方法),本图是**系统边界**(讲前端→网关→业务三层各挡什么、职责怎么切分)。它最该让人看清的,是那条贯穿全图的铁律——**权限只在后端可信边界强制,前端拦截一律不算数**;以及职责切分的本质:网关做"身份可信化"(把不可信外部头换成可信内部头),但绝不替代服务侧的权限判定,两者是接力、不是冗余。anon_id 让玩家免登消费,但创作 / 写域必须越过后端这道墙。图上还诚实标了一处现状:控制器注释里"网关 + 服务端双重校验"是未来态,当前单体下网关甚至不在请求路径上,权限强制 100% 在服务侧单点;mock 后门是 staging 现状、生产必须关死的红线。
### 图 7 · 角色 × 端全景Mermaid·讲·现
这张图回答"**谁在哪个端做什么**"。绘境AI 把"用户"收敛成六种角色,分布在两个前端(C 端 studio / B 端 admin)上;最容易混的一对是"经营"和"运营"——**经营 = 创作者看自己作品的数据**(留存 / 完玩 / 广告转化),**运营 = 平台管理员**(审核 / 精选 / 封禁 / 经营看板),两者在需求清单里分属不同的域(OPS vs OPN),混了就会把功能归错端。
```mermaid
flowchart TB
subgraph C端["C 端 · game-studio(Vue3 + Vant)"]
direction LR
CR["创作者<br/>一句话生成 / 预览迭代<br/>发布 / 看收益(经营)"]:::role
PL["玩家<br/>刷 feed 即点即玩<br/>点赞分享 / 发起同款"]:::role
CB["B 端客户(询单侧)<br/>提需求 / 看 demo / 验收"]:::roleb
end
subgraph B端["B 端 · game-admin(Vue3 + Element Plus)"]
direction LR
OPN["运营(平台管理员)<br/>内容审核 / 精选推荐<br/>封禁处置 / 经营看板"]:::roled
ADM["管理员<br/>用户管理 / 权限角色<br/>合规处置 / 数据看板"]:::roled
BD["商务 / BD<br/>B 端定制单据流转<br/>报价 / 进度 / 交付"]:::roled
end
COM["通用(任意端可触)<br/>账号 / 登录 / 消息通知 / 政策页 / 申诉"]:::common
CR -->|产出可玩游戏| PL
PL -.->|发起同款 → 变创作者(P-FED-12)| CR
CB -.->|线索 → 单据| BD
OPN -.->|审核 / 降权联动| PL
ADM -.->|白名单置位 set-creator| CR
C端 --- COM
B端 --- COM
classDef role fill:#eff6ff,stroke:#2563eb,stroke-width:2px;
classDef roleb fill:#f5f3ff,stroke:#7c3aed,stroke-width:1.6px;
classDef roled fill:#fefce8,stroke:#ca8a04,stroke-width:2px;
classDef common fill:#f1f5f9,stroke:#475569,stroke-width:1.6px;
```
这张图最该让人看出的,是**两条跨角色的转化回路**:一条是玩家"发起同款"跳转工作坊变成创作者(P-FED-12)——它把"玩游戏的人"转化成"做游戏的人",是网络效应护城河的产品载体;另一条是 B 端客户的询单经商务 / BD 流转成定制单据。还有一处系统级衔接:运营对内容的审核 / 降权处置会联动 feed 曝光(影响玩家看到什么),管理员对创作者的白名单置位(set-creator)决定一个 C 端用户能不能创作——这两条"B 端动作影响 C 端体验"的链路,正是图 6 那条"权限在后端强制"与图 4 那条"feed 重排"的人侧投影。这张图没有现行 / 远期的灰度,它是当前的角色与端的真相;每个角色的完整旅程(创作者旅程、玩家旅程)在产品图说,每个端的视图地图在前端图说。
---
## 3. 领域导航(本 apex 的心脏)
读完第 2 章,你已经有了全局轮廓。这一章把你领到七个领域的门口:每一段告诉你**这个域的图在讲什么故事、最该据图 review 的关键设计缝是哪条、链接到哪份图说**。读完这七段,你就知道了全局每一块在哪、各自的命门是什么。
### ① 产品域 → [产品图说](产品/产品图说.md)
**讲什么故事**:产品域只回答一件事——这个产品对用户提供什么(WHAT),不碰"用什么技术实现"。它的九张图从最顶层的"做得出 → 有人玩 → 赚到钱"闭环讲起,展开成 19 个产品域归拢的五大块(创作 / 玩家 / 变现 / 成长 / 平台),讲清 155 条需求怎样收敛成 55 条 P0(MVP 验收口径)、产品需求与技术模块之间那张唯一的多对多映射矩阵(RTM),再落到创作者与玩家两条旅程,最后到商业定位与护城河。读完这个域,你知道"这个产品到底要给谁、给什么"。
**最该据图 review 的设计缝**:产品域是**定义层、不是建设层**——它描述"产品要提供什么",不是"代码建到了哪一步"。所以评审时最该盯两处诚实纪律:**第一,产品定义 ≠ 建设进度**——55 条 P0 是验收口径,不等于今天都真端到端,真实完成度以需求模块映射的现状快照与 MVP 进度总账为准;**第二,护城河话术的红线是"不假装有墙"**(图 9)——四层护城河是要在窗口期点燃的、不是已有的,任何把飞轮 / 网络效应画成"已有的墙"都击穿信任;以及第二条生成轨(tier2)在 19 域里是 future,未落代码、尚无正式 P-id,绝不能画成 MVP 范围。
### ② 架构域 → [架构图说](架构/架构图说.md)+ 生成引擎子树,见下文⑦)
**讲什么故事**:架构域回答 HOW——这套系统用什么技术、怎么搭。它的十二张图讲清六层分层、那四项最关键选型为什么选 A 不选 B、13 个后端模块各管什么又怎么单向依赖、一条"一句话生成游戏"的请求怎么异步跑通、生成任务状态机怎么管超时 / 失败 / 重试 / 取消、游戏怎么安全跑在玩家面前、推荐打分公式、工程治理(幂等 / SLO / 可观测)、以及那张**最该据图评审的契约族总览**。读完这个域,你知道"这套架构是不是想要的那个、哪里有设计缝"。
**最该据图 review 的设计缝**:架构域评审的命门在**图 11 契约族总览(声明 vs 现实)**——它不只画理想的"应该怎样",更如实标出五处已经漂掉的地方:DB 镜像已漂移(contracts 只含 18 个迁移、执行副本有 25 个)、CI 防漂移门缺位(文档写了四道闸、代码里全仓唯一 CI 永不触发)、Dify #6 契约已废、"第 9 契约"五套编号相撞、agent-loop / templates 在 README 目录图漏登。这五处是"声明与代码不符"的待决策位,据图就能揪。另两处状态纪律:图 2 / 图 3 里被推翻的 Dify / OpenGame / 自研壳是**决策史**(理解"为什么现在是这样",别误当现行),图 10 的四路可观测落地态是**接**(设计意图真、后端真接上大半还没做)。
### ③ 后端域 → [后端图说](后端/后端图说.md)
**讲什么故事**:后端域回答服务实现视角的几件事——13 个业务模块在工程上怎么摆(两段式 -api / -server、包名自动套端前缀、错误码分段)、全平台数据长什么样、怎么跨域连、以及"谁能做什么"这条鉴权约束在代码里如何强制。它的八张图里,图 5 是**全仓唯一的 ER 权威**(据 Flyway V1V25 真实落库的约 40 张表画出五条业务链),图 6 是五条业务链路的跨模块调用,图 7 是鉴权双模型。读完这个域,你知道"这套后端结构是不是想要的那个"。
**最该据图 review 的设计缝**:后端域八张图整体都是"现"(已落代码、已 e2e 验证),但现行结构里仍有几处桩与缝必须照实看清——图 5 的 **contracts DB 镜像已漂移**(只读 contracts 会漏掉 aigc 的 level/trace 列、source_project 的并发幂等唯一键、feed 的 exposure_limit)、图 6 的 **compliance 检测原子恒返回 pass / feed 游标分页是桩 / 真广告联盟 SDK 是桩**(这些缺口的共同特点是逻辑已建、卡在不可压缩的日历闸门或 W-G1 质量门)、图 7 的**网关双重校验是未来态而非现状**。还有一条贯穿全域的设计意图最该让评审看出:**全图无物理外键**(归属靠 Service 可信边界的 eq 谓词、不靠 DB 约束),以及源(game_source_project)与产物(game_version)两个存储面解耦——"改源不改包"范式在数据层的落点。
### ④ 前端域 → [前端图说](前端/前端图说.md)
**讲什么故事**:前端域回答三件事——绘境AI 有哪两个前端各服务谁、它们靠一套什么设计体系撑起一致体验(token 两层 + 组件库四层、三条数据流、三大契约、主题切换防 FOUC)、以及生成出的游戏怎么在前端被真正地玩起来(真实试玩宿主)。它的九张图里八张是"现"(设计体系已全量收口合入主干),图 2 的 token 两层 + 组件库四层是整个前端域最核心的一张。读完这个域,你知道"这套前端方案是不是想要的那个"。
**最该据图 review 的设计缝**:前端域评审的命门在**图 8 真实试玩宿主**——它是 studio 比 demo 多出来的护城河命门,但必须看清"机制建成 ≠ 合规收口":iframe 的 CSP、sandbox 属性、sha256 校验这套机制都已建成真跑通过,但整套现在跑在**同源过渡态**(同源 srcdoc + allow-same-origin),还有三处真实债——CSP 文档口径与代码对不上、sandbox 属性三处不一致、后端下发的 sandboxAttr 前端根本没接线,收敛方向(迁独立 usercontent 子域、CSP 改 HTTP 响应头下发、sandboxAttr 真接线)必须一起做才闭合,权威细节在沙箱图说与产物执行沙箱.md §8。另一处状态边界:图 9 的 **tier2 富游戏前端承载**整图是"建"(归属已定但代码未建),钉归属、不预先设计,绝不画成已建。
### ⑤ 产物执行沙箱(架构域子主题)→ [产物执行沙箱图说](架构/产物执行沙箱图说.md)
**讲什么故事**:沙箱图说回答一个被独立成档的硬问题——**一款 AI 生成的不可信游戏代码,怎么在玩家浏览器里被隔离着安全跑起来**。生成主线已从"禁代码、填参数"迁到"让 agent 写码",注入面就是模型现写的 JavaScript 本体,平台必须把每一款生成游戏当成有恶意、有 bug 的不可信输入。它的七张图讲清三层封堵(build 段静态扫描 / iframe + CSP / sandbox 属性)、取包 sha256 校验注入时序、postMessage 双向桥双校验、SDK 受控能力面、两条正交边界、CSP / 同源红线 / 产物消毒、三容器加载 / 失败 / 销毁态机。读完这个域,你知道"这套隔离方案是不是想要的那个"。
**最该据图 review 的设计缝**:沙箱域评审最该守的纪律点是"**别把机制已建当成已经安全**"——iframe、桥、双校验、sha256 这套都真跑通过了,但它现在跑在同源过渡态,HJ-AUDIT-001 那条"独立源就绪前禁用 allow-same-origin"的红线在代码里并未强制,origin 白名单还含字符串 'null'。还有两条最该看清的概念边界:**两条信任边界正交、别混**(沙箱边界 = iframe 壳 vs 宿主、受控面 = 游戏代码 vs 引擎,受控面在沙箱里面、沙箱在受控面外面,破一条另一条仍兜);以及 **'unsafe-eval' 看着危险但风险被纵深防御承接住了、不是漏洞**(逻辑串先经 build 段静态扫描、再加 connect-src 'none' 无出网、再加 iframe sandbox 隔离);它是现行那套声明式 gameDefinition 运行时(用 `new Function` 编译逻辑串)的产物,而 gameDefinition 只是通往 `src/` 源项目终态的中间脚手架、产线正迁移中,这条 CSP 的收敛口径以沙箱图说/生成引擎子树的最新裁定为准。
### ⑥ 运营域 → [运营图说](运营/运营图说.md)
**讲什么故事**:运营域接在产品域与架构域之后,回答三件相互咬合的事——一款游戏被造出来之后,怎么合规上线、怎么把钱赚回来、怎么发行到各渠道。它的十一张图讲清 12+1 合规闸门的日历临界路径、合规死锁三环 + 双层定性破解、分账公式钱流(平台恒留 0.2N)、两平面两钱包三道硬边界、三线变现排序、四层护城河、发行双路线、一壳多游 L1 精选整包、变现端到端钱流地图、审核台双层审核。读完这个域,你知道"这套上线 / 变现 / 发行方案是不是想要的那个"。
**最该据图 review 的设计缝**:运营域十一张图整体都是"现"(已拍板的现行设计逻辑),但它的特殊之处在**元素级**——同一张图里常常一半是"已建真跑"、一半是"被合规日历闸门或外部资质阻塞、尚未接线 / mock / 留待后续波次"。评审最该盯的是这条纪律:**绝不能因为整图是现行设计,就把图里那些被阻塞的部分画成已建好**——变现侧的打款 mock 桩(降级即吞真钱、必须 fail-fast)、消费钱包未接、自助购买订阅被支付闸门阻塞;审核台的检测原子全是桩恒返回 pass(框架在、判定空、处置半通);渠道侧的备案锁(把"一壳多游"从灰区可行降级为高风险待律所裁)与引擎竞标 P1 段暂停。还有一处全局阻塞:8 项 C 端法定 P0 的换血边界要等律所对两核心问给出书面意见,这是仍卡着全局的最大未决项。
### ⑦ 生成引擎子树(架构域旗舰)→ [生成引擎子树](架构/生成引擎/README.md)
**讲什么故事**:生成引擎是绘境AI 护城河的关键路径,内容最厚、单独成一棵子树。它回答"一句话怎么变成一款可上线的游戏"这条技术主线:现行那台被刻意设计成可靠的、固定相位的生成机器(便宜模型驱动 + 确定性图编排约束控制流 + 九门 harness 兜底),以及它要往哪走的演进路线、贯穿全程的范式原则(游戏是长生命周期源项目、LLM 是它的工作室)。本总图叙的图 3 已给出"两条生成轨现行 vs 远期"的总闸轮廓,这棵子树是它的深度展开。
**最该据图 review 的设计缝**:生成引擎子树评审最该带着一条**范式定性**读——这套"便宜模型 + 受限 schema + 九门验收"是一条**为超休闲轻游戏(Tier0)量身打造的可靠产线,而不是一个通用生成范式**;它最大的风险不在工程层,而在被当成通用范式去对标 demo 里那一档富交互游戏(那一档结构性地够不着,必须显式分层、复杂品类另开一轨)。子树内现行结论可能随产线化 plan(把现行的 gameDefinition JSON 中间脚手架迁成直接生成 `src/` 源项目)的推进变化,以最新裁定为准。**跨 session 协调红线:生成引擎子树正被另一条 session 在飞建设,本总图叙对它只链接、不画其内部**——它的两簇(现行 SAA 廉价线 / 远期 tier2 自治轨)的逐张图、SAA 16 节点拓扑、九门逐门、tier2 详设都在子树内,本文不重复承载。
---
## 4. 按角色读:推荐下钻路径
读完第 2 章系统定向图、再按你的角色选第 3 章一两个领域下钻,是最省时的读法。下面给四类角色各推荐一条 23 份图说的路径。
- **产品 / 运营 / 投资人**:先读本文第 2 章图 1(六域生命周期)+ 图 4(数据飞轮)+ 图 7(角色×端),建立"这是个什么系统、靠什么越用越聪明"的轮廓;再下钻 [产品图说](产品/产品图说.md)(产品定义与护城河)→ [运营图说](运营/运营图说.md)(合规上线 / 变现 / 发行,尤其图 9 备案锁、图 10 钱流、图 11 审核台)。命门:护城河"不假装有墙"、变现被日历闸门阻塞的部分别当已建。
- **工程师(新加入)**:先读本文图 2(六层分层)+ 图 3(两条生成轨边界)+ 图 6(鉴权边界);再下钻 [架构图说](架构/架构图说.md)(尤其图 11 契约现状)→ 你负责的模块在 [后端图说](后端/后端图说.md)(图 5 ER + 图 6 五条业务链)→ 若做生成主线直接进 [生成引擎子树](架构/生成引擎/README.md)。命门:契约 DB 镜像漂移、网关双校验是未来态、桩与真要分清。
- **前端工程师**:先读本文图 6(鉴权信任边界,前端那一层挡不住直连)+ 图 7(角色×端);再下钻 [前端图说](前端/前端图说.md)(图 2 token 两层 + 组件库四层、图 8 真实试玩宿主)→ 跨到 [产物执行沙箱图说](架构/产物执行沙箱图说.md)(图 8 宿主侧的安全隔离纵深)。命门:试玩宿主"机制建成 ≠ 合规收口"、同源过渡态三债一起收。
- **安全 / 可靠性评审**:先读本文图 5(失败 / 降级 / 补偿全景,据图 review 六条检查清单)+ 图 6(鉴权信任边界);再下钻 [产物执行沙箱图说](架构/产物执行沙箱图说.md)(三层封堵 + 两条正交边界)→ [后端图说](后端/后端图说.md)图 7(鉴权双模型)→ [运营图说](运营/运营图说.md)图 10(打款 fail-fast)。命门:降级方向(可降 mock vs 必须 fail-fast)、权限只在后端可信边界强制、同源红线过渡态。
---
## 5. 图清单与状态表
**系统级 7 图**(本总图叙内联,跨域、无单域拥有):
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 六域生命周期全景 | 架 | SVG新 | 现 | 产品→架构→后端/前端→运营→运维 六域串成产品全生命周期 + 数据回流弯成环 + 单源纪律 |
| 2 | 六层技术分层总图 | 架 | SVG新 | 现 + F | 接入→网关→业务→基座→AI→中间件 + 旁路可观测(接);先简后扩取向;Nacos/RocketMQ=future |
| 3 | 现行 SAA 廉价线 ‖ 远期 tier2 自治轨 边界 | 架 | SVG新 | 现 + F | 两条生成轨硬边界:左=现行 SAA+LittleJS 廉价线(终态产 src 源项目·gameDefinition JSON 为中间脚手架迁移中) vs 右=远期 tier2 AgentScope+Phaser 自治轨(待 spike);只经公共件交汇;远期可能收敛为一条;深度链子树 |
| 4 | 跨域数据流(越用越聪明) | 流 | SVG新 | 现 | 埋点→telemetry 聚合→质量分→Redis 候选集→feed 重排→行为回流 飞轮;error_rate 硬降权;收益语料远期 |
| 5 | 失败/降级/补偿路径全景 | 流 | SVG新 | 现 | 横切外部模型/异步/支付:超时→失败→重试→幂等→补偿→兜底;打款 fail-fast 反差;六条 review 清单 |
| 6 | 端到端鉴权信任边界总图 | 架 | SVG新 | 现 | 前端→网关→业务 各层挡什么;anon_id 衔接;网关+业务双校验职责切分(双校验=未来态) |
| 7 | 角色 × 端全景 | 讲 | Mer新 | 现 | 创作者/玩家/经营/运营/B 端/通用 各在哪个端做什么;经营≠运营;两条跨角色转化回路 |
> **状态分布**:现 ×5、现 + F ×2(图 2 含 future-state 中间件与"接"可观测、图 3 含远期 tier2 轨)。系统级图与领域图**互补不重复**:本 7 图都是跨域才画得出、无单域拥有的图;领域已画的图(产品闭环、13 模块依赖、生成请求时序、全平台 ER=后端图 5、契约现状=架构图 11、护城河/三线变现=运营、部署/观测=运维、生成引擎深度=生成引擎子树)一律只在散文里链接、不重画。**远期/已废标注**:tier2 轨(图 3,= AgentScope+Phaser)= 远期·待 spike 虚线、远期可能与左轨收敛为一条;Nacos/RocketMQ(图 2)= future-state 未部署;观测(图 2)= 接;收益回流语料(图 4)= 远期·待建;打款 mock(图 5)= 现状桩;网关双校验(图 6)= 未来态;Dify/OpenGame/玩法填参模板/15KB = 已废;gameDefinition JSON 数据壳 = 中间脚手架·正迁移成直接生成 `src/` 源项目;均不画成现行终态。
**指向七领域图说的索引**(下钻入口):
| 领域 | 图说 | 一句话 + 命门 |
|---|---|---|
| ① 产品 | [产品图说](产品/产品图说.md) | 产品对用户提供什么(WHAT);命门=产品定义 ≠ 建设进度、护城河"不假装有墙" |
| ② 架构 | [架构图说](架构/架构图说.md) | 系统用什么技术怎么搭(HOW);命门=图 11 契约五处现实缝、决策史别当现行 |
| ③ 后端 | [后端图说](后端/后端图说.md) | 13 模块工程落地 + 数据 + 鉴权;命门=DB 镜像漂移、桩与真分清、全图无物理外键 |
| ④ 前端 | [前端图说](前端/前端图说.md) | 两前端设计体系 + 真实试玩;命门=试玩宿主机制建成 ≠ 合规收口、tier2 承载待建 |
| ⑤ 产物执行沙箱 | [产物执行沙箱图说](架构/产物执行沙箱图说.md) | 不可信代码怎么隔离着安全跑;命门=别把机制已建当已安全、两条正交边界别混 |
| ⑥ 运营 | [运营图说](运营/运营图说.md) | 合规上线/变现/发行;命门=元素级被阻塞的部分别画成已建、8 项法定 P0 待律所 |
| ⑦ 生成引擎子树 | [生成引擎子树](架构/生成引擎/README.md) | 一句话怎么变成可上线游戏;命门=Tier0 可靠产线非通用范式、子树在飞建设只链不画 |
> **防漂移门**:本图说 frontmatter 记九份主要源档的 commit hash(architecture/README @ ec7fda2c、架构/README @ 38357c3d、产品/README @ 366a44b4、运营/README @ 3e71715a、运维/README @ 15b707fd、后端/数据模型 @ 38357c3d、后端/鉴权与权限 @ 38357c3d、架构/契约总览 @ 38357c3d、生成引擎/README @ 37f5eddb),源档变更即比对,hash 对不上则本图说与对应 SVG 标"待复核"。
>
> **PNG 后续**:7 图中 6 张为 SVG(图 16),SVG 入仓后在 mini-desktop 批量转 PNG(6c6g 禁 chrome);1 张 Mermaid(图 7)GitHub 直接渲染、无需转换。

View File

@ -1,184 +0,0 @@
---
date: 2026-06-22
topic: 运维域图说——把「部署在哪、怎么变成在跑的服务、靠什么持续看见它」画成一套图 + 讲解(架构图集金样板·运维域首件)
status: 现行 + 待接(观测)+ 缓做k3s三态并存 · 防漂移门记源档 commit hash
映射源档:
- docs/architecture/运维/README.md @ 15b707fd
- docs/architecture/运维/观测体系.md @ 3e71715a
- docs/architecture/运维/k8s迁移.md @ 15b707fd
---
# 运维域图说
> **这是什么**绘境AI 运维域的「看图入口」。运维域回答三件事——这套系统**部署在哪些机器上**、代码**怎么从一行 commit 变成在运行的服务**、靠**什么确认它还活着并且活得够好**。这份图说把这三件事连同两件「设计已出但还没接上」的事线上观测体系、k3s 迁移),用一套图加配套讲解画清楚。复杂、跨机的用手绘 SVG 大图,简单、线性的用 Mermaid已有的图一律单源引用、不复制。
>
> **给谁看**:负责部署与值守的工程师、做发版的人、排查线上故障的人,以及关心可用性与运维成本的创始人。判断「这套运维方案是不是想要的那个」看这份图就够建立全局轮廓,逐字节的命令仍去 `deploy/` 脚本与 `.agents/skills/staging-ops.md`
---
## 0. 阅读约定与同步纪律
- **映射的设计档**:本图说不另立设计,只把运维域三份 canonical 设计档画出来——部署链与四机分工出自 [`运维/README.md`](README.md),线上观测体系出自 [`观测体系.md`](观测体系.md)k3s 迁移出自 [`k8s迁移.md`](k8s迁移.md)。frontmatter 里记了这三份的当前 commit hash作为**防漂移门**源档一旦变更、hash 对不上,这份图说与对应 SVG 即标「待复核」,由收口脚本比对。
- **同步纪律****设计一变动,本图说与对应 SVG 必须同步更新**,每张 SVG 脚注注明映射源档与状态。已并入 wave 收口清单。
- **三种状态贯穿全图,必须看清**:运维域的特殊之处是它同时承载「现行已建」「设计已出待接线」「收窄后缓做」三类内容,绝不能把后两类画成已建。图 6观测整体是**接**(待接线)、图 8k3s整体是**缓**(缓做、排在 W-G1 之后),其余六张是**现**。每张图内部还会用实心块 / 虚线框 + 「待接线」「缓做」小标把单个元素的状态再标一层。
- **产物形式**SVG 入仓GitHub 与编辑器直接渲染矢量PNG 在 mini-desktop 转6c6g 禁 chrome、无转换器。本图说只出 SVG。
## 1. 全图通用图例
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上,运维域主要关心其中四个):
- **可靠**`#16a34a`):隔离验证安全变体、备份 JAR 一键回滚、冒烟门退出码可卡口、观测旁路降级、k8s 共存保护与 rollout undo。
- **可观测**`#0ea5e9`OTel 统一采集、Grafana 三联下钻、夜莺告警必达——这是图 6 的主轴。
- **安全**`#dc2626`push 走 Gitea 中转scp/rsync 被分类器拦、Collector 集中脱敏、admin 观测入口权限守门不裸暴露后端。
- **成本**`#16a34a`):内网物理机 + 人工部署而非重 CI、不硬凑第二台机器上多节点、缓存命中率哨兵——都是 < ¥5,000/月成本盒子的取舍。
(另两个维度 **数据** `#475569`、**伸缩** `#7c3aed` 在 k3s 图上点到:声明式编排与平滑长成多节点 = 伸缩。)
**复用 / 边界三线语义**
- **实线**`#334155`):现成直接用、同步动作或命令。
- **虚线**`#64748b``stroke-dasharray="6 4"`):自建 / 解耦 / 回执 / 待接线 / 缓做的目标态。
- **双线 / 加粗框**:跨域共享的公共件或需要强调的边界。
> 运维域图说里,虚线还额外承担一层**状态语义**凡是「待接线」观测或「缓做」k3s的元素一律用虚线框 + 文字小标画出,与「现行已建」的实心块在视觉上一眼区分开。这是本域最该守的纪律点——观测体系和 k3s 迁移都是「设计已出、代码未接」,绝不能因为画得好看就让人误以为已经建好了。
---
## 2. 图集
### 图 1 · 四机分工拓扑〔引·现〕
> 单源引用,不复制:四机分工拓扑的 Mermaid 已在 **[运维/README.md §1.1](README.md#11-跑在哪里四台机器各司其职)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来——同一张图存两处、改一处漏一处,正是这份图集要消灭的漂移面。
这张图回答「服务跑在哪里」。绘境AI 在内网阶段刻意不上云托管、不上 Kubernetes而是用一组通过 Tailscale 连起来的物理机,按角色硬分工:**lili-mac** 是创作者本地工作站,跑开发主会话与快构建,但它会休眠合盖,所以不进 Tailscale 调度、也不承担任何「门」;**mini-desktop** 是权威验收机staging 全栈、重型构建、浏览器端到端测试都在这里,且与生产同构;**mini-infra** 是共享基建机Gitea / PostgreSQL / Redis / MinIO / new-api 都在这台,它绝不跑项目 app 或重型构建;**6c6g** 是常驻无人值守机跑常开的编排、定时任务、git 操作,但禁跑重活(重型前端构建会 OOM
读这张图要抓住一条最硬的边界:**Mac 是 ARM 架构,产出的 JAR 与前端产物架构中立可用,但 Docker 镜像与冒烟门必须在 x86 的 mini-desktop 出**,否则镜像架构与生产不同构,等于半假的门。这条边界在后面图 8k3s 迁移)里会再次出现并延伸——到了 k8s 时代,「进集群的镜像必须 mini-desktop x86 出」依然成立。这张图没有现行/远期的灰度它就是当前真相唯一的「设计缝」其实在别处——README §1.1 自己点明 mini-infra 上跑的关系型库是 PostgreSQL而 mini-desktop 上是隔离的 staging MySQL两者不是一回事端点口径以凭据 SoT《内网凭据与端点.md》为准别混。
### 图 2 · 部署链push → pull → 重建 → 验门SVG新·时序·现
![图 2 部署链 push→pull→重建→验门](assets/02-部署链时序.svg)
这张时序图回答「代码怎么变成在跑的服务」。它要先破除一个误解开发团队版文档里那套「push 触发 CI、自动构建镜像、滚动更新」是**目标态蓝图,与现实系统性脱节**(那份文档顶部自带审计横幅说明这点)。现行的部署没有 docker-compose、也没有自建 CI 流水线,而是**人工经标准序在 mini-desktop 上完成**——图里把它画成四条泳道之间的一串动作,并在底部用一个虚线框单独把这套蓝图标成「现实未建·勿当现状」,免得有人照着蓝图去找不存在的 CI。
核心三步在图上从左到右展开。**第一步同步代码**:代码经 `git push` 推到 Aliyun Gitea默认远程SSH `:2222`mini-desktop 再从同一个 Gitea 以匿名 HTTP `:3000` 拉取(注意是 HTTP 只读端口、不是 SSH。这里画出了两条已经踩过的坑直接 `scp / rsync` 源码树会被分类器拦下,所以必须走 Gitea 中转;大资产 push 在途时再发 push 会撞 Gitea 的 ref 锁,所以同仓 push 要串行。**第二步重建**:在 mini-desktop 上 `git reset --hard` 到目标分支、`mvn clean install` 出新的 fat JAR收口前**以字节码实证**新 JAR 确实含本次改动(曾因「构建源 ≠ 运行的 JAR」翻过车图上单画一格强调。**第三步验门**:重启后验 health 200、四模板就绪、Flyway up-to-date再跑冒烟门即图 4
整张图最该让人看出的,是中间那个橙色虚线框——**隔离验证安全变体**。高风险或整机变更不直接动 live而是先用新 JAR 在隔离端口 `:48090` 起一个实例验全,**live 的 `:48080` 全程不动**,验全过才切;任一步失败就用 `/tmp` 里的备份 JAR 把 `:48080` 恢复回去。这套「验全才切、失败即回」的安全变体是运维域可靠性的支点,后面图 8 把它原样平移到了 k8s 的隔离端口切换。图底还有一条红线值得记住:**API 全绿 ≠ UI 通**,编排器旁路会掩盖 UI 缺陷,用户可见波次收口前必须另做一次真浏览器 UI 走查。
### 图 3 · 隔离验证安全变体Mer新·流程·现
这张图把图 2 里那个橙框单独放大,讲清「为什么验全才切、失败怎么退」。它是一条状态/分支流程:新 JAR 不直接顶替 live而是先在隔离端口 `:48090` 起一个实例跑完整验证health、四模板、Flyway、冒烟门 12 项);只有**全部通过**才停旧实例、释放端口、把新实例切到 `:48080`**任一步失败,立即用 `/tmp` 备份 JAR 把 `:48080` 恢复**,回到改动前的形态,全程 live 不受影响。这条流程让一次高风险发版的下行风险被牢牢兜住——最坏情况也只是「白验一次、live 没动」,而不是「切了一半、服务挂了、退不回去」。
```mermaid
flowchart TB
START["新 JAR 已构建<br/>(字节码实证含本次改动)"] --> ISO["在隔离端口 :48090<br/>起一个新实例"]
LIVE["live 后端 :48080<br/>全程不动 · 继续服务"]:::live
ISO --> V{"在 :48090 验全?<br/>health 200 · 四模板就绪<br/>Flyway up-to-date · 冒烟门 12 项"}
V -- "全过" --> SWITCH["停旧实例 → 释放端口<br/>把新实例切到 :48080"]
V -- "任一失败" --> ROLLBACK["/tmp 备份 JAR<br/>把 :48080 恢复回去<br/>(5 分钟内 · live 本就没动)"]:::danger
SWITCH --> REVERIFY["切后复验冒烟门<br/>+ 真 UI 走查"]
SWITCH -.->|稳定观察一两天后| CLEAN["再删 /tmp 备份 JAR"]
ROLLBACK --> BACK["回到改动前形态<br/>排查后重来"]
classDef live fill:#eff6ff,stroke:#2563eb,stroke-width:2px;
classDef danger fill:#fee2e2,stroke:#dc2626,stroke-width:2px;
```
这张图没有现行/远期边界,它就是现行高风险发版的标准动作;它和图 2 的关系是「图 2 给全链路、图 3 把其中最关键的安全机制放大」。要注意的设计缝只有一个:这套变体是**人工经标准序**执行的,不是声明式的——这正是图 8k3s想用 `kubectl rollout undo` 改进的地方,但在 k8s 落地前、乃至落地后的过渡期,这条人工兜底路始终保留。
### 图 4 · 冒烟门 12+1SVG新·流程·现
![图 4 冒烟门 12+1 项](assets/04-冒烟门12项.svg)
这张图回答「靠什么确认它健康」。每次 staging 部署之后跑一遍 `deploy/smoke-test.sh`——它是「部署后是否健康」的**就绪检查**(秒级、以读为主、可反复跑),逐项 PASS / FAIL末尾给总判与退出码0 = 全过1 = 有 FAIL所以能直接挂到部署脚本里当卡口。图上把 12 个默认项按「基础设施 / 鉴权 + 五条端到端闭环链路」分组画出来,让人一眼看出冒烟门验的不是零散接口,而是**五条业务链的关键 API 是否都在岗**:① 创作→生成→预览、② 发布→审核→游戏流、③ 试玩→互动→分享、④ 广告→收益→钱包、⑤ 数据回路遥测→质量分→feed 重排)。
读这张图要抓三个细节。其一,**12 项里唯一的写操作**是建一条无副作用的草稿(`POST /app-api/studio/draft`status 0、不发布、无下游副作用用于验证创作入口 + 鉴权 + gameId 分配在岗;其余全是读。其二,`--deep` 才加的第 13 项(图上用橙色虚线框单独标「按需」)走真实写路径,触发一次生成入队 + 遥测落库,默认不跑、只验入队 `200/code=0`,不等生成完成。其三,图上用红框钉死了一个反复出现的坑:**feed 列表项的 `packageUrl` 字段恒为 null**,真实取游戏包要走 `GET /app-api/runtime/package/{versionId}`,别拿 `packageUrl` 当取包入口。
这张图的「设计缝」画在右下角那个虚线框里:冒烟门是「部署那一刻的就绪点检」,它**不是**深度 e2e深度 e2e 由 agent-loop 编排器批跑,职责不重叠),也**还没有**常态监控来补它的另一半——这正好衔接到图 6 的观测体系。衔接点写在图上:冒烟门那 12 项的结果可以打成指标推给 Prometheus让「每次部署的健康度」也进可观测历史而不是只在部署当时的终端里闪一下。
### 图 5 · 可用性 SLO / Error BudgetMer新·讲解·现
这张图回答「健康到什么程度才算达标」。运维域的硬指标是**服务可用性 ≥ 99.5%**,与之配套的是 MVP 基础设施成本控制在 **< ¥5,000/月**——这两个数字是运维域所有取舍(不上云托管、单体而非微服务、人工部署而非重 CI的约束来源。图把可用性目标拆成三档 SLO来自 `security-and-reliability.md` §5.1:游戏流 99.5%/月 ≈ error budget 3.6 小时、AI 生成 99%/月 ≈ 7.2 小时、支付 99.9%/月 ≈ 43 分钟),并点明这些目标怎么落进成本盒子。
```mermaid
flowchart TB
GOAL["可用性目标 ≥ 99.5%(MVP)<br/> 基础设施成本 ¥5,000/月以内"]:::goal
subgraph SLO["三档 SLO + Error Budget(security-and-reliability §5.1)"]
direction LR
S1["游戏流<br/>99.5% / 月<br/>容错预算 ≈ 3.6 小时"]
S2["AI 生成<br/>99% / 月<br/>容错预算 ≈ 7.2 小时"]
S3["支付<br/>99.9% / 月<br/>容错预算 ≈ 43 分钟"]
end
subgraph COST["成本盒子怎么撑住目标"]
direction LR
C1["内网物理机<br/>不上云托管"]
C2["单体<br/>而非微服务"]
C3["人工部署<br/>而非重 CI"]
end
GOAL --> SLO
GOAL --> COST
SLO -.->|"现状:只有一个目标数字,<br/>没有东西在持续度量它"| GAP["缺口error budget 无人消耗与记录<br/>→ 由观测体系落地(图 6)<br/>用 health 成功率算实际可用性 + burn rate 看板"]:::gap
classDef goal fill:#f0fdf4,stroke:#16a34a,stroke-width:2px;
classDef gap fill:#fff7ed,stroke:#d97706,stroke-width:2px,stroke-dasharray:5 4;
```
这张图最该让人看出的是那条虚线指向的**缺口**≥99.5% 现在是一个**目标数字**,但没有任何东西在持续度量它、没有 error budget 在被消耗和记录。换句话说,达标线画出来了,举证手段还没建。这个缺口的归宿就是图 6 的观测体系——用 health 探测的成功率算游戏流 API 的实际可用性,对着三档 SLO 做 burn rate 看板和告警,让「达没达标」从一句承诺变成一张有数据、有容错预算余量的看板。所以图 5 和图 6 是一对:图 5 立目标、点缺口,图 6 给落地手段。
### 图 6 · 观测体系OTel → Grafana / 夜莺SVG新·架构·接设计已出·待接线
![图 6 观测体系 OTel→Grafana/夜莺](assets/06-观测体系.svg)
这张图回答「线上靠什么持续观测」——也是本域**最该验状态纪律**的一张。它整体是**接**(待接线):创始人 2026-06-21 定了栈OTel 统一采集 + Prometheus + Grafana 主看板 + 夜莺主告警),正式设计稿已出,但**代码大半没接、没后端**。所以图上做了一件最要紧的事:把「现在已经有什么」和「还得新建什么」用实心块 / 虚线框严格分开,绝不让人误以为观测已经建好。
图按「采集 → 管道 → 存储 → 看板/告警」一条链画,逐段标状态。**唯一已就位的实心块**在图正下方高亮aigc-server 已引入 `spring-ai-alibaba-starter-graph-observation`SAA 裸图每个节点已发 `spring.ai.alibaba.graph.node.<id>` 的 Micrometer observation带 trace 和耗时,失败反映在指标里)——这是后端唯一一段已经在以标准产出、且依赖已就位的观测信号。但图上同样标清楚:它缺一个把它收走的后端、缺一个非 NOOP 的 `ObservationRegistry`(要 actuator/micrometer 装配在席)。**其余全是虚线框 + 「待接线」**OTel Java Agent自动 spanmonitor starter 当前根本没进 aigc 部署单元)、五个生成业务指标(`gen_task_total` / `gen_duration_seconds` / `gen_queue_depth` / `gen_gate_fail_total` / `llm_cost`,目前在代码里**全部零命中**,要补 MeterRegistry 注册才有数据,其中成本指标还额外依赖一个尚未落地的 new-api `logs.quota` 采集薄片、OTel Collector、Prometheus / trace 后端 / 日志后端trace 倾向 Tempo、日志倾向 Loki但都标「选型待定」、Grafana、夜莺、通知通道、admin 观测入口。
读这张图要抓住三层设计意图。其一,**为什么 Collector 居中而不是各组件直连后端**:让每个进程直接推各自后端会把地址、协议、脱敏逻辑硬编码进每个应用,上 k8s 或换后端就得改一圈;中间放一个 Collector 当统一入口,脱敏(手机号/token、批处理、采样、路由全在这一层集中做换后端只改 Collector 导出配置、应用零改动——这正是「先单体可跑、后平滑上 k8s」能成立的技术支点。其二**Grafana 和夜莺不是冗余而是分工**Grafana 负责「你主动去看时看得清」(三联下钻),夜莺负责「你没在看时它把你叫来」(把 P0P3 升级链变成真规则真通道,补上「告警通道一根没接」这个最大的空);创始人点名的三类关键告警都在图上有家——可用性走 P0、错误率5xx>2%)走 P1、生成失败率<70% P1其三图底那条红线是观测体系的底线**埋点开关默认关 profile 显式开agent 异步批量上报Collector 不可达时本地丢弃**硬验收是停掉 Collector主链路与各 API 行为不变冒烟门仍全绿观测栈本身挂掉绝不能影响被观测的服务
除图上画出的「trace/日志后端选型、admin 嵌入方式与 SSO详见图 7」这几条待核外源档《观测体系.md》§6 还留了两条待创始人拍板的口径,读图时一并记住、别当已定:一是**观测数据保留期与成本**——trace 与 metrics 存多久直接吃 mini-desktop 的磁盘,要对一下账「预算里留的那笔监控冗余够不够这套栈的存储」;二是**生成成功率告警阈值**——现在 P1 写的是「成功率 < 70%已经很糟该紧急处理的线而验收线是 80%是否要在 70% 之外再加一条 80% 的趋势预警让成功率从 80% 往下掉时就先有提醒而不是等到 70% 才报也待拍
### 图 7 · admin 观测入口Mer新·流程·接待接线
这张图把图 6 右侧「admin 观测入口」那一块放大,讲清运营怎么从后台一键进监控大盘。它整体也是**接**——而且这块的现状是**零**,要整套新建:`game-admin/src` 下没有任何观测相关的路由、菜单或组件,后端也没有任何给 admin 用的观测查询接口。所以「控制台一键进盘」不是接一根线,而是要补齐前端菜单/路由/组件、后端管理员专属查询接口、嵌入安全处理三件,缺一不可。图用虚线把这三件标成「待接线」,并画出 admin 进盘的链路与那个必须解决的体验问题:**别让运营进个监控还要再登一次 Grafana**。
```mermaid
flowchart LR
OPS["运营<br/>(system_users 已登录 admin)"] --> ADMIN["game-admin 控制台<br/>『观测』菜单(待建)"]:::todo
ADMIN -->|"观测大图:嵌入只读大盘"| EMBED["Grafana 嵌入面板<br/>可用性/错误率/生成成功率"]:::todo
ADMIN -->|"深挖跳转"| PROXY["admin 后端 auth-proxy<br/>透传 system_users 身份头(待建)"]:::todo
PROXY -->|"可信头免登(SSO)"| GRAF["Grafana 完整大盘<br/>trace/metrics/log 三联下钻"]
ADMIN -.->|"告警概览 API"| N9E["夜莺告警列表<br/>最近告警 / 值班状态"]
EMBED --> GRAF
classDef todo fill:#fff7ed,stroke:#d97706,stroke-width:1.5px,stroke-dasharray:5 4;
```
这张图要让人看出两处尚未拍板的设计缝,都还**待核**,不能当成已定。其一,**嵌入方式**iframe 嵌 Grafana 不是写个 `<iframe src>` 就完——Grafana 默认带 `X-Frame-Options: deny` 和自身 CSP浏览器会直接拒绝被嵌入要让嵌入成立得开 `grafana.ini``allow_embedding` 并放 CSP `frame-ancestors`;另一条路是不嵌 iframe、改由 admin 后端查询接口取数、前端自渲核心曲线,绕开嵌入安全开关但要自己画图。其二,**SSO 免登**:倾向 auth-proxy 透传admin 后端把已登录的 `system_users` 身份经可信请求头透给 Grafana体验最好但要核 Grafana auth proxy 在 iframe 场景下的 cookie/同源限制,以及 admin 代理层的安全边界——**不能让未授权 admin 用户读到观测数据,更不能把 Grafana / Prometheus 裸暴露出去**。这两处待核是这块落地前必须先定的,图上据实标出、不臆造结论。
### 图 8 · k3s 单节点迁移(收窄 + 缓做SVG新·架构·缓缓做·排 W-G1 之后)〕
![图 8 k3s 单节点迁移](assets/08-k3s迁移.svg)
这张图回答「部署形态往哪走」——也是本域**第二个最该验状态纪律**的图。它整体是**缓**:创始人 2026-06-22 拍板「范围收窄、时机缓做」,所以图上整张是**目标态、本阶段不做**,用紫色虚线框 + 「缓做」标清楚,绝不能画成现行已建。范围收窄为单节点 k3s 跑在 mini-desktop 上、只迁 staging 应用与观测栈、数据库不进集群、多节点 / 高可用 / prod 全部推迟;时机缓做、排在 W-G1生成质量到 80%)告一段落之后(其中阶段 0 容器化零 k8s 风险、是上云前提,可先行)。
图分三块。**左上是目标拓扑**紫虚线mini-desktop 单节点 k3scontrol-plane 与 worker 同机),里面是后端单体 Deployment、studio/admin Deployment、observability namespace 的三件观测 workload旁边两个**实心块**是迁移期**全程保留**的东西——隔离 MySQL/Redis 裸容器(标「不进集群」,因为有状态迁移是另一个量级的风险)和「裸 JAR + /tmp 备份」逃生口(用红框单画,强调任一阶段、任一时刻 kubectl 出问题就 5 分钟内退回今天形态)。**右侧三块**是 mini-infra共享基建不进集群、不装 kubelet集群经 ExternalName Service 走 Tailscale IP 访问它、6c6g不当节点、不跑 workload只当 kubectl 控制端、lili-mac镜像必须 x86 出,与图 1 的边界一脉相承)。**底部是四阶段迁移路**:阶段 0 容器化(绿色实心、可先行)→ 阶段 1 装 k3s空集群、live 仍裸跑)→ 阶段 2 后端上集群(流量切换在此、风险最高)→ 阶段 3 前端 + 观测栈上集群,每阶段都标了独立验收门与回滚手法。
读这张图,最要让人看清的是「**买到什么、买不到什么**」那一栏:本阶段上 k8s 买到的是声明式部署 + `rollout undo` 一键回滚 + requests/limits 共存保护 + 观测栈编排;**买不到的是高可用**——单节点 k3s 一旦节点挂了,集群和所有 workload 一起没,这和今天裸 JAR 挂了没本质区别,反而多背了一整套 k8s 控制平面的复杂度。如果创始人的预期是「上了 k8s 就更稳了」,这里要先校准:高可用要等多节点,而多节点要等有第二台有内存余量的 x86 机器(现在没有)。技术细节上还有两个被图钉住的关键决定:后端走 `hostNetwork: true`(一举两得——既直占宿主 48080 让对外端口零变化,又能连只 bind 在 `127.0.0.1` 的库,`hostAliases` 和 host-gateway 都做不到);隔离期 Pod 用 `server.port=48092` 起(避开正被 live 裸 JAR 占着的 48080这正是图 2/图 3 的隔离验证安全变体平移到了 k8s。
---
## 3. 图清单与状态表
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 四机分工拓扑 | 架 | 引(链 README §1.1 | 现 | lili-mac / mini-desktop / mini-infra / 6c6g 角色边界 + Gitea 中转 + ARM/x86 镜像门铁律 |
| 2 | 部署链 push→pull→重建→验门 | 时 | SVG新 | 现 | Gitea 中转 + push 串行 + 字节码实证 + 隔离验证安全变体 + 真 UI 走查红线 + 目标态蓝图对照 |
| 3 | 隔离验证安全变体 | 流 | Mer新内联 | 现 | 新 JAR 在 :48090 验全才切、live :48080 全程不动、失败用 /tmp 备份回滚 |
| 4 | 冒烟门 12+1项 | 流 | SVG新 | 现 | 基础设施/鉴权 2 项 + 五链路 10 项 + --deep 写路径 1 项 + 退出码卡口 + packageUrl 恒 null 坑 |
| 5 | 可用性 SLO / Error Budget | 讲 | Mer新内联 | 现 | ≥99.5% + 成本 <¥5,000/月 约束来源 + 三档 SLO + 「无人持续度量」缺口指向图 6 |
| 6 | 观测体系 OTel→Grafana/夜莺 | 架 | SVG新 | **接** | 采集→管道→存储→看板/告警全链;唯一已就位=SAA 节点 observation其余待接线Collector 居中/双看板分工/旁路铁律 |
| 7 | admin 观测入口 | 流 | Mer新内联 | **接** | 控制台一键进盘链路 + SSO 免登 + 嵌入方式/SSO 两处待核;现状=零、整套新建 |
| 8 | k3s 单节点迁移 | 架 | SVG新 | **缓** | 单节点 k3s + staging 应用 + 观测栈,库不进集群;四阶段迁移路;裸 JAR 兜底全程保留;买到/买不到边界 |
> **状态分布**:现 ×6、接 ×2图 6/7观测体系待接线、缓 ×1图 8k3s 收窄缓做)。**防漂移门**:本图说 frontmatter 记三份源档的 commit hashREADME/k8s迁移 @ 15b707fd、观测体系 @ 3e71715a源档变更即比对hash 对不上则本图说与对应 SVG 标「待复核」。
>
> **PNG 后续**8 张图中 4 张为 SVG图 2/4/6/8SVG 入仓后在 mini-desktop 批量转 PNG6c6g 禁 chrome3 张 Mermaid图 3/5/7GitHub 直接渲染、无需转换;图 1 单源引用 README、不产新图。

View File

@ -1,161 +0,0 @@
---
date: 2026-06-22
topic: 运营域图说——把「一款游戏造出来之后,怎么合规上线、怎么把钱赚回来、怎么发行到各渠道」画成一套图 + 讲解(架构图集·运营域)
status: 现行为主(全 11 图整体状态 = 现)· 元素级标注「待接 / 待建 / mock / 留 M4 / 待律所 / 远期账」诚实区分 · 防漂移门记六份源档 commit hash
映射源档:
- docs/architecture/运营/README.md @ 3e71715a
- docs/architecture/运营/变现与单位经济.md @ 7ecd616e
- docs/architecture/运营/变现端到端.md @ 38357c3d
- docs/architecture/运营/渠道发行.md @ 5cadf504
- docs/architecture/运营/合规闸门.md @ 3e71715a
- docs/architecture/运营/审核台运营.md @ 15b707fd
---
# 运营域图说
> **这是什么**绘境AI 运营域的「看图入口」。运营域接在产品域(用户能感知什么)与架构域(系统怎么搭)之后,回答三件相互咬合的事——一款游戏被造出来之后,**怎么合规上线、怎么把钱赚回来、怎么发行到各渠道**。这份图说把这三件事,连同审核台这一摊日常内容安全运营,用一套图加配套讲解画清楚。复杂、跨平面的用手绘 SVG 大图,简单、线性的用 Mermaid各域 README 已内嵌的 Mermaid 一律单源引用、不复制。
>
> **给谁看**:运营负责人、商务 / BD、合规与法务对接人、负责变现与审核链路的后端工程师以及做投资尽调时关心商业模型与风险的创始人。判断「这套上线 / 变现 / 发行方案是不是想要的那个」看这份图就够建立全局轮廓;逐字节的公式、逐项闸门状态、逐个 file:line 锚点,仍去对应的子设计档与跟踪面。
---
## 0. 阅读约定与同步纪律
- **映射的设计档**:本图说不另立设计,只把运营域六份 canonical 设计档画出来——三件事的咬合骨架与分账公式出自 [`运营/README.md`](README.md);两平面 / 两钱包 / 单位经济出自 [`变现与单位经济.md`](变现与单位经济.md);三线钱流的工程地图出自 [`变现端到端.md`](变现端到端.md);一壳多游与渠道合规红线出自 [`渠道发行.md`](渠道发行.md);合规死锁与 12+1 闸门出自 [`合规闸门.md`](合规闸门.md);双层审核与处置联动出自 [`审核台运营.md`](审核台运营.md)。frontmatter 里记了这六份的当前 commit hash作为**防漂移门**源档一旦变更、hash 对不上,这份图说与对应 SVG 即标「待复核」,由收口脚本比对。
- **同步纪律****设计一变动,本图说与对应 SVG 必须同步更新**,每张 SVG 脚注注明映射源档与状态。已并入 wave 收口清单。
- **本域状态分布——整体是「现」,但布满设计缝,必须看清**:运营域不像运维域那样有「整图待接 / 整图缓做」的图;这里 **11 张图的整体状态都是「现」**(讲的都是已拍板的现行设计逻辑)。它的特殊之处在**元素级**——同一张图里常常一半是「已建真跑」、一半是「被合规日历闸门或外部资质阻塞、尚未接线 / mock / 留待后续波次」。所以本域守的纪律点是:**绝不能因为整图是现行设计,就把图里那些被阻塞的部分也画成已建好**。凡是「待接线」「待建」「mock 桩」「未接」「钱留 M4」「待律所裁」「远期账」的元素一律用虚线框 + 文字小标画出,与「现行已建 / 框架真」的实心块在视觉上一眼区分。变现侧的打款渠道、消费钱包、自助购买订阅、B 端收款,审核台的双层机审 / 人审队列 / 降权接缝 / 创作者信用,渠道侧的引擎竞标 P1 段与备案锁,合规侧那 8 项法定 P0 的换血——这些都是「设计已定、代码 / 资质未到」,本图集逐个标清。
- **状态码**:现 = 现行已建 / 框架真 · 接 = 现行待接线 · 建 = 待建 · 缓 = 缓做 · F = future-state · 废 = 决策史对照。本域 11 图整体均为「现」,状态差异在图内元素级标注。
- **产物形式**SVG 入仓GitHub 与编辑器直接渲染矢量PNG 在 mini-desktop 转6c6g 禁 chrome、无转换器。本图说只出 SVG。
## 1. 全图通用图例
**生产维度徽章**(用小色块 chip + 白字标在每张图相关的维度上,运营域主要关心其中三个,个别图点到第四个):
- **安全**`#dc2626`):合规即护城河(资质 / 备案是后来者 6-12 个月才补齐的壁垒、new-api 上游 API key 不明文 / 防盗刷、打款 fail-fast 绝不发假钱、审核降级朝保守(绝不放行型降级)、审核台端点权限强制在后端可信边界。
- **数据**`#475569`):备案 / 资质合规、成本与精度域隔离(元 ≠ 分、配置即数据GameConfig 禁代码)、内测养行为数据飞轮、审核台账留证 ≥180 天。
- **成本**`#16a34a`):单款生成成本远不到 1 元、自有端 IAA 万级 DAU 才回本的单位经济、渠道零构建生产红利、快检把审核大面在本地消化(省阿里云调用量)。
- **可靠**`#16a34a`):变现侧 7 个资金动作各有幂等键、账户恒等式、发起 ≠ 终态的打款异步化、对账锚点链与补偿 job——这是变现端到端图的主轴。
> 运营域的徽章里,**安全与成本两个维度是一体两面**:同一套合规资质,对自己是必须翻过的闸门(成本 / 时间),对后来者就是 6-12 个月才能补齐的护城河(安全壁垒)。所以「先把合规闸门跑通」既是上线的前置,也是在攒护城河——这条贯穿合规闸门、死锁破解、四层护城河三张图。
**复用 / 边界三线语义**
- **实线**`#334155`):现成直接用、真钱流 / 状态推进、硬前置依赖。
- **虚线**`#64748b``stroke-dasharray="6 4"`):自建 / 解耦 / 待接线 / 待建 / mock / 编译期接缝 / 分析镜像 / 条件解锁。
- **双线 / 加粗框**:跨域共享的公共件,或需要强调的硬边界(如三道资金硬边界、临界路径闸门、合规死锁三环)。
> 本域图说里,虚线同样额外承担一层**状态语义**:凡是被合规日历闸门或外部资质阻塞、尚未接线 / mock / 留待后续波次的元素,一律虚线框 + 文字小标;红色虚线 / 红框则用于「绝不能跨越的硬边界」与「合规生死线」。这是本域最该守的纪律点——变现链路里 mock 的打款、未接的消费钱包,审核台里待建的双层机审,渠道里待律所裁的备案锁,绝不能因为整图是现行设计就让人误以为已经建好了。
---
## 2. 图集
### 图 1 · 运营三件事咬合〔引·流·现〕
> 单源引用,不复制:运营三件事咬合的 Mermaid 已在 **[运营/README.md §1](README.md#1-一句话与一张图运营域要解决什么)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来——同一张图存两处、改一处漏一处,正是这份图集要消灭的漂移面。
这张图回答「运营域到底要解决什么」。它把上线、变现、发行三件事的咬合关系一句话说清:**合规闸门是总闸**,没过就不能商业化;**发行决定钱从哪里进来**(自有 H5 流 + 微信 / 抖音渠道);**变现决定钱怎么分出去**(广告 / B 端 / 远期内购订阅 → 分账 → 创作者钱包 → 提现)。三条线在「现金流」这个点上汇合。
读这张图最该抓住的是它顶上那个**反直觉但关键的战略判定**绘境AI 的差异化护城河**不在「自有 feed 形态」本身**(那块早有现任者——摸摸鱼 / 233 / 4399 占着),而在 **AI 供给侧的成本结构**(用 agent 闭环把游戏的生成与质检全自动化,产能成本远低于人工)+ **IP 锁风保真**。运营域的所有安排,都服务于把这个成本优势,在监管窗口期内滚成内容资产与数据飞轮。这就是为什么后面的图里,合规、变现、发行三条线看似各管一摊,实则都指向同一个目标。
### 图 2 · 12+1 合规闸门依赖与日历临界路径SVG升·流·现
![图 2 12+1 合规闸门依赖与日历临界路径](assets/02-合规闸门依赖.svg)
这张图回答「合规要过哪些闸门、按什么顺序拆」。它把 README §2.1 与合规闸门 §4 那张依赖 Mermaid 升成高保真大图,要让人一眼看出三条主线。**第一条**经营主体已经具备0 号闸门,创始人 2026-06-10 确认,图上用绿色实心块画出),所以下游各项可以立即并行起跑,**没有多米诺式的等待**——这是把整条链从「串行等待」变成「并行冲刺」的关键事实。**第二条**ICP 备案是临界路径7-20 工作日,图上用红边加粗框强调),它一通过,支付进件和广告资质两条线才能动;这条链由日历时间而非工作量决定,人再多也压不短。**第三条**:律所意见是另一个分叉点,它到位后才能定分账方案(#12)、确认大模型登记与算法备案(#9/#10)的属地路径与触发时点。
图上还钉了两件最该记住的事。其一是「**谁能压、谁压不动**」那条红线AI 一秒也压不动这些闸门,材料准备(报备文案 / 备案说明 / 隐私协议占位稿)可以由 AI 代劳,但**提交、实名、付费三类动作只有创始人本人能做**——这正是日历临界路径的本质。其二是状态纪律:每道闸门的实时状态、负责人、最晚提交日是会变的活数据,**本图只画不变的依赖逻辑、不抄状态**唯一跟踪面是《A1 闸门看板》看板变了即真相变了。这张图的「设计缝」画在最右侧那一栏8 项 C 端法定 P0实名 / 防沉迷 / AIGC 标识等)当前仍是国家强制义务的全集,但它们的**换血边界要等律所对两核心问给出书面意见后才能定稿**——这是仍阻塞全局的最大未决项,图上据实标出。
### 图 3 · 合规死锁三环 + 双层定性破解SVG新·讲·现
![图 3 合规死锁三环 + 双层定性破解](assets/03-合规死锁双层定性.svg)
这张图回答「为什么做得出游戏却不能直接公开经营、又怎么解开」。它是理解整个运营域合规逻辑的主干,左半边画死锁、右半边画破局。**左边的死锁是三条互相咬合的链**第一环UGC 小游戏无版号 → 接不进官方实名 / 防沉迷系统(版号是接入前提)→ 自有端作为运营方无法履行法定义务(有 Roblox 停服、罚没 111 万元量级的先例第二环IAA 免版号的豁免只在微信 / 抖音备案制内成立,搬到自有 H5 站就落进监管灰区;第三环,平台代收广告费再分账给个人创作者,等于无牌照资金归集,踩二清红线。这三环不是并列而是连环——「想合法经营 → 需版号 → UGC 拿不到 → 接不进官方系统 → 履行不了义务 → 真变现又必触发资金归集 → 碰二清」形成闭环,**任何单点突破都解不开**。
右边的破局办法是**双层定性**,把「自有端」和「变现渠道」在合规上彻底分开:自有端收敛为邀请制内测(邀请码注册、不公开经营、不接真钱),按「试玩 demo / 内测」定性,规避公开运营才触发的出版与防沉迷义务;真实变现全部放到渠道线(微信 / 抖音备案 + IAA豁免通道成立、实名 / 防沉迷由渠道代管、资金经渠道结算绕开二清。这样三环锁同时解开。这张图最该让人看清的**设计缝**,是右侧那个橙色虚线框标出的事实:**「邀请制内测能否稳稳落在试玩 demo 定性上」,其成立边界(人数上限 / 链接可否分享 / 能否有任何收入)目前是工程判断、不是已经验证的法律结论**——这正是要约律所的核心两问之一。在律所书面意见到位前,自有端按「不接真钱」运行(这也是现状、不引入新增风险),公开经营推迟到什么条件满足,要等律所答。
### 图 4 · 分账公式钱流〔引·流·现〕
> 单源引用,不复制:分账公式的钱流 Mermaid 已在 **[运营/README.md §2.2](README.md#22-变现两个平面两套钱包加一道单位经济检验)** 内嵌(同口径在 [变现与单位经济.md §4.1](变现与单位经济.md) 也有公式块),是该图的唯一来源。这里只链接、不复制——分账公式是全平台唯一口径,存两处改一处漏一处会直接酿成「账算成负数」的事故,最该单源。
这张图回答「广告挣的钱按什么规则分」。它画的是 R3 拍板(创始人 2026-06-10的唯一分账口径总广告消耗 G渠道扣 40%(微信 IAA 现金分成 60%)后平台实收净额 N = 0.6G;无 IP 时创作者拿 0.8N、平台留 0.2N,带 IP 时创作者 0.55~0.65N、IP 方从创作者份额内出 0.15~0.25N、**平台恒留 0.2N**。
读这张图要抓住它精妙的那一点——**平台恒留 0.2N**:带 IP 时IP 方的分成是从创作者那一份里出的,所以无论带不带 IP平台都稳定留 20%,而对外宣传创作者「拿 55%~65%」和内部「80% 分成」用的是同一个模型的两种表述,**账永远不会算成负数**。这正是规避资金纠纷与二清风险的会计前提。配套这条公式还有一条贯穿全域的**诚信红线**对创作者宣传「能赚钱」必须用「头部款」口径eCPM 30 时单款约需每日 12 次激励视频观看才达 5 元提现门槛,头部款可达、长尾款达不到),**绝不做普遍性承诺**。这个公式背后的单位经济结论(自有端 IAA 是万级 DAU 才回本的规模生意,约 1.33 万 DAU 覆盖 ¥4,300/月基建成本,所以近期现金只能靠 B 端),直接决定了图 6 的三线变现排序。
### 图 5 · 两平面、两钱包、三道硬边界SVG新·架·现
![图 5 两平面两钱包三硬边界](assets/05-两平面两钱包三硬边界.svg)
这张图回答「钱往外花和钱往回赚怎么隔开」。变现这件事工程上最容易出错的是把不同方向的钱混在一起算绘境AI 用三道永不混淆的硬边界把它钉死,图上用红色虚线把三道边界一条条画出来。**边界①**:生成计费平面(钱往外花)由 new-api 网关负责,配额只减不增、既不结算也不碰合规;收益与支付平面(钱往回赚)由后端 trade / pay 模块负责,广告分成入账、提现、结算、合规全在这里——把广告分成塞进只会扣减的 new-api 配额是范畴错误。**边界②**收益平面内部再分两套钱包——创作者收益钱包trade 模块,挣广告分成 / 提现用,**已建成**图上实心绿块与消费钱包pay 模块,用户充值 / 扣减内购用,**尚未接入单体**,图上虚线框 + 「未接入」)。**边界③**:成本侧全程用浮点「元」(活在编排器域)、收益侧全程用 BIGINT「分」活在后端数据库域两个精度域跨平面对照**必须显式换算、严禁同列求差**。
读这张图要抓住它把**已建与未建严格分层**的纪律。已建的实心块只有创作者收益钱包那条链(广告台账 → T+1 结算 → 物化账户,带恒等式与单测);其余都用虚线标清:消费钱包未接入、自助购买订阅被支付通道阻塞(现由 admin 手动赋)、打款渠道是 mock 桩。图底那个红框是边界铁律:**trade/pay 的钱永不写进 new-api**(已 grep 确认 new-api 里没有任何收益写入路径),而且 new-api 的 redemptions / top_ups / subscription_* 表 schema 在、却从未跑过数据,**不要当成就绪能力**。这张图的设计缝就在这些虚线处:消费钱包最小闭环属 v2.0、非 MVP 必需,自助购买订阅同被日历闸门阻塞——它们是「设计已留好接口、被外部资质卡住」,不是已经建好。图上还单标了一条 P0 安全红线new-api 的 channels 表存着上游厂商 API key开通公网 / 创作者账户前必须确认 3000 端口未绑 0.0.0.0、ufw 已封非内网,否则公网可达即被盗刷上游账单。
### 图 6 · 三线变现排序〔引·流·现〕
> 单源引用,不复制:三线变现排序的 Mermaid 已在 **[运营/README.md §3](README.md#3-三件事怎么咬合三线变现排序)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来。
这张图回答「三条变现线按什么先后次序走」。它画的是绘境AI 现行战略主轴的一条有先后的三线变现:**① B 端 / IP 营销小游戏(现金线·首位)→ ② 自有端邀请制内测(数据资产线)→ ③ 渠道线(规模线·微信 / 抖音 IAA**B 端的标杆案例还能反哺渠道线。
读这张图要理解每一线**为什么是这个合规定性、它产出什么**,而排序的根因正是图 4 / 图 5 的单位经济结论。B 端排首位,是因为推广内容不是网络出版物、版号争议最小、回款最早(已有「王蓝莓」案例点火),产出现金流 + 标杆案例;自有端排第二,按「试玩 demo」定性、不公开经营、不接真钱产出行为数据 + 产品迭代(飞轮种子,必须诚实地讲成未来式);渠道线排第三,豁免通道成立、平台代管实名 / 防沉迷,产出规模化曝光 + 真实 eCPM。这条排序对外讲给投资人的故事主轴是单人 + AI agent 体系的资本效率(已实证)→ 用 B 端 / IP 现金线供血 → 在监管窗口期里把供给侧的成本优势,滚成内容资产与数据飞轮(**后半段是未来式,必须诚实标注**)。这张图的设计缝就在「②③ 的产出是未来式」——飞轮和规模化 eCPM 都还没发生,图与口径都把它讲成未来式,不画成既成事实。
### 图 7 · 四层护城河〔引·讲·现〕
> 单源引用,不复制:四层护城河的 Mermaid 已在 **[运营/README.md §3「这套商业模型为什么成立」](README.md#这套商业模型为什么成立资本效率与护城河)** 内嵌,是该图的唯一来源。这里只链接、不抄一份进来。
这张图回答「真正难被复制的壁垒在哪」。它的核心论点是一句反直觉的判断绘境AI 的护城河**不在生成引擎本身**(通用大模型 12-18 个月就会把纯生成能力追平),而在时间沉淀出来的四层壁垒——**数据**(玩家行为 + 质量评分 + 推荐信号,需真实流量积累、无法购买)、**网络效应**(创作者多 → 内容富 → 玩家多 → 创作者更多,飞轮转起后追赶成本指数级增长)、**资产**(模板库 + 素材市场 + IP 合约,时间沉淀型资产)、**合规**ICP + 文网文 + 广告资质 + 渠道关系6-12 个月才齐备)。
读这张图最该看出的,是它和图 2 / 图 3 的呼应——**合规壁垒恰恰是那串闸门的另一面**:同一套资质,对自己是必须翻过的门槛,对后来者就是 6-12 个月才能补齐的护城河。所以「先把合规闸门跑通」既是上线的前置也是在攒护城河。绘境AI 的窗口期判断是 6-12 个月,竞争路线上**不追求技术深度第一,追求生态完整度第一**——技术够用即可,生态无法复制。这张图本身没有现行 / 远期的灰度(四层壁垒都是战略判定),它的「设计缝」是:四层里只有合规壁垒是当下就在攒的(闸门在跑),数据 / 网络效应 / 资产三层都依赖真实流量与时间沉淀,是**未来式的长期优势**,不是已经筑成的墙。
### 图 8 · 发行双路线 H5 / 渠道〔引·流·现〕
> 单源引用,不复制:发行双路线分工的 Mermaid 已在 **[运营/README.md §2.3](README.md#23-发行自有-h5-流--双渠道精选两条腿走路)** 内嵌(更细的分工根因与流程在 [渠道发行.md §1-2](渠道发行.md)),是该图的唯一来源。这里只链接、不抄一份进来。
这张图回答「游戏造出来铺到哪、怎么铺」。它画的是绘境AI 两条互补的发行路线,分工的根因是底层技术能力的硬差异:**自有 H5 流 = 海量 UGC 与「改码」的主场**浏览器对动态生成的代码没有禁令agent 生成的每款游戏都能即时发布、即时被刷到,这是「创作 → 生成 → 发布」闭环最完整的形态);**微信 / 抖音小游戏 = 精选整包过审的分发面**(这两个渠道对远程包会自动剥离代码、明文禁止 JS 解释器,所以渠道里只能跑「包内固定的模板代码 + 远程下发的纯数据配置」)。
读这张图要记住对外统一措辞——**「自研流即时发布 + 双渠道精选发行」**,以及那条「不互跳、不外导」的边界。它和图 9 是一对:图 8 给发行分工的全局轮廓,图 9 把渠道线那条「一壳多游」的架构与合规红线放大。这张图的设计缝在渠道这一支:渠道线只做 L1 精选整包过审,对外口径是「主题小游戏合集」而非「开放 UGC 平台」,且受备案锁约束(详见图 9而自有 H5 流没有备案锁、是 UGC 海量生成与 L2 改码玩法的主场。两条线的命运截然不同,绝不能混为一谈。
### 图 9 · 一壳多游 · L1 精选整包发行SVG新·架·现
![图 9 一壳多游 L1 精选整包发行](assets/09-一壳多游L1精选整包.svg)
这张图把图 8 渠道这一支放大,回答「渠道里的游戏到底怎么装、怎么过审」。它的起点是一个技术现实:微信 / 抖音自动剥离远程代码 + 明文禁 JS 解释器,浏览器无此禁令——所以海量 UGC 留 H5渠道只做 L1 精选整包过审。图分三块讲清「一壳多游」:**左边是壳工程**(随包提审、微信 / 抖音各一份、固定不变模板代码、核心层、SDK、四件 adapter 全打进包、固定不变,模板注册表只命中包内白名单;**中间是远程 GameConfig**(纯数据),玩法的差异全靠它表达,经 schema + hash 双重校验后才实例化——而它必须守住**渠道生死线**:禁一切可执行 / 可解释的字符串、禁远程下发任何代码、剧情关卡只能用有限状态机枚举,一句话「渠道里的游戏逻辑必须是数据、不能是代码」(这条红线转正后成为契约第 9c 条);**右边是平台运行时 + 备案锁 + 上架**。
读这张图要抓住两个最该看清的设计缝。其一是**备案锁**(图上用红边加粗框 + 「待律所裁」标出):官方规定备案完成后不支持改游戏内容 / icon / 代码,实质变更须重新备案,这条锁的是「内容」,于是把「一壳多游」从「灰区可行」**降级为「高风险待裁」**——「当日热发新游进渠道」的叙事已经收回,热发只限既有游戏的非实质参数微调,实质变更要走月级的「重新备案 + 整包提审」(具体边界待律所裁定);注意这条锁只约束渠道,**完全不影响自有 H5 流**。其二是**渠道引擎竞标 W-CH-α**(图上虚线框 + 「待裁」C-A=LittleJS+自研 adapter 对决 C-B=Cocos 原生导出P0 先行段五件产物已交付、6/6 PASS但 P1 真机段七道门**暂停中、待创始人提供三件套**(微信 AppID + Win/Mac 构建机 + 安卓千元机)。这张图还点出「禁动态代码」反而带来的架构红利:每游生产是产 GameConfig + 资产、Linux 工厂全自动零构建,对 Win/Mac 的依赖只落在低频的壳版本发布层、且仅 Cocos 胜出才需——真正绕不开人工的只有平台审核节奏本身。
### 图 10 · 变现端到端钱流地图SVG新·时·现
![图 10 变现端到端钱流地图](assets/10-变现端到端钱流地图.svg)
这张图回答「钱具体怎么从一次广告 / 一笔订阅 / 一单定制,流到创作者钱包或平台营收」。它是图 5 的下钻——图 5 立两平面 / 两钱包 / 三边界的架构,图 10 画三条线的工程钱流地图,凡 mock / 未接段一律虚线标清。**① 广告分成线**(最长、已建真跑,图上整条绿色实心):玩家看广告 → ad 计费 bill()(合规校验 blockMinor + 幂等 uk_trace + 归因 getCreatorUserId→ 落 game_ad_revenue 台账 → T+1 SettlementJob 逐笔 recordIncome 入账 → game_trade_income中间隔着 ad→trade 的 AdRevenueApi 接缝(单体 @Primary 就地解析)。**② 订阅会员线**trade 独管,入账已建 / 收单未建admin 赋订阅 → 幂等账本 subscription_grant → 续期 → C 端实时查态;自助购买那一半被支付通道阻塞,现由 admin 手动赋。**③ B 端定制线**biz 独管,图上整条红色虚线):只走业务状态机、**完全不碰钱**,收款 / 在线签章 / 分账整段留 M4现仅 signed_offline 兜底标记。
读这张图要抓住右侧三条线汇合后的钱流终态,以及它最硬的可靠性纪律。三条线在创作者收益钱包 game_trade_account 上汇合,**账户恒等式 balance + frozen + total_withdraw = total_income 必须永远成立**,四个原子动作更新 0 行就抛错回滚、绝不允许「状态已置、资金未动」的半态 commit。提现 → 异步打款这一段最该看清的是「**发起 ≠ 终态**」(图上红框):审核事务内只 CAS 0→1终态由回调驱动**打款渠道是 mock 桩**(图上虚线 + 「打款 mock 桩」)——因为 PayoutClient 只有 MockPayoutClient真实 wxpay / alipay 被合规日历闸门阻塞,但抽象已做对、补真实现即零改业务码切真;这条线的降级口径与广告线**正好相反**:广告渠道缺失降级 mock 可接受(少算收入),打款渠道缺失若降级 mock 就是吞真钱,**必须 fail-fast**。图底的控制平面画清「钱不会自己流」——三个 XXL-Job + 单体 Feign 接缝 + 打款双路驱动(正常路回调、异常路补偿 job两条路都过 CAS 故重复驱动安全),以及那条端到端的**对账锚点链**ad_revenue.id —source_ref→ trade_income —余额→ account 恒等式 —→ withdraw.transfer_refstat_date 统一取上游)。这张图的设计缝集中在三处虚线:订阅自助购买未接、打款 mock、B 端钱留 M4——它们都是「逻辑早已真实落地或抽象做对、被外部资质 / 后续波次卡住」,图上据实标层、不画成已通。
### 图 11 · 审核台:双层机审 + 锁风三档 + 人审 BPM + 处置联动SVG新·流·现
![图 11 审核台双层审核](assets/11-审核台双层审核.svg)
这张图回答「门开了以后,每条内容怎么一条条审过去、违规怎么处置」——它和合规闸门是两件事:合规闸门是把平台这台机器通上电的总开关(一次性、日历驱动),审核台是机器跑起来之后的质检线和安全阀(持续运转)。设计的核心不在「调三个检测器」,而在**路由**——什么内容在哪一层被放掉、什么必须往下一层送。图的主干是一个**三段瀑布**第一层自部署快检safe-content-ai挡掉大面、明显 OK 放行 / 明显违规拦截,只把灰带样本往下送,价值在成本——快检把大部分流量本地消化、省阿里云调用量);第二层阿里云内容安全(灰带样本送阿里云拿有合规背书的权威结论,**接入时点是接真实公开流量前 / 渠道线③上线前**,代码接缝现在留好、实现挂 feature flag第三层人审队列两道机审都判 review 或锁风人工档建工单MVP 用轻量状态机 + admin 队列、重型 Flowable 留远期,人审终裁是最高权威)。瀑布之上还有一个**锁风三档选档器**(标准 / 严格 / 人工复核),按内容的 IP 归属 + 类型自动选档,档位源现阶段是过渡表 lock_strength_policy、终态收敛进 IP 实体授权属性。
读这张图最该守的是它把**现状与待补严格分层**的诚实。现行已建实心绿块只有锁风门聚合那条框架ComplianceGateApi.evaluate 按 block > review > pass 取最严裁决、落 game_compliance_gate_result 台账、在发布前检查被真注入——但**聚合进来的原子目前都是桩、恒返回 pass**意味着今天的发布链对违规内容零自动拦截、纯靠人工兜底。其余全是本设计要补的待建虚线框双层机审的两层、人审队列底座、feed 自动降权接缝、创作者信用。处置联动这一栏要看清四类处置各自的现状落差——**下架**走 feed 现有的跨模块接缝 FeedApi.offlineRank现成可用、封禁联动下架已在走它**降权**则因为 setExposureLimit 现在只是管理端 HTTP 端点、不在跨模块 FeedApi 上,要 contract-first 新建 feed 降权 -api创始人 2026-06-22 定放第一期、单独做);**封禁**台账已建,但封账号联动断着(不置 player.status=DISABLE、不连带下架全部内容validateCreator 也不查 ban 表,所以今天封号拦不住本人继续创作,是本设计要补的两条断链);**创作者信用**现在一点没有、第一期建简单扣分台账(只记不连带、保守形态、防误伤)。图上还钉了两条贯穿铁律:**审核降级朝保守**(阿里云超时 / 报错降级到 review、绝不降级到 pass与打款 fail-fast 同理),以及**审核状态唯一权威在 compliance**project 只接回写、不双写,避免脑裂)。这张图的设计缝几乎布满全图——它如实画出了「框架在、判定空、处置半通」的真实现状,而非假装审核台已经建好。
---
## 3. 图清单与状态表
| # | 图名 | 家族 | 形式 | 状态 | 覆盖内容 |
|---|---|---|---|---|---|
| 1 | 运营三件事咬合 | 流 | 引(链 README §1 | 现 | 上线(合规总闸)/ 变现(钱怎么分)/ 发行(钱从哪来)三件事咬合 + 护城河在 AI 供给侧成本结构的战略判定 |
| 2 | 12+1 合规闸门依赖 | 流 | SVG升 | 现 | 经营主体已具备0 号)→ 全链并行ICP 临界路径 7-20 工作日律所分叉8 项法定 P0 换血待律所;状态去 A1 看板 |
| 3 | 合规死锁三环 + 双层定性破解 | 讲 | SVG新 | 现 | 死锁三环(无版号 / IAA 豁免仅渠道 / 二清)+ 双层定性(自有端内测 ‖ 变现走渠道);内测成立边界待律所问 1 |
| 4 | 分账公式钱流 | 流 | 引(链 README §2.2 | 现 | R3 唯一口径N=0.6G,平台恒留 0.2N,账永不为负;头部款口径诚信红线 |
| 5 | 两平面、两钱包、三道硬边界 | 架 | SVG新 | 现 | 生成计费(new-api)≠收益(trade/pay);创作者收益钱包(已建)≠消费钱包(未接);元≠分;边界铁律 + API key 安全红线 |
| 6 | 三线变现排序 | 流 | 引(链 README §3 | 现 | ① B端现金线 → ② 自有端内测数据线 → ③ 渠道规模线;②③产出诚实讲成未来式 |
| 7 | 四层护城河 | 讲 | 引(链 README §3 | 现 | 数据 / 网络效应 / 资产 / 合规 四层;护城河不在生成引擎;合规壁垒=闸门的另一面 |
| 8 | 发行双路线 H5 / 渠道 | 流 | 引(链 README §2.3 | 现 | 自有 H5 流UGC + 改码主场)‖ 微信 / 抖音(精选整包过审);不互跳不外导 |
| 9 | 一壳多游 · L1 精选整包发行 | 架 | SVG新 | 现 | 固定壳 + 远程 GameConfig禁代码·9c 红线)+ 备案锁(待律所裁)+ 引擎竞标P1 暂停)+ 零构建生产红利 |
| 10 | 变现端到端钱流地图 | 时 | SVG新 | 现 | 三线(广告全真 / 订阅半真 / B 端仅状态机)→ 创作者钱包(恒等式)+ 提现 mock 打款;控制平面三 job + 对账锚点链 |
| 11 | 审核台双层审核 | 流 | SVG新 | 现 | 快检 + 阿里云兜底 + 人审 BPM + 锁风三档 + 处置联动(下架现成 / 降权·信用·封账号联动待建);锁风门框架真·原子桩 |
> **状态分布**11 张图整体状态全为「现」(讲的都是已拍板的现行设计逻辑);状态差异在**元素级**——已建真跑 / 框架真用实心块,待接线 / 待建 / mock / 钱留 M4 / 待律所 / 远期账用虚线框 + 文字小标。本域无「整图待接 / 整图缓做」的图,其纪律点是**不把现行设计里被合规日历闸门或外部资质阻塞的部分画成已建好**。**防漂移门**:本图说 frontmatter 记六份源档的 commit hashREADME/合规闸门 @ 3e71715a、变现与单位经济 @ 7ecd616e、变现端到端 @ 38357c3d、渠道发行 @ 5cadf504、审核台运营 @ 15b707fd源档变更即比对hash 对不上则本图说与对应 SVG 标「待复核」。
>
> **PNG 后续**11 张图中 6 张为 SVG图 2/3/5/9/10/11SVG 入仓后在 mini-desktop 批量转 PNG6c6g 禁 chrome5 张为单源引用现有 README Mermaid图 1/4/6/7/8GitHub 直接渲染、不产新图、不复制。

View File

@ -1,7 +1,7 @@
---
date: 2026-06-22
topic: 架构图集——全域目录 + 图清单 + 每图讲什么(确认稿 v2,已纳 Codex+Opus 双评审整改)
status: v2 据双评审修订 · 决策已拍(混合形式/导览式/分两期)· 待创始人确认修订后按域启动
status: 第一期已收口 = 单一全量主档 docs/architecture/系统全图说.md(创始人 2026-06-22 反馈:多文件跨子目录引用不渲染图 → 把"导览式总图叙 + 分散各域图说"改为合并一篇·删冗余;§4 图清单仍是有效图账)· 第二期生成引擎子树归在飞 session 只链不双写
---
# 架构图集 · 全域目录与图清单(确认稿 v2)