创始人 2026-07-06 三拍立项、晚间升档(3 款顶级 10h+ 并行、全 fable5 high、预算解除、clean-room 红线)、 四拍收口(统一山海原创 IP 宇宙《山海行纪》《山海巡异录》/《夜市一条街》定名/W-SAVE-CAP 立即切单/即批即开)。 三书各过 Codex+Opus 双评审(6 席 35 条全修入:两本账/阈值标草案/待建基建如实分层/链护栏三层/结构常数例外清单)。 台账:作战清单 W-POLARIS+W-SAVE-CAP 单、在飞板三行、SpaceHuggers 靶档裁定戳、NSTAR 档 reachability 引用核正; 三线 M0 同夜交付结果已记账(割草本机面全绿/夜市 卡牌 PARTIAL 断点清晰)。
160 KiB
date, topic, status, sot-impact, 上级, 关联, 图清单
| date | topic | status | sot-impact | 上级 | 关联 | 图清单 | |
|---|---|---|---|---|---|---|---|
| 2026-07-06 | 复杂游戏北极星件 | 终审稿(2026-07-06 fable 终审:走查缺口台账十条全部裁定——九条闭合、一条归属他单〔⑧线上批量迁移归 L2 实装+O-6 前置〕;场景 C 补 schema 后回写为通;20 处合并期裁定全部复核签认。同日在前:八单回填、O-6 挂起、Codex+Opus 双评审 N1–N14 修入)——待创始人拍。 | 骨架期不新建 canonical topic。本档若获批,将修订 `架构/生成引擎/agentic运行时架构图说`(§5.1 运行时形态与 §六 交互面的席位化演进)并可能新增生成引擎 L4 子档;九类工件 schema 落地时进 `contracts/`(遵 Δ5「无校验器不算契约」,走 contract-first);版本语义建在 A3.5 源工程版本寻址与 W-ASSET-SRC 之上、不与其争主(见 §4);需求基线 = `.agents/skills/agentic-seat-context-design.md`(需求输入、非 SoT,本档 §7 对其〔提案〕件逐条留「采/改/弃」)。不改 55 P0 验收定义,不挤占 16 周主线排期。 | docs/mvp/MVP作战清单.md | .agents/skills/agentic-seat-context-design.md · docs/architecture/架构/生成引擎/agentic运行时架构图说.md(§3 A1-A13/C5/C6 · §4.2 · §5.1-5.3) · .agents/knowledge/agentscope-2.0-facts.md · docs/agent-specs/2026-07-05-游戏资产管理范围决策-设计.md(W-ASSET-SRC) · contracts/play-loop/play-spec.schema.json · contracts/play-loop/verdict-feedback.schema.json · docs/architecture/架构/生成引擎/游戏质量与爆火能力.md · docs/architecture/架构/生成引擎/数据飞轮.md |
|
复杂游戏北极星件 · 设计(终审稿)
现行生成运行时的能力上限,是「一个 agent 一口气写出一款过九门的游戏,外加 A11 两段式改一改」。北极星要回答的是另一个量级的问题:一款肥鹅美食街级的复杂 2D 经营游戏,项目持续数十天、改动数千次、交付多个版本,创作者全程零工程感知——这样的多 agent 游戏工作室长什么样,以及它如何从现有 runtime 生长出来、而不是另起炉灶。
本档在骨架的六处承重裁决(立哪些席、工件长什么骨、版本语义踩在谁之上、阶梯怎么排)之上,回填了八个填充单的核实与草案:标的规格细化到字段名与曲线锚、六席四层配方成文并附框架默认注入面审计、九类工件 schema 完整化并与既有契约逐字对账、三场景席位-工件流走查逐步推演、切片阶梯落到 16 周主线接缝。走查是证伪测试:场景 A、B 的机制骨架走得通(附条件与前置),场景 C 的立身机制在走查当时的 schema 下走不通、当场标断回终审——终审据此补了 schema(约束性决定 decisions[] 落判定书与升级事件、账本建决策索引、工单加 decisionRefs 铸单时机械对撞),场景 C 回写为通:断点是被修复的,不是被糊掉的。O-6(版本语义源码核实)挂起,等 W-ASSET-SRC 执行计划成文再起。
0. 目标与边界
目标与作战清单 W-NSTAR 单(2026-07-06 升档版)逐字对齐,产五件:ⓐ 标的游戏规格(§1,全档架构决策的测试用例);ⓑ 席位架构裁决(§2);ⓒ 九类工件 schema 字段级草案(§3);ⓓ 版本语义落到现实接口(§4);ⓔ 倒排切片阶梯与主线接缝(§5)。
边界,四条硬的:
- 设计先行,不含实现。 schema 冻结在本档文字 + 示例 JSON;校验器、代码物随实现波次走 contract-first,不在本单。
- 不挤占 16 周主线。 本档只标注接缝(§5),每级切片进主线仍过波次排期;与主线争资源升级回创始人。
- 标的只做一款经营品类。 多品类扩展归 W-TPL 与 W-GENRE;tier2 复杂游戏的「模板」形态由本档 §5 的切片裁决间接约束,但模板产线本身不在此。
- 既有 canonical 只引用不重写。 运行时形态、质量口径、回流环、九门纪律各有其主;本档对它们的每一处引用,冲突即以对方为准并回本档修。
需求基线(agentic-seat-context-design)是输入不是结论:§7 对其全部〔提案〕件逐条留「采/改/弃 + 理由」。
1. 标的游戏规格
命题:北极星标的不是产品排期承诺,是架构的测试用例。 每个席位、每类工件、每条版本机制的取舍,都必须能在下面这款游戏的三个真实场景里走通;走不通的设计,当场作废,不许「留到实现时再看」。选经营品类不是偶然:多系统共享经济状态、数据表密集、生命周期长,是对席位划分与版本语义压力最大的品类——解谜或跑酷类撑不开这套架构的受力面。
1.1 标的:《夜市一条街》(概念名)
一条可扩张的夜市街,玩家从一个小吃摊起步、逐步盘下整条街的餐饮生意。对标肥鹅美食街的复杂度档位,八个系统共享一套经济状态、彼此的产出互为对方的输入——这正是选经营品类当北极星标的的理由:多系统在同一份存档上耦合,是对席位划分与版本语义压力最大的受力面。八个系统的机制与主要数据表如下,字段名粒度、类型省略,schema 随实现波按 contract-first 补齐。
① 服务循环(核心手感所在)。 顾客进店、点单、等待烹饪、上菜、结账、留下口碑——这条链是整款游戏每一帧都在跑的主循环,也是玩家零阅读就该上手的地方。顾客耐心条是整条循环的节拍器:它的衰减斜率直接决定同屏能塞下多少顾客,也决定玩家在「先服务谁」这个优先级判断上有多少余地(决策模式见 sim-business-game-design.md:48)。耐心耗尽即翻台走人、扣口碑;及时上对菜给好评、附带小费。核心动作必须单击可达——点等待中的顾客即按其点单自动出餐结账,不做「先点顾客再点货架」的两步匹配(否则零-LLM 真玩 driver 跟不动、好游戏被九门 H 误判,红线见 sim-business-game-design.md:151);深度来自同屏顾客的优先级排序、连击维持与库存节奏,不来自操作步数。
| 数据表 | 主要字段 |
|---|---|
| 顾客类型表 customer_type | id / 名称 / 立绘assetId / 耐心基线秒 / 客单价区间 / 出现权重 / 偏好菜品tag[] / 稀有度 / 小费基础系数 |
| 菜谱表 recipe | id / 名称 / 图标assetId / 所需食材[{食材id,数量}] / 烹饪时长秒 / 售价 / 成本(食材合计) / 解锁条件ref / 稀有度 / 偏好客群tag[] |
② 街区扩张。 摊位盘成店面、店面连成多店,空间不是背景板而是吞吐上限:一张桌子同时只坐一组客,灶台数量卡住并行出餐的锅数,收银台排长队会连带压垮前面几组的耐心。玩家花金币与声望盘下新地块、摆布桌椅与设备,把「一个摊能服务几人」这条产能曲线一段段抬高。扩张是长线成长轴的骨架——数十天生命周期里,「开第 N 家店」是最外层的阶段目标。
| 数据表 | 主要字段 |
|---|---|
| 地块表 plot | id / 类型(摊位/店面) / 坐标 / 解锁价格 / 容纳桌位数 / 解锁条件ref / 状态(未解锁/空置/营业) |
| 设备表 equipment | id / 名称 / assetId / 类型(灶台/冰柜/收银台/装饰) / 占地格数 / 吞吐加成 / 价格 / 解锁条件ref |
③ 菜谱研发。 食材两两三三组合解锁新菜,稀有食材配出的菜卖得贵、利润率也更陡——利润梯度是研发这条线的诱饵。玩家攒够声望或食材解锁研发节点,菜单越铺越宽,能接住的客群也越广(某些稀有客只认高阶菜)。研发与街区扩张共用同一棵解锁树,保证「下一个该解锁什么」在任意时刻只露出玩家够得着的那几个锁。
| 数据表 | 主要字段 |
|---|---|
| 食材表 ingredient | id / 名称 / 图标assetId / 采购单价 / 稀有度 / 库存上限 / 保鲜时长(可选) / 解锁条件ref |
| 解锁树表 unlock_tree | 节点id / 类型(菜谱/地块/设备/食材) / 目标ref / 前置节点[] / 解锁成本{货币,数量} / 触发(声望阈值/任务完成) |
④ 员工体系。 雇人是把玩家的手从重复劳动里解放出来的机制:服务员自动收台、后厨自动出基础菜、收银自动结账。员工有岗位、有效率、有可升级的技能槽,玩家在「多雇一个人 vs 升现有人的技能」之间做投入判断。它替玩家自动化掉一部分服务循环,让玩家的注意力上移到调度与扩张——这是放置品类「不肝」体验在经营壳里的落点。
| 数据表 | 主要字段 |
|---|---|
| 员工表 staff | id / 名称 / assetId / 岗位(服务/后厨/收银) / 基础效率 / 雇佣成本 / 日薪 / 技能槽[技能id] / 状态(在岗/休息) |
| 技能表 skill | id / 名称 / 适用岗位 / 效果类型(加速/加成/自动化) / 效果数值曲线ref / 升级成本曲线ref / 上限等级 |
⑤ 事件与节奏。 平铺直叙的经营会闷,事件系统负责在时间轴上打节拍:高峰潮汐把客流猛地拉满、美食评论家带来一次高风险高回报的接单、限时活动给一个短期目标,雨天这类天气事件换一整套场景氛围与客流修饰。每个事件都是一组对基线数值的临时修饰(客流倍率、耐心系数、同屏上限、售价加成),叠加在服务循环之上。这个系统也是场景 B「雨天夜市」的宿主——雨天是一个天气类事件条目,连着它自己的场景资产。
| 数据表 | 主要字段 |
|---|---|
| 事件表 event | id / 名称 / 类型(潮汐/评论家/限时活动/天气) / 触发条件(时段/日期/概率) / 持续时长 / 效果修饰{客流倍率,耐心系数,同屏上限修饰,售价修饰} / 场景assetId / 奖励ref |
⑥ 经济与进度。 金币、声望、食材三种资源构成经济底盘:金币是循环挣、用于常规升级的软币,声望是解锁高阶内容的稀缺轴,食材是需要进货补货的消耗品。离线收益让玩家回归时有惊喜,每日目标手把手给下一步。这个系统的数值不是散落各表的魔法数,而是集中在一张数值配置表里由曲线管着(见 §1.1.1),让平衡能被仿真器整体扫过、也让「第 1400 次改动」不必翻遍代码找一个常量。存档表是这一切状态的落盘面,带 schema 版本号——它是 §4 兼容检查器认的那个对象。
| 数据表 | 主要字段 |
|---|---|
| 数值配置表 economy_curve〔即经营参数的曲线常量表,归为「数值配置表」一类,性质上区别于实体表〕 | 键 / 曲线类型(线性/指数) / 基值 / 增长率 / 卡点位 / 适用对象(升级成本/单位产出/耐心/离线收益) |
| 任务表 quest | id / 类型(每日/阶段/引导) / 目标{指标,阈值} / 奖励{货币,数量} / 前置ref / 有效期 |
| 存档 schema save_state〔运行时状态、非内容席数据表;承载 §4 saveDataImpact 的独立版本纪律面,缺口④终审定性〕 | schemaVersion / 三资源余额 / 已解锁节点[] / 地块与设备状态[] / 员工状态[] / 每日进度 / 事件历史 / lastOfflineTs |
⑦ 变现位。 双倍收益广告、加速广告、装饰内购位——变现在经营游戏里是包装成福利的自愿点位,不打断爽点。每个位子是一个逻辑槽,触发点(结算/加速/解锁)、奖励倍率、冷却写在表里;真实的广告调用不在游戏里发生,而是经 SDK 抽象到宿主侧(渠道约束见 §1.1.3)。装饰内购位在 MVP 只预留结构、不接支付。这张表的字段刻意与平台广告 API 解耦:游戏只认 adSlotId 逻辑标识,不认平台的 adUnitId。
| 数据表 | 主要字段 |
|---|---|
| 变现位表 monetization_slot | id / 类型(激励视频/内购预留) / adSlotId(枚举白名单) / 触发点(结算/加速/解锁) / 奖励{类型,倍率} / 冷却秒 / 兜底奖励(reward_fallback 计入) |
⑧ 社交外围(远期档)。 排行榜与好友串门属长线社会性钩子,MVP 不做——单机联网社交落不到轻量运行时,可达性红线明写要改单机 + 本地最佳分(sim-business-game-design.md:146)。此处只登记两张远期占位表、给最小字段,标明不进 MVP、进 L4 传播线后再定。
| 数据表(远期占位) | 主要字段 |
|---|---|
| 排行榜条目表 leaderboard_entry(远期) | 玩家id / 指标(声望/营收) / 值 / 榜期 |
| 好友串门表 friend_visit(远期) | 主家id / 访客id / 时间 / 互动类型 / 奖励 |
数据表清点: 实体与配置表 12 张(顾客类型/菜谱/地块/设备/食材/解锁树/员工/技能/事件/数值配置/任务/变现位)+ 存档 schema 1 份(save_state——运行时状态、非内容席可填的数据表:其变更走 SpecDelta 登记与实现席代码,校验器是兼容检查器而非 validate_datatable;缺口④终审定性),另加社交外围 2 张远期占位,满足「数据表不得低于 10」;八系统满足「系统数不得低于 8」。save_state 是从原始清单里显式拆出的一份——它承载 §4 版本语义的兼容检查器所依赖的 schema 版本纪律,§4 隐含依赖它、§1 补齐登记,使两节自洽。
量级估计(架构受力用,非承诺):源文件 30–60 个,数据表 10 张以上,精灵/UI 素材 150–250 件,音效 8–12 条 + BGM 2–3 首;生命周期数十天、改动上千次、版本卡几十张。运行主端是自研 H5(web/iframe 沙箱),标的数十天、千次改动、多版本的完整闭环活在这一端;微信/抖音小游戏平台自动剥离远程代码、禁 JS 解释器,写码富游戏上不了它们的「一壳多游」批量通道,只能作为重点游戏走「单游固化」导出特例——单独一 appid、把代码固化进包提审,人在环、受备案锁与月级审核节奏约束。运行端的架构受力真正有力的是三条:包体分包上限逼资产走按需加载与体积门、触控为主逼输入抽象、云存档逼存档 schema 有版本纪律;具体数值与渠道 API 现状详见 §1.1.3。〔fable 合并期裁定·终审签认 2026-07-06:渠道定位——运行主端 = 自研 H5,微信/抖音 = 单游固化导出特例,不走一壳多游批量通道。〕
1.1.1 数值曲线骨架(首版)
数值是这款游戏的受力核心,但它同时是全档里最不该在骨架期拍死的部分——耐心斜率、利润梯度、解锁节奏这三条曲线怎么配才「好玩」,靠的是把游戏快进跑上千局看曲线形状(§1.2 场景 A 的快进仿真器、§5 L3 的仿真器工具、可行性见 §2.C),不是骨架期一次填对。所以这里只钉形状与首版锚点,每条都标清锚点的来源与「待仿真校准」的部分。
一处口径必须先说清:sim-business skill 里那套客流锚(清闲期出现间隔 1.8–2.8s、同屏上限 3、耐心 5–7s;高峰期间隔 1.0–1.5s、上限 4;rush 起点 ≥35s)是为便宜档 60 秒单局校的(sim-business-game-design.md:74)。北极星标的是 tier2 复杂游戏,一个「局」是一个营业日、生命周期跨数十天,不是 60 秒。所以下表把便宜档单局锚当作营业日内节拍的起点量级继承过来,而把「拉伸到营业日与跨日成长」的那部分统一标为待仿真校准——这条继承关系本身也是 §2.C 要验证的:营业日节拍能不能直接沿用单局锚,还是需要另一套。
| 曲线 | 形状 | 首版锚点 | 锚点来源 | 校准状态 |
|---|---|---|---|---|
| 顾客耐心 | 按稀有度分档的常量基线,受事件修饰临时下调 | 普通客耐心 5–7s、高峰更短;同屏上限 清闲 3 / 高峰 4 | sim-business-game-design.md:74(便宜档单局锚) |
营业日尺度下的分布、稀有客耐心梯度 待仿真校准 |
| 客流出现间隔 | 清闲慢、高峰密;高峰不早于营业日中段 | 清闲 1.8–2.8s / 高峰 1.0–1.5s;高峰起点 ≥ 营业日 35%(单局对应 ≥35s/60s) | 同上 :74 |
营业日曲线与多波次潮汐 待仿真校准 |
| 菜价利润梯度 | 售价随稀有度递增、利润率随解锁深度递增 | 营收三档解锁阈值 22 / 55 / 100(金标烘焙店 serve 的菜单渐次解锁形状) | sim-business-game-design.md:184(金标 bake-shop-serve 锚) |
三资源经济下的绝对值与利润率斜率 待仿真校准 |
| 解锁/升级成长 | 成本指数增长,制造「差一点」的卡点、不卡死 | 升级成本 ×1.15/级(默认锚) | 质量 SoT §5「成长曲线 ×1.15/级为默认锚」(游戏质量与爆火能力.md:78) |
跨营业日的解锁阶梯步距 待仿真校准 |
| 离线收益 | 每 N 秒基础产出 × 离线时长,设封顶 | 〔首版无锚〕 | —— | 产出率与封顶值 待仿真校准;〔来源缺口:仓内无离线收益具体数值锚,待品类件或仿真给出〕 |
| 同屏最大顾客数 vs 帧率 | 性能约束曲线,同屏上限随设备档降级 | 低端设备帧率锁 30fps、限制粒子/音频预加载 | runtime-and-multichannel.md:148(低端降级) |
高峰同屏上限的性能安全值 待仿真校准;此曲线是 §1.2 场景 C「高峰期太卡」的数值宿主——同屏上限既是玩法参数也是性能闸,两重身份必须同表管 |
首版骨架的自检口径:成长必须有「越来越快」的暴富段而非平淡线性,卡点是诱惑不是墙(sim-business-game-design.md:72);经营品类的经济门要求真玩到盈利终态可达、且不制造经济死局(质量 SoT §8 平衡门五裁定),这两条是仿真器校准时的目标函数,不是骨架期的锚。
1.1.2 资产清单(表格粒度)
竖屏 390×844、单/少场景(sim-business-game-design.md:12),美术一致性靠全资产共用一组风格词(主体 + 风格 + 配色 + 构图,sim-business-game-design.md:88),风格基调走 Q 版萌系扁平或治愈暖色(:80)。下表把量级估计(精灵/UI 150–250 件、音效 8–12、BGM 2–3)落到类别粒度;总量与体积必须落进运行时体积门(全量 ≤10MB、首屏 ≤2MB,见 §1.1.3),这是资产席 harness 的硬闸(§2 资产席「体积门」)。
| 类别 | 数量估 | 单件规格 | 格式 | 来源 |
|---|---|---|---|---|
| 顾客立绘 + 状态动画 | 8–12 类型 × 3–4 状态(等待/满意/不满/离店)≈ 30–48 | 128×128 | png / atlas | mmx 生成 |
| 菜品图标 | 15–25 | 96×96 | png / atlas | mmx 生成 |
| 食材图标 | 12–20 | 64×64 | png / atlas | mmx 生成 |
| 摊位/店面地块 | 6–10 | 可变 | png | mmx 生成 |
| 设备(灶台/冰柜/收银/装饰) | 10–15 | 可变 | png | mmx 生成 |
| 场景背景(含雨天变体) | 3–5 场景 ×(基础 + 天气变体) | 390×844 或平铺底 | webp | mmx 生成 |
| UI 组件(HUD/按钮/弹窗/图鉴格/进度条) | 30–50 | 分级圆角、9-patch | 矢量 / png | 程序化 + mmx |
| 特效贴图(飘字/连击/解锁光效) | 5–10(主体走 particles-juice 程序化) | 小图 | png | 程序化为主 |
| 音效 | 8–12(收钱叮/上菜/升级/合成/点击/解锁/翻台) | 短样本 | 音频 | zzfx 程序化兜底 + mmx |
| BGM | 2–3(闲时/高峰/雨天) | 循环 | 音频 | mmx music(instrumental) |
合计精灵/UI 约 150–200 件(落 150–250 区间)、音效 8–12、BGM 2–3。体积纪律:首屏只加载首营业日首场景的资产(≤2MB),其余走三容器预加载/按需(runtime-and-multichannel.md:48);全量顶到 10MB 门前,靠 WebP/AVIF 与音频懒加载压(runtime-and-multichannel.md:159)。程序化兜底是硬底线——缺图不许阻塞可玩性(sim-business-game-design.md:90)。
1.1.3 双端渠道约束(核实)
§1.1 末段预判双端约束里对架构真正有力的三条力,这里逐条核实并给仓内一手出处。核实结论:三条力都成立,但第三条(存档)比预判更重,还有第四条(禁远程代码)预判里没写、却是对标的影响最大的一条。仓内查不到的数字标〔来源缺口〕、不编造;与既有渠道 SoT 冲突处以 SoT 为准。
先把「双端到底是哪两端」钉清楚:
- 运行主端 = 自研 H5 流(iframe 沙箱)。 浏览器不禁动态生成代码,是写码富游戏唯一容身处(渠道发行 SoT :20/:49)。标的数十天、千次改动、多版本的完整闭环活在这一端。
- 特例发行端 = 微信/抖音小游戏(单游固化)。 渠道只接 L1 纯数据一壳多游;tier2 富游戏要上渠道只能作为重点游戏单独一 appid、把代码固化进包提审(渠道发行 SoT :55),受备案锁与月级审核节奏约束。
A. 包体与分包。 H5 iframe 全量资源 ≤ 10MB、首屏 ≤ 2MB、超限编译失败(六处契约一致:架构/README.md:341、security-and-reliability.md:65、game-package.schema.json:35、api-schemas/runtime.yaml:121、db-schemas/V3.0.0__create_game_runtime.sql:30、runtime-and-multichannel.md:69);渠道版主包上限 ≤ 4MB(渠道发行 G1 真机门,渠道发行.md:240);微信/抖音「主包 + 分包」总上限、单分包上限、分包数量,仓内无出处、〔来源缺口:待外部核实〕。对架构的力:逼资产按需加载 + 体积门。 标的资产量级(§1.1.2)在 H5 端就顶着 10MB / 2MB 门,资产席「体积门 harness」是硬闸;渠道单游固化端 4MB 主包连全量精灵都放不下,分包/按需下载是硬需求——这条力不依赖分包上限的具体数字:无论上限多少,标的都必须分包。
B. 存档(比预判更重)。 现行 H5 storage 四道闸:闸①key 只放行 idle:gameId:versionId 白名单;闸②value ≤ 4KB(idle 存档实际 <200B);闸③写前 JSON.parse 校验、回读只接受对象形态;闸④落盘加 wxgame: 前缀命名空间隔离(03-产物执行沙箱图说.md:74、:217)。SDK Storage 层做云存档/进度、失败回退 localStorage(runtime-and-multichannel.md:90);渠道版存档走 canvas-input-audio-storage 四件 adapter 之一(渠道发行.md:126)。平台云存档配额(单 key / 总量)仓内无、〔来源缺口:待外部核实〕。对架构的力:逼存档 schema 有版本纪律,且逼存档面为复杂游戏重新定容。 现行四闸是为「无离线态模板、存档 <200B」设计的,value ≤ 4KB 对北极星复杂存档(save_state:三资源余额 + 已解锁节点 + 地块设备状态 + 员工状态 + 每日进度 + 事件历史)根本不够,单 key 白名单也容不下结构化多字段存档。这坐实了 §4 挂的「save-progress 现状待核」:现行 L2 KV 存档既无 schema 版本字段、value 又卡 4KB,对标的是前置增补需求——存档面要重新定容(放宽 value 上限或改多 key / 结构化)并加 schemaVersion 字段,走 L2 插件库通道(§4 明示不在本单实现)。§4 兼容检查器正是建在这个带版本的存档面上;没有这次定容与加版本,场景 A/B 的存档迁移无处落。
C. 输入。 输入抽象落 canvas-input-audio-storage 四件 adapter 之一(渠道发行.md:126);触控为主——真机门 G2b「各 3 次真实触摸完成 tycoon 闭环」、真机测试禁状态注入(渠道发行.md:242、:213);竖屏 390×844(sim-business-game-design.md:12)。对架构的力:触控为主逼输入抽象。 canvas-input adapter 把触摸事件抽象成引擎统一输入,一套玩法逻辑跨三端(H5 pointer / 微信 touch / 抖音 touch)。标的的服务循环「点顾客即成单」本就受此约束——所有交互必须触控单击可达,不能依赖键盘或鼠标 hover(与 sim-business-game-design.md:151 driver 可达红线同源)。这条力回馈 §1.2 场景 A 的交互设计:创作者说的每个新机制,主设计席产规格时都要落到触控单击可达。
D. API 与网络(四重力)。 禁远程代码:微信/抖音自动剥离远程包代码、明文禁 JS 解释器,渠道 9c 契约禁一切可执行/可解释字符串、禁远程下发 JS/WASM/HTML/脚本化 SVG(渠道发行.md:20/49/140-146);iframe CSP connect-src 'none',游戏内零网络请求(tech-decisions.md:141、runtime-and-multichannel.md:67);广告 API showRewarded(slotId) → 平台 wx/tt.createRewardedVideoAd,slotId→adUnitId,广告/支付在宿主侧 iframe 外渲染(渠道发行.md:151、runtime-and-multichannel.md:96);广告红线 rewarded=true 只认平台「完整观看」回调,兜底发奖标 reward_fallback=true,加载失败必须跳过、游戏继续、绝不卡死(渠道发行.md:151/153);官方 weapp-adapter 已不再维护,变现 SDK 各引擎都得手接(渠道发行.md:188)。四重力:①禁远程代码 → 逼标的的渠道路径二选一(H5 主线 / 单游固化),上不了一壳多游——这是对标的影响最大的一条,渠道里「游戏逻辑必须是数据、不能是代码」(渠道发行.md:147)与 tier2「LLM 写真 src/ 多文件代码」根本对立;②iframe 禁网络 → 变现位与云存档经宿主代理,变现位表只认 adSlotId 逻辑标识正是这条力的落点;③广告红线 → 变现位设计的诚实与降级纪律(加载失败静默跳过、兜底标 reward_fallback);④weapp-adapter 弃维护 → 渠道适配层是长期自研维护面(标的走单游固化则其 Phaser 工程的微信/抖音适配要自研 B-CHANNEL-* adapter)。
E. 备案与版本节奏。 备案后不支持改内容/icon/代码,任何实质变更须重新备案,「当日热发新游进渠道」已被收回、渠道线只能非实质参数微调(渠道发行.md:73/81);渠道版本节奏是月级「攒一批 → 统一备案 → 整包提审」(渠道发行.md:53/78/115)。对架构的力:逼版本语义分端。 §4 的高频版本语义(版本卡、意图重放、即时热发)只对自研 H5 流成立(H5 无备案锁);渠道侧标的的「数十天/千次改动」节奏落不了地——每次实质变更都要重新备案 + 月级整包提审。这条力已在 §4 末的端别边界落地。
尚待外部核实(仓内无权威出处,禁编造): ① 微信/抖音「主包 + 分包」总体积、单分包、分包数量的具体数字(仓内只有渠道主包 ≤ 4MB);② 平台云存档单 key 与账号总配额(仓内只有 H5 侧 iframe 沙箱的 4KB value 闸,那是自研 storage adapter 的闸、非平台云存档配额);③ 离线收益具体数值锚(§1.1.1 已记同一缺口),存档跨端同步的离线时长上限可能受平台约束,一并待核。
1.1.4 数据结构对三场景的自洽核对
- 场景 A(追加宠物系统):宠物是上线后的追加需求,不在基础规格里,但基础规格已为它留好 additive 落点——结账环节含小费(顾客类型表的小费基础系数),追加时是在顾客类型表加一列「互动小费加成」、在存档表 save_state 加一个可选宠物子树(旧档缺省视为未解锁宠物、additive 不升存档 schema 版本),正是 §1.2 场景 A 的 SpecDelta 与 saveDataImpact。基础规格不含宠物、但表结构不排斥它,自洽。
- 场景 B(雨天夜市回退分叉):雨天夜市是事件表里的一个天气类条目(连场景 assetId),V21 加的这条事件独立可回放/可重实现;§1.2 场景 B 说的「菜谱表在 V22 加过字段导致存档不兼容」,对应菜谱表字段可 additive 扩展、且 save_state 带 schemaVersion 供兼容检查器比对,自洽。
- 场景 C(第 1400 次改动·高峰太卡):高峰潮汐是事件表条目,「同屏最大顾客数 vs 帧率」曲线(§1.1.1)是这次改动的数值宿主——它既是高峰玩法强度旋钮、也是渲染性能闸,决策史「曾为正确性关掉渲染合批」重开会复发的正是这条上的性能约束,自洽。
1.2 三场景走查
标的的三个真实场景不是产品示例,是架构的证伪测试。每个席位、每类工件、每条版本机制的取舍,都要在下面三条链上逐步走通——哪一步指不出承接它的席位、消费不到需要的工件字段、或缺一道机制把上一步的产物接住,就是设计的断点,当场标出、回终审,不许留到实现时再看。三场景分别压不同的受力面:场景 A 压「一句话新增机制」到多席协作与存档契约变更的全程,场景 B 压版本回退分叉与意图重放,场景 C 压数千次改动后决策史如何在噪音里被精确对撞。走查的每一步都写明:哪个席(限六席)、消费什么工件的哪个字段、产出什么工件、创作者在这一步被不被打扰、若被打扰是三档确认的哪一档。走查暴露的 schema/配方缺口与软依赖逐条收进 §7「走查缺口台账」(下称「缺口①–⑩」「软依赖」),此处只引编号、不在正文展开;台账十条已经 fable 终审逐条裁定(2026-07-06),正文相应处标〔已闭合·终审〕,裁定细节见 §7 终审裁定表。
场景 A · 追加新功能
一句话:上线三周后创作者说「加一个宠物系统,顾客可以撸猫,撸完小费变多」,这句话要一路走到创作者手上多出一个能玩的预览版,中途不问他一个技术问题。
走查推演。 第一步落在制作人席。它消费两样东西:context 配方里的「用户现场快照」块(会话态即时、性质为事实,承载创作者那句原话),与场景注册表(§2.B,harness 层的分诊路由)。制作人席按注册表把这句话匹配到 sceneId=modify.behavior(sceneFamily=修改、intentClass=behavior),路由取 route.entrySeat=producer、route.terminalSeats=[design, impl]。这里守可信边界铁律——模型自己报的执行 mode 一律不采信,只按 intentClass 落路由。制作人席同时识别出这个需求会碰存档(撸猫养成态要落盘)和顾客类型表(撸猫按顾客类型触发),于是 irreversibleSources 潜在命中 saveData。
第一步在这里就撞到本场景的第一个承重争议:本节命题期望创作者「只在最后试玩这一步」被打扰,即全程档 1;但场景注册表把 modify.behavior 的 confirmFloor 记成「saveData 命中即 2」,照字面制作人席此刻就得把确认档顶到 2、先问创作者,档 1 的承诺当场破。调和的唯一走法,是让 confirmFloor 对 saveData 分两种性质:additive(新增可选字段、旧档缺省仍可读,SpecDelta.saveDataImpact.migratorNeeded=false)不顶 2,breaking(改删字段、旧档失效、migratorNeeded=true)才顶 2。宠物系统按 §3 的 SpecDelta 示例是 additive(旧档缺省视为未解锁宠物、无需迁移器),因此不顶 2、可走档 1。但这带出一个时序约束:additive 还是 breaking,要等主设计席产出 SpecDelta、saveDataImpact.migratorNeeded 落定才知道,而分诊在它之前——所以确认档的终判不能在分诊这一刻拍死,得推迟到 SpecDelta 产出之后。这与 WorkOrder.confirmTier「铸单时定死」并不矛盾:把分诊后先铸的那张工单(给主设计席、confirmTier=0、纯内部设计步骤)与后面碰创作者的工单分开,确认档就落在后者、且落在 SpecDelta 已知之后。〔fable 合并期裁定·终审签认 2026-07-06:confirmFloor 对 additive/breaking 细分、确认档终判推迟到 SpecDelta 已知后——采纳(缺口⑩口径);故场景 A 走档 1 成立。〕
第二步,制作人席产出一张 WorkOrder(工件①),route.terminalSeats 先指 design。工单字段:goal="为『顾客撸宠物、撸后小费上浮』设计系统契约与数据 schema 增量";confirmTier=0(内部步骤,不碰创作者);budget 按主设计席额度填 {rmbSoft, rmbHard, wallClockS, resumeMax}。此处指认到一个 schema 缺口:这张工单的产出是 SpecDelta(契约/schema 面),可 scopeWhitelist 只有 {files[], tables[]} 两维,圈不出「只许改这几份契约」——给主设计席的工单无法用写白名单精确约束契约面(缺口②)。走查照实标:填 scopeWhitelist.tables=["顾客类型表","存档表"] 只能勉强表达「涉及这两张表的 schema」,不能表达「涉及 source-project 契约的哪一段」。〔已闭合·终审:scopeWhitelist 增 contracts[] 维(契约路径 + JSON Pointer 锚),主设计席工单据此圈契约面,§3①。〕
第三步落在主设计席。它消费上一张 WorkOrder(六要素)、context 配方里的「系统契约」块(出处戳=契约版本号、事实)与「数据 schema」块(顾客类型表、存档表 save_state 的 schema),以及「决策史」块(对撞检查——宠物是纯新增,无历史冲突)。产出 SpecDelta(工件④):contractRef="game://nightmarket/datatables/customer_type.gold.json#/columns";contractVersionBump=minor;changes=[{op:add, path:/save/pet, rationale:宠物养成态持久化}, {op:add, path:/datatables/customer_type/columns/petInteraction, rationale:顾客类型表加互动列}];migrationNote="旧档缺省视为未解锁宠物、无需强制迁移器";saveDataImpact={changed:true, migratorNeeded:false, schemaBump:none, saveSchemaVersion:"nightmarket-save/3"}。主设计席的 harness 铁律是「规格增量必过 schema 校验器才发布」。
这一步的 saveDataImpact.saveSchemaVersion 登记面,压在一个尚不存在的东西上,走查必须如实引用而非写成已就位:§1.1.3 已坐实现行 H5 存档面是四道闸的 KV 存档,value ≤ 4KB、单 key 白名单只放行 idle:gameId:versionId,且现行 L2 save-progress 插件不带 schemaVersion 字段。标的的 save_state(三资源余额+已解锁节点+地块设备状态+员工状态+每日进度+事件历史,再加 pet 子树)早已顶破 4KB、也容不下单 key。因此 saveDataImpact 要登记的那个「带版本、能装复杂结构」的存档面,是一个前置增补需求(存档面重新定容+加 schemaVersion),走 L2 插件库通道、明确不在本单实现(§4 已挂「save-progress 现状待核」,O-6 负责落地)。这一步能产出 SpecDelta,但它承诺的存档语义要等存档面增补才真兑现(软依赖)。
第四步仍在主设计席,戴帽消费快进仿真器的输出。§2 已裁数值仿真「先工具后席」,仿真器是门/工具、不是席,v1 由主设计席读它的结果。主设计席据 context 配方里的「仿真结果」块(性质=推断、出处戳=仿真跑批 ts+局数)判断:撸猫小费加成初版若给 +30%,快进千局会不会击穿金币曲线。§3 的 DistillDelta 示例正来自这一役——+30% 快进千局即击穿、赢线提前使后期内容失去意义,于是主设计席把系数压到安全值再回写进 SpecDelta。走查在这一步指认到一处软依赖:快进仿真器可行性已由 §2.C 坐实(路 A 成立)、数值仿真席本身缓立到 v2,仿真器工具落地前,这一步只能退化成主设计席的人工判读,acceptance 里那条「经济仿真非劣化」门暂无证据源(EvidencePackage.simRunRef 是 optional 占位)。这不是设计漏洞,是已知的缓立项,如实标为软依赖。
第五步回到制作人席,此刻它消费主设计席产的 SpecDelta——关键是读到 saveDataImpact.migratorNeeded=false,据此把确认档终判为 1(additive、不顶 floor 2)。制作人席铸两张并行 WorkOrder,写白名单互不相交:
- 实现工单:
goal="顾客可与宠物互动,互动后小费系数上浮"、scopeWhitelist={files:["src/systems/pet*","src/systems/tipCalc.js","src/scenes/PlayScene.js"], tables:[]}(新文件走通配前缀、必触碰的既有文件显式列全——缺口⑤终审语义)、acceptance={gates:["九门"], machineChecks:["经济仿真非劣化"], checks:["撸猫动效可见"]}、confirmTier=1。 - 内容工单:
goal="顾客类型表加互动小费加成列并填初值"、scopeWhitelist={files:[], tables:["顾客类型表"]}、acceptance={gates:[], machineChecks:["validate_datatable"], checks:[]}、confirmTier=1。
两张白名单一个只碰宠物三文件、一个只碰顾客类型表,files/tables 维度不相交,满足工单级白名单互斥。这一步又指认到两处缺口。其一(缺口③):acceptance.gates[] 的取值域在契约对账里被锁成九门闭集(A_boot..I_control + richGame 三门),可上面两张工单的 gates 里塞了「经济仿真非劣化」和「validate_datatable」——都不是九门闭集里的门名。这说明 acceptance 的「gates=九门/checks=人判」二分不够用:非九门的机器门没有干净落点,塞 gates 破闭集、塞 checks 又不是人判。其二(缺口④):存档表 save_state 的 pet 子树是运行时状态 schema、不是内容席能填的静态表(不像顾客类型表有样例行),它的变更由 SpecDelta 登记、由实现席在 pet 系统代码里读写,不进内容席的 validate_datatable。所以内容工单的 tables 不含 save_state,实现工单的 files 含存档读写代码,scopeWhitelist.tables 的白名单机制对 save_state 不适用。〔缺口③④均已闭合·终审:acceptance 改三分{gates 九门闭集, machineChecks 非九门机器门, checks 人判},上方两张工单示例已按此写;save_state 定性为运行时存档 schema、白名单增 saveStateSubtrees[] 维承接其子树授权、其校验器 = 兼容检查器而非 validate_datatable,§1.1 清点与 §3① 同步。〕
第六步是两张工单并行执行。实现席#pet 消费实现工单(六要素+白名单 src/systems/pet*)、SpecDelta(据它知道存档加 pet 子树、小费系数改哪)、品类坑清单,产出 DeliveryPackage(工件⑤):commitHash(必须 git rev-parse 得到、反造假)、filesTouched[]、sourceProjectRef、selfTestEvidence={cmd, exitCode, summary}、journalRef。这一步撞出本场景最实的一处麻烦(缺口⑤):DeliveryPackage 示例把 filesTouched 填成 ["src/systems/petSystem.js","src/systems/tipCalc.js","src/scenes/PlayScene.js"],可实现工单 scopeWhitelist.files=["src/systems/pet*"] 只圈得住 petSystem.js——tipCalc.js、PlayScene.js 落在白名单外。而 §3 明写 filesTouched 必须 ⊆ scopeWhitelist.files(离场清账的核对面),照此离场清账会当场判这次交付越界。根子在需求本身:「撸完小费变多」这个改动天然跨文件——新增 pet 系统、改既有小费计算 tipCalc、接既有场景 PlayScene——「只圈新文件」的通配前缀白名单圈不住「新增机制必然触碰的既有文件」。要么白名单铸单时就放宽到显式列全三个文件,要么承认新增机制的白名单不能只写通配前缀。〔已闭合·终审:白名单语义钉死为「新文件通配前缀 + 必触碰既有文件显式列全」的并集展开,DeliveryPackage 校验 filesTouched ⊆ 展开集;确需越界不得静默,发升级事件(reason.code=scope_expand)改单再写,§3①⑤⑦ 同步;第五步示例已按此列全。〕
这一步还连着一个走查判不了、必须核实的点(缺口⑥,潜在硬断点):§2.A 的审计 A4 提到 tier2 的 LOCKED_PLATFORM_FILES 平台锁定文件集(含 main.js/game-core.js/layout.js 与 systems 下若干系统文件),实现席的 write_source 撞上锁定文件直接拒改。若这里的 systems/*.js 是目录级 glob 锁,实现席连自己要写的 src/systems/petSystem.js、要改的 src/systems/tipCalc.js 都会被平台锁挡住——「实现席写玩法系统」与「平台锁定 systems 目录」直接对撞,场景 A 第六步走不动。走查不能凭记忆断定它是目录锁还是仅特定文件锁(更可能是 game-core.js 结算、main.js 装载这几个特定文件锁,否则实现席无法工作),此处标为必须核实。〔已闭合·终审(源码核实):锁是 10 个显式文件路径的 frozenset 精确匹配(toolkit.py:34-45 定义、:50 以 rel in 判定),systems/ 下只锁 resource/merge/order/reachability 四个具名平台系统文件、非目录 glob——petSystem.js 与 tipCalc.js 均为新文件不在锁内,本步可写,硬断点不成立。另注:现行 mini-fei-e fixture 的分工约定(agent 只写表现层)比锁本身更窄,北极星实现席「写玩法系统文件」需要 fixture-spec 预建分工随 L3 演进——这是分工规格问题、非锁语义问题,归 L3 详设。〕
同一步里另有两处软依赖,如实标不写成已就位:journalRef 要写的「写前意图 journal」是现状缺口(实现席暂无 journal 协议),要等 §5 L1 切片补;sourceProjectRef 的寻址锚(addressingKey/versionId)压在 W-ASSET-SRC 源工程版本寻址上,而 W-ASSET-SRC 首段未排期。
与实现席并行,内容席消费内容工单(scopeWhitelist.tables=["顾客类型表"])、SpecDelta(顾客表加 petInteraction 列的 schema)、表 schema+样例行+数值曲线锚,只在 data/*.json 里给顾客类型表加互动小费加成列、填初值,产出自己的 DeliveryPackage,过 validate_datatable 校验器(不过不出席)。内容席只写表不写码,与实现席写权限天然互斥,这一步干净。
第七步,门与工具(非席位)在两份交付产物上跑,产 EvidencePackage(工件⑥):gateRunRef 指九门 verdict.json、tracePath 指本局 trace、screenshots[] 是四件套取证图、costActual={totalRmb:0.42, tokens}、simRunRef 指经济仿真非劣化产物(同样压在仿真器工具落地上)。
第八步落在评审席(盲)。它消费规格(SpecDelta)+交付包(两份 DeliveryPackage)+证据包(EvidencePackage),context 配方里刻意致盲——不注入实现会话的存在、不注入前任心路。产出 Verdict(工件②,并存形态):decision 引 tier2-verdict 的 accept/fix/kill;perCheck[] 投影 layerResults.L1.gateResults+richGameGates+findings;ftueNotes 投影 humanPlayability+play-spec firstPlay(玩家席缓立期的 FTUE 权宜项);evidenceRef 指 EvidencePackage;若判 fix 才有 fixFeedbackRef 指一份 C6 续修载荷。评审席工具面含「快进仿真器(只读)」,它读 EvidencePackage.simRunRef 判「经济仿真非劣化」——仿真器工具缺位时这条判不了,同上软依赖。
第九步回到制作人席,消费 Verdict(decision=accept),产 VersionCard(工件③):versionId/baseVersionId、baselineStamp={gatesGreen, telemetryNonRegression, qualifiedAt}、appliedIntents=[实现工单ref, 内容工单ref]、compatStamp={saveSchemaVersion:"nightmarket-save/3", compatibleFrom}、thumb+oneLiner="加了宠物,撸猫小费更多"。baselineStamp.telemetryNonRegression 依赖遥测按 versionId 切片,O-6 待核(若埋点无 versionId 维度,这一戳暂时打不出,软依赖)。
第十步,也是创作者在整条链上唯一被打扰的一步:制作人席把 VersionCard(thumb+oneLiner)连同预览版推给创作者,创作者上手玩。这落制作人席「档 1=做完给试玩,确认的最好形式是玩预览版、不是读计划」。
场景 A 结论:通,附一处机制补充条件。 十步全程可指认承接席与消费/产出工件字段,创作者被打扰点确实收敛到最后试玩一步(档 1)——这个档 1 在「confirmFloor 对 additive/breaking 细分+确认档终判推迟到 SpecDelta 产出后」这个 fable 合并期已采纳的口径下成立。走查另暴露多处 schema/配方缺口与软依赖,逐条记入 §7 台账——终审已逐条裁定:缺口②③④⑤随 schema 修补闭合,缺口⑥经源码核实闭合(文件级枚举锁、非目录 glob,硬断点不成立)。
场景 B · 从已发布版回退分叉
一句话:玩家反馈 V23 起变难,创作者说「回到 V19 那个手感,但雨天夜市那个场景(V21 加的)要留着」,这句话要走成一条以 V19 为基线、又带上雨天的新版本 V24,全程创作者只在「碰玩家存档、先问一次」这一处被打扰。
走查推演。 这一场景把 §4 的四条版本机制逐条上受力。第一步落在制作人席。它消费「用户现场快照」块承载的原话与场景注册表。这句话是复合意图——回退到 V19 + 保留 V21 的雨天。注册表里回退是 version.rollback、保留某功能重实现是 version.fork(意图重放);「回 V19 但留雨天」的本质是以 V19 为基线、把 V21 的雨天意图重放上去,落 sceneId=version.fork(route.terminalSeats=[design, impl]、defaultConfirmTier=2、confirmFloor=2 因 irreversibleSources 含 saveData、producesWorkOrder=true)。回退碰玩家存档,confirmFloor=2 焊死,这一场景注定要先问创作者一次——档 2。走查在此就答出被打扰点:场景 B 与场景 A 的档位差别,正来自「碰玩家持久化数据永远先问」。
第二步是机制一「版本卡时间线」。制作人席用只读的台账查询工具,从「功能台账投影」块(版本线)拉出 VersionCard[] 列表(全量列表在制作人席 context 的省略目录里、只给检索句柄)。呈现给创作者的每张卡是 thumb(缩略图)+oneLiner(一句人话),不是 git log。创作者据此指认 V19。这一步字段齐(VersionCard.thumb/oneLiner),走得通。
第三步是机制二「基线资格戳」。制作人席消费 V19 那张 VersionCard.baselineStamp={gatesGreen, telemetryNonRegression, qualifiedAt},确认 V19 当年门全绿(gatesGreen=true)且线上指标没劣化(telemetryNonRegression=true),坐实 V19 是一个合格基线。字段齐,但 telemetryNonRegression 依赖遥测能按 versionId 切片——O-6 待核,若埋点无 versionId 维度,这一戳的「不劣化」判不出(软依赖,§4 机制二已挂同一待核)。
第四步是机制三「存档兼容检查器」。检查器是工具、不是席,由制作人席在回退前调它。它消费三样:V19 的 VersionCard.compatStamp={saveSchemaVersion, compatibleFrom}、当前 V23 存档的 saveSchemaVersion、以及历史 SpecDelta 链里 V22 那条的 saveDataImpact(菜谱表在 V22 加过字段、changed=true)。检查器判出 V23 存档的 schema 版本高于 V19 的 compatStamp.compatibleFrom——V23 存档在 V19 打不开。到这里走查撞上本场景第一个 schema 缺口(缺口①):检查器判出「不兼容」后,§4 要求「把选项翻成人话(迁移/重置/放弃)交创作者」,可这三个选项该挂哪个工件?optionsInProductLanguage[] 在 §3 里只长在 EscalationEvent 上,而 EscalationEvent 的方向是「任一席→制作人席」、producedBy.actorKind 必须是席位(seat);检查器是工具、产不了 EscalationEvent;制作人席→创作者这个方向,九类工件里只有 VersionCard,而版本卡是「版本结果通知」、不是「回退前请你选」的决策请求。走查当时的 schema 里,「制作人→创作者决策请求」无处落——档 2 的「先问」缺工件承载。 走查照实标:逻辑清楚(检查器判不兼容→翻人话→创作者选),但承载「翻人话选项」的工件缺位。〔已闭合·终审:不加第十类工件——升级事件方向扩为「任一席→制作人席;制作人席→创作者(终端升级)」,EscalationEvent 增 presentedTo(producer/creator)与 answer{chosenLabel, answeredAt} 字段:档 2「先问」= 一条 presentedTo=creator 的升级事件,创作者的选择落 answer、status 随之 resolved,进账本可回放。理据:工件承载的是席间与升级链的交接,创作者正是升级链的终端裁决人,§3⑦。〕
第五步,创作者在档 2 做出选择(迁移/重置/放弃其一),这是场景 B 里创作者被打扰的那一次。走查要答的第三问「玩家存档迁移谁负责」在这一步分两层:创作者自己的开发存档,走 SpecDelta.migrationNote 登记迁移规格(主设计席)+实现席写迁移器代码,这条链九类工件能表达;但线上全体玩家的存档是另一回事——回退把 live 从 V23 切回 V24(≈V19)后,所有还揣着 V23 存档的真实玩家,其存档 schema 版本高于 V24,会集体不兼容。§4 的兼容检查器锚在「创作者回退前比对目标版本与当前存档」,针对的是创作者视角的单份存档,并不覆盖「回退后线上批量玩家存档降级」这个更大的面。谁负责线上玩家批量存档迁移、用什么机制,§4 与九类工件都没给(缺口⑧)。走查第三问因此只能部分作答:创作者侧迁移有主、线上批量迁移无主。〔归属已定·终审:定性为开放实装项而非 schema 缺口——v1 兼容检查器只管创作者预览与新进玩家,存量玩家批量迁移是运营窗口的人在环动作,机制随 L2 版本闭环实装另设计;前置事实(存档面定容/versionId 维度)归 O-6 核实,§4.3 已补边界句。〕
第六步是机制四「意图重放取代 merge」,也是本场景的执行命脉。「保留雨天」不走代码合并,走意图重放:取 V21 那张雨天工单的意图,在 V19 基线上重新实现、过同套验收。制作人席从 V21 的 VersionCard.appliedIntents(workOrderRef[])里取出雨天事件那张工单的 ref,拉回原始 WorkOrder 的 goal+acceptance(工单工件已持久化)。雨天在 §1.1 里是事件表 event 的一个天气类条目、连一个场景 assetId,独立可回放。制作人席据此铸新工单,goal 沿用 V21 雨天工单的 goal、deps 指向 V19 基线,交主设计席(若雨天涉及事件表 schema 增量则产 SpecDelta)+实现席(重实现雨天逻辑)+资产席(雨天场景 assetId)。约束守 §4:重放的是意图不是 diff,重实现出的代码与 V21 原实现不同是预期,acceptance 门等价才是判据。
这一步撞上场景 B 的硬前置,走查必须如实引用、绝不写成已就位:意图重放要能「按 versionId 取回 V19 的源工程、装载、在其上重新生成」。取回并重建 V19 源工程这条通道 = A3.5 版本寻址 + W-ASSET-SRC 源工程长期存储/版本寻址,而 DeliveryPackage.sourceProjectRef 的源工程寻址也压在同一处(VersionCard 本身只持 versionId,同样经 W-ASSET-SRC 按 versionId 二跳解析回源工程,不自带寻址锚)。§4 自己已挂「session 三加载路径中『加载已有工程』的 workdir 指向机制,与『按 versionId 取回重建再装载』的接缝」交 O-6 核实;而 W-ASSET-SRC 首段尚未排期。所以场景 B 的意图重放,逻辑设计完整(取意图→在旧基线重实现→过等价验收),但它的执行通道压在一个未排期的前置上——机制成立、通道未就位。
第七步,重放的三席(主设计/实现/资产)各产 DeliveryPackage,门产 EvidencePackage,**评审席(盲)**产 Verdict,判据是过 V21 原工单的同套 acceptance(验收等价)。这条与场景 A 第六到八步同构,字段齐。
第八步回到制作人席,产出 V24 的 VersionCard:versionId=V24、baseVersionId=V19(基线是 V19、不是 V23——这就是分叉)、appliedIntents=[V21 雨天工单 ref]、compatStamp={saveSchemaVersion, compatibleFrom}。走查要答的前两问在这一步撞上第二个 schema 缺口(缺口⑦)。「分叉后旧线(V20–V23)怎么标记」——VersionCard 有 versionId/baseVersionId,能表达「V24 的基线是 V19」这层父子关系,但没有任何字段表达「这条线是 live/已归档/被分叉废弃」;创作者回看版本卡时间线,哪张是当前线上版、哪条线已被 V24 取代,工件层看不出来。「live 指针何时切」——§4 定 live 指针=现行 publish 审核门后的指针切换:V24 过评审 accept 后,制作人席用「版本决策提案」工具提议切指针,走注册表的 publish 场景(producer→review 审核门→指针切、confirmFloor=2 因 liveState),审核门过了指针才切到 V24、回退=指针回切。这条流程能走通,但 live 指针本身是 game-cloud 版本域的状态(§4 映射)、不落在九类工件里,走查当时 VersionCard 也无从表达一张卡属于哪条线。〔已闭合·终审:VersionCard 增 lineId(铸卡时所属版本线,不可变);线状态与 live 指针刻意不上卡——卡是通过验收的不可变工件,active/superseded/live 是发布域与账本的可变状态,写进卡则每次切线都得回头改历史工件;创作者看到的时间线视图由账本按 lineId join 线状态呈现(哪条线活跃、哪张卡是 live 一目了然),分叉关系由「新 lineId + baseVersionId=分叉点」表达,§3③/§4.1 同步。〕走查第一、二问的答案就此补齐:切换流程有主(publish 审核门+版本决策提案),线归属在工件层(lineId)、线状态在账本视图层,各归其位。
场景 B 结论:通,带一处硬前置、三处 schema 缺口。 四条版本机制逐条可指认字段:版本卡时间线(thumb/oneLiner)、基线资格戳(baselineStamp)、兼容检查器(compatStamp+历史 saveDataImpact)、意图重放(appliedIntents→原工单 goal/acceptance)在 schema 上都接得住。但意图重放的执行通道压在未排期的 W-ASSET-SRC 首段+O-6 待核的 session workdir 接缝上。走查当时三问因三处缺口不能全答;终审后:缺口①闭合(升级事件扩 presentedTo/answer,「翻人话交创作者」有了载体)、缺口⑦闭合(VersionCard 增 lineId,线状态由账本视图承载)、缺口⑧归属已定(线上批量迁移 = L2 实装期运营机制,O-6 先核前置)。前两问经 schema 修补可答满,第三问的机制设计归 L2 实装期——硬前置(W-ASSET-SRC)不变。
场景 C · 第 N 千次修改
一句话:第 1400 次改动,创作者一句「高峰期太卡了」,这句话要先被当成一次诊断咨询(只读即答、不动一行代码),等创作者点头要修,再转成一张性能工单——而这张工单在铸造的一瞬间,必须自动撞上「第 300 次改动曾为正确性关掉渲染合批」这条决策史,拦住盲目重开旧优化。
走查推演。 第一步落在制作人席。它消费「用户现场快照」块与场景注册表,把这句话匹配到 sceneId=diagnose.query(sceneFamily=诊断咨询、route.terminalSeats 空、defaultConfirmTier=0、confirmFloor=0、producesWorkOrder=false)。producesWorkOrder=false 是这一族的定义性字段——诊断咨询只读即答、不铸工单。走得通。
第二步守制作人席「模糊请求五步」的头一条「现场快照先于追问」。制作人席消费「用户现场快照」块(性质=事实、出处戳=会话态即时),读出创作者此刻在玩哪个版本、最近触发了什么事件——「它太卡了」的「它」九成是刚碰过的东西。这里读出的是刚触发过高峰潮汐(§1.1 事件表 event 的潮汐类型)。字段齐。
第三步是遥测佐证。制作人席用只读遥测查询工具、消费「遥测摘要」块(帧率窗、按版本切片、性质=推断),坐实高峰掉帧真存在、定位在高峰渲染。这条对应 §1.1.1 那条「同屏最大顾客数 vs 帧率」曲线——它既是高峰玩法强度旋钮、也是渲染性能闸,正是这次改动的数值宿主;量级对齐 §3 LoopbackOrder 示例(帧率 P75@高峰 48fps→31fps)。软依赖同前:帧率按版本切片依赖遥测 versionId 维度(O-6 待核)。
第四步,制作人席只读即答,把「高峰渲染没分帧、掉帧与你刚触发的潮汐吻合」讲给创作者。走查在这一步撞上一个与缺口①同源的缺位:这份「诊断答复」是制作人→创作者方向、又不是版本卡,九类工件里没有承载它的一类。可论证诊断答复是同步对话、不必留痕成工件;但本节命题要求「数千次改动后 context 装配不被历史噪音淹没(账本投影)」——若诊断也要可回放、可进账本,答复就该留痕。这归入缺口①同一类,走查标出、不在此展开。〔已裁·终审:诊断答复不进工件存储——它是同步只读问答,落 trace(带 traceId)留痕即可回放,账本要引用时经 trace 检索;工件面只承载改变系统状态的交接,只读问答若工件化,账本会被咨询噪音淹没,恰与「投影不被历史噪音淹没」的命题相悖,§2.B 判读要点同步。〕创作者被打扰?此步是创作者主动问、制作人答,档 0,算不上打扰。
第五步,创作者看完诊断说「那修一下」,制作人席这才转出一张性能工单——这是第二次分诊,按注册表判读走 modify.behavior(性能优化要改渲染/玩法代码)。诊断咨询只读不铸单的口径在此兑现:工单铸造发生在创作者确认之后的这一步。到这里为止,场景 C 的前半程(诊断→只读→转工单)逐步可指认承接席与字段,走得通。
第六步是场景 C 的立身之本——决策史对撞——也是走查判定场景 C 断裂的地方。本节命题与场景注册表都明确:对撞发生在「(转出来的这张)工单铸造时」,即制作人席铸单的一瞬,要自动撞上「第 300 次改动为正确性关掉渲染合批(renderBatch)、当时有判定书」,拦住「高峰优化最直接手段=重开合批」这个会复发旧 bug 的走法。走查逐字追这个「自动对撞」怎么在 schema 上发生,撞出两道断点。
其一,对撞的时机在 schema 上落不下。§3 把承载对撞结果的 decisionHistoryHit({priorVerdictRef, conflict})字段只挂在 EscalationEvent 上;而 EscalationEvent 场景 C 示例的 producedBy.actorId 写的是「实现席#perf」(actorKind=seat)、reason.code=decision_history_conflict——也就是把对撞放在实现席执行到一半、发现要动 renderBatch 才升级上报,这比命题要求的「制作人席铸单时对撞」晚了一整个执行阶段。而 WorkOrder(工件①)自身没有 decisionHistoryHit 字段——制作人席铸单那一刻,即使想对撞,也没有字段把「本工单触及 D300 决策」这个结果记进工单。铸单时对撞在 schema 上无落点,只能退化成实现席执行时的兜底升级,与「工单铸造时自动对撞」不符。
其二,也是更硬的一道——对撞的数据基础在九类工件里根本不存在。要在铸单时(或任何时候)自动撞上「D300 为正确性关闭 renderBatch」,系统得能拿着新工单的拟改动面(renderBatch)去查一个结构化的决策史,命中一条「决策=关闭 renderBatch、受影响面=renderBatch、理由=正确性、约束=不得重开」的条目。这条决策史条目从哪来、长什么样?§3 的 decisionHistoryHit.priorVerdictRef 指向「D300 判定书」,即假定决策史=历史判定书集合。可判定书 Verdict(工件②)的字段只有 decision(accept/fix/kill)、perCheck[]、ftueNotes——它装不下「这次为正确性关闭了 renderBatch 这个可改面、且以后不许重开」这层决策语义。制作人席 context 配方虽然列了「决策史」块(出处戳=决策日志条目 ts+关联工单),但「决策日志条目」的 schema 在九类工件里没有定义,priorVerdictRef 指过去的判定书也接不住这层语义。决策史对撞所依赖的「决策史条目」这类数据,既不是九类工件的任何一类,判定书也承载不了它——场景 C 的核心机制没有数据基础(缺口⑨,含前一道对撞时机字段落点)。
走查到此如实定性:场景 C 的前半程(诊断咨询、只读不铸单、二次分诊转工单)走得通、字段可指认;但它区别于普通性能改动、也是它被选为北极星走查场景的唯一理由——「决策史在工单铸造时自动对撞、拦住重蹈覆辙」——在走查当时的九类工件 schema 下走不通:对撞的数据(决策史条目)无 schema、对撞的时机(铸单时)在 WorkOrder 上无字段。两道断点按走查纪律标断回终审。
〔已闭合·终审(缺口⑨,场景 C 据此回写为通):**不加第十类工件——约束性决定以字段形态长在既有工件上,对撞做成 harness 机械动作。**四件套:其一,判定书 Verdict 与升级事件 EscalationEvent 各增可选 decisions[]:{constraint, scope:{files[],tables[],systems[]}, rationale, standingUntil?}——约束性决定天然产生在两处,评审判定时(「合批保持关闭」随判定书落档)与升级裁决时(制作人席/创作者拍板的约束随升级事件收口落档),D300 那条即 Verdict-300#/decisions/0。其二,账本对全量 decisions[] 按 scope 维护倒排索引(决策索引)——账本本就是机器生成的投影,索引是它的一部分、不是新工件;制作人席 context 配方里的「决策史」块 = 该索引按工单拟改动面的投影。其三,WorkOrder 增 decisionRefs[]:铸单时 harness 拿工单 scopeWhitelist 机械检索决策索引、命中即自动注入——对撞是确定性检索,按「判定确定化→做成门」戒律归 harness,不设席、不靠模型自觉;冲突真伪与怎么办的判断留席位。其四,EscalationEvent.decisionHistoryHit(priorDecisionRef 指向 decisions 条目)保留为实现席执行期二道网——铸单对撞漏网(如 scope 声明不全)时,实现中撞上约束仍能升级。时机矛盾就此消解:铸单 = 制作人席 decisionRefs(一道网),执行 = 实现席 decisionHistoryHit(二道网),§3①②⑦ 同步。〕
补上对撞一步的走查:制作人席铸性能工单,scopeWhitelist.files=["src/systems/render*"];harness 以该 scope 检索决策索引,命中 Verdict-300#/decisions/0(constraint="renderBatch 保持关闭"、scope.systems=["render"]、rationale="正确性:合批引发顾客层级显示错误"),自动写入 WorkOrder.decisionRefs=["Verdict-300#/decisions/0"];实现席#perf 拿到工单即见约束,首选方案改为分帧生成顾客;若它仍试图动合批,执行期二道网升级(§3⑦ 示例正是这一幕),制作人席把两个选项翻成人话交创作者(presentedTo=creator)。每步席位、工件、字段可指认,链路闭合。
场景 C 结论:通(经终审补 schema)。 走查当时判断为断——断点二处:对撞数据(决策史条目)无 schema、对撞时机(铸单时)在 WorkOrder 上无字段;终审以「decisions[] 落判定书/升级事件 + 账本决策索引 + WorkOrder.decisionRefs 铸单机械注入 + decisionHistoryHit 执行期二道网」四件套闭合(见上),对撞一步的席位-工件-字段已补入推演。走查末问「context 装配不被历史噪音淹没」随之落地:决策史块 = 决策索引按拟改动面的投影,有了结构化源,投影不再是空话。
裁决点(本节)
标的品类=经营、复杂度锚=肥鹅美食街级,已随 W-NSTAR 立项定死;概念名与具体系统组合是填肉自由度,O-1 可改,但系统数不得低于 8、数据表不得低于 10,低了撑不开测试用例的受力面。以上骨架期裁决不变。走查在此之上追加三条,均因走查证据触及骨架冻结面,回 fable 终审:
- 场景 C 判断(已裁·终审 2026-07-06):不补「决策史条目」独立工件——约束性决定以 decisions[] 字段长在判定书与升级事件上(决定产生的两处即其落档处),账本建决策索引,WorkOrder.decisionRefs 承载铸单时机械对撞、EscalationEvent.decisionHistoryHit 保留执行期二道网。场景 C 据此回写为通。
- 场景 A 确认档口径(已签认·终审 2026-07-06):confirmFloor 对 additive/breaking 细分(additive 不顶 2)+确认档终判推迟到 SpecDelta.saveDataImpact 已知之后——N3 已将其结构化为 confirmFloorRule 字段(§2.B),细分稳,场景 A 走档 1 成立。
- 九类工件是否补第十类(已裁·终审 2026-07-06):不补第十类,以字段扩展闭合——缺口①升级事件扩 presentedTo/answer(创作者 = 升级链终端裁决人)、缺口⑦版本卡加 lineId(线状态归账本视图)、缺口⑨ decisions[]/decisionRefs 落既有工件;诊断答复(①后半)裁为 trace 留痕、不工件化。九类的「类」不动,冻结面按终审程序扩字段。
2. 席位架构初裁
命题:席位分的是结构,不是能力;v1 立 6 席,3 个〔提案〕席缓立,健康自检=席位数从此不随游戏复杂度涨。 依据分席四判据(context 食谱/写权限互斥/验证独立/生命周期)与两条不设席戒律(判定确定化→门,调度确定化→代码)逐席过尺:
| 席位 | 裁决 | 理由(命中判据)与认领胚胎 |
|---|---|---|
| 制作人席 | 立 | 分诊、工单铸造、三档确认、版本决策提案是不可归约判断;唯一面向创作者的常驻责任线。胚胎=A11 /modify/plan 两段式(判意图→确认→执行)+ 场景注册表。 |
| 主设计席 | 立(瘦版) | 场景 A 没有它就没人产规格增量与存档 schema 登记——契约变更是复杂游戏区别于模板小游戏的分水岭;且命中验证独立(实现席绝不能自改契约)。瘦版=只管两件:系统契约/数据 schema 的规格增量 + 「模糊词→可调面」映射表。 |
| 实现席 ×N | 立 | 胚胎最厚:cheap-worker/tier2 worker + RepairMiddleware + write_whitelist 全在跑。缺口只两条:工单化收窄(白名单从档位级收到工单级)+ journal 写前意图协议。 |
| 内容席 | 立 | 经营品类数据表是工作量大头,且「过校验器的数据表」大半机器可判——便宜模型档即可,写权限与实现席天然互斥(只写表不写码)。 |
| 资产席 | 立(薄) | 复用 B-ASSET-mmx provider 生成链;资产 prompt 大半可模板化(风格锚+类型模板),席只留清单执行与元数据登记的薄判断。资产规划(要哪些)归主设计席,不归它。 |
| 评审席(盲) | 立 | 胚胎=gate_judge + 九门。北极星增量:九门之上的设计符合性(L2)判读需要 LLM 评审,盲评纪律(不见实现会话)在席位层落地;判定书 schema 见 §3。 |
| 数值仿真席 | 缓(v2),快进仿真器先做成工具 | 两条戒律第一条:数值平衡判定大部分可确定化——仿真器快进跑千局出曲线是门/工具,不是席。v1 由主设计席戴帽消费仿真结果;只有「曲线好不好玩」的判断长期留席位。仿真器可行性见 §2.C。 |
| 馆长席 | 缓(v2),机器门 + 抽查代位 | 蒸馏守门 v1 量小;docs-gate/rubric-sync-gate 范式已证明查重对账可机器化。回写分道纪律 v1 就立(journal/坑增量只走自己的道),缺的只是守门人,先由 harness 查重门代。 |
| 玩家席 | 缓(v2) | 九门真玩 driver + play-spec 已覆盖「能不能玩」;persona 体验报告的价值在调优期。上线后优先接真实遥测(回流工单),合成玩家排后。权宜:评审席判定书加 FTUE 检查项。 |
一处必须先划清的边界:tier2 阶段 1 的 design_team(AgentCreate/TeamSay 星形)不违反「禁自由对话」。星形账本通信约束的是席位之间(跨工单、跨生命周期)的交接;design_team 的 worker-as-tool 是席内一次装配的内部结构——worker 生命周期在单 POST 内、不产跨席工件、其结论最终收敛为 leader 的单一产出。席间走工件,席内怎么想是席位自己的事。这条边界让现行 tier2 两阶段范式原样成为主设计席(阶段 1)与实现席(阶段 2)的胚胎,不必推翻。
每个立席的席位,都是「prompt 宪法 + context 配方 + 工具面 + harness」四层的一个版本化组合,整组落在配置控制面按 POST 现装配;四层各自的取舍是:prompt 只列判断性宪法要点(可门化、可模板化的规范不进这里);context 列承重块清单,每块标出处戳性质,并给省略目录(未推送但可检索的项);工具面列运行时应有的工具全集(即「声称面」),其与框架默认注入面的差额由 §2.A 审计逐席对账;harness 列过程壳。凡标「胚胎」处即 §2 已认领的现有落地物,配方在其上生长,不平地起楼。
制作人席(常驻,唯一面向创作者)
- prompt 宪法要点:分诊协议——把创作者一句话判成意图类 + 路由 + 风险,只判不执行;可信边界铁律(模型给的 mode 不采信,一律按意图类落路由,胚胎
cheap_classify.py:121)。三档确认判据,可逆性替代确认:档 0 静默直做(参数级、一键可撤),档 1 做完给试玩(新功能默认,确认的最好形式是玩预览版不是读计划),档 2 先问再做(仅不可逆/贵/与既往决定冲突三类)。模糊请求五步:现场快照先于追问、模糊词落设计轴、遥测佐证纠偏、收敛按序(试玩变体 > 选择题 > 追问,永不出开放问答)、判读入档。升级协议:范围失控发升级事件,不硬扛;禁技术方案——不产代码、不碰实现细节,越界即角色投影错误。 - context 配方(承重块 + 出处戳):功能台账投影(版本线/在飞工单/门态,账本机器生成、禁聊天回放;性质=事实);决策史(为什么某处不能乱动,防第 N 千次改动把第 300 次的深思当垃圾;性质=事实);遥测摘要(漏斗卡点/留存/帧率窗,按版本切片;性质=推断);用户现场快照(在玩哪版哪景 + 最近触发事件;性质=事实)。省略目录:全量版本卡列表、完整 journal、契约与数据 schema 全文——只给检索句柄,不推全文。
- 工具面(声称面,白名单):台账查询(只读)、遥测查询(只读)、账本决策索引查询(只读;缺口⑨终审件,铸单对撞的检索面)、工单铸造(create_work_order)、版本决策提案;无任何代码/写工具(范围失控在根上被断)。胚胎
cheap_classify.py:26已实践该收窄:判意图只喂三个可改面文件,连读全码都不给。运行时对账见 §2.A:制作人席是「框架默认工具与角色冲突最彻底」的一席——Service 路必须封六内建 + 剔 Planning/Team/Schedule,extra 工厂不得注入任何写工具。 - harness:场景注册表路由(§2.B),分诊按注册表驱动、新场景显式增列;两段式(判意图→前端确认→执行,胚胎 A11,同时绕开 goal-loop 的 input-required 暂停 P0);档 2 事项强制挂决策点(goal-loop 铁律:仅档 2 自动暂停),里程碑产版本卡供异步试玩;铸单时 harness 以工单 scope 机械检索决策索引、命中自动注入 WorkOrder.decisionRefs(缺口⑨终审件——对撞是确定性检索,不靠模型自觉)。
主设计席(常驻,瘦版)
- prompt 宪法要点:契约变更纪律——凡触碰存档 schema 的规格增量,必登记数据版本(落 SpecDelta.saveDataImpact,§3④);只管两件——系统契约/数据 schema 的规格增量 + 「模糊词→可调面」映射表(数据驱动使「改简单」=参数提案而非代码重写);禁写实现代码(只产规格不落码,是验证独立铁律的上游端——实现席绝不能自改契约,故契约的产与改必须独立成席)。
- context 配方(承重块 + 出处戳):系统契约(现行 contract registry,出处戳=契约版本号、事实);数据 schema(schema 版本、事实);决策史(与制作人席共源,防规格与历史决定冲突);仿真结果(只读消费,v1 由本席戴帽消费快进仿真器输出,出处戳=仿真跑批 ts + 局数、推断)。省略目录:实现细节、历史版本规格全文——给检索,不推。
- 工具面(声称面,白名单):契约注册表读写、schema 校验工具、快进仿真器(只读);无代码写。运行时对账见 §2.A:胚胎 tier2 阶段 1 design_team 是 leader + 四专家 worker-as-tool 的席内结构(席内自由、席间走工件),CLI 纯库路只拿设计 worker 工具、无框架默认工具;Service 化则同样踩 get_toolkit 坑。
- harness:规格增量必过 schema 校验器才发布(不过不出席);design_team 星形 worker-as-tool(胚胎
roles.py:66-69:纯库 import Agent 无 create_app,故星形用 worker-as-tool,leader 是唯一中心、worker 之间不互通)。
实现席 ×N(工单席,可并行)
- prompt 宪法要点:单系统职责(只在本工单白名单内动,工单级白名单比档位级更窄);诚实红线(commit hash 必须真实可 rev-parse,禁谎报 DONE、禁自评门绿);只改白名单内文件,其余保持不变、需要上下文就读不写(胚胎
cheap_toolkit.py:75-80write_whitelist basename 拒 /tier2 toolkit.py:168平台锁定文件拒)。 - context 配方(承重块 + 出处戳):单工单六要素 + 白名单文件(出处戳=工单铸造 ts、事实);品类坑清单(知识库版本、事实/经验)。省略目录:非可改面的 plumbing 文件不喂(胚胎
cheap_classify.py:25「其余 plumbing 文件不喂」),只给读句柄。出处戳纪律:三天前的构建状态与刚跑完的门结果必须能被区别信任。 - 工具面(声称面,白名单):便宜档六工具(read_file/list_dir/write_file/check/build/finish,
cheap_toolkit.py:118-121)或 tier2 九工具(scaffold_init/write_source/validate_datatable/build/headless_check/run_gates/read_verdict/screenshot/query_asset/finish,tier2 toolkit.py:368-378);写工具在工具层强制白名单(cheap write_file 校 write_whitelist / tier2 write_source 校 LOCKED_PLATFORM_FILES),build/test 只读产物,契约/门结果查询只读。运行时对账重点席(§2.A):CLI 路声称即真拿到,Service 路若不封口,框架内建 Write/Edit/Bash 完全旁路上述白名单(cheap 已双补丁封 / tier2 未封=审计 A4)。 - harness:RepairMiddleware 续修(on_reasoning 洋葱内拦 finish、注入门失败反馈续跑,胚胎已落);软预算两段式(soft_budget 档位软停不断链、hard 保底);journal 写前意图 + 离场清账——缺口:现状实现席无 journal 协议,L1 切片补(§5 L1)。
内容席(工单席,便宜档模型)
- prompt 宪法要点:数据表纪律——只改表不改码(与实现席写权限天然互斥,这是它独立成席而非并入实现席的判据);表 schema 忠实——按平台锁定的固定 key 消费,自创 schema 会让系统空转(胚胎
tier2 toolkit.py:191-197validate_datatable「自创 schema 会让合成系统空转、三联动门全挂」)。 - context 配方(承重块 + 出处戳):表 schema + 样例行 + 数值曲线锚(出处戳=schema 版本 + 曲线锚来源、事实/推断)。省略目录:代码文件、其他表全文——不喂。
- 工具面(声称面,白名单):表编辑(限 data/*.json)+ 校验器(validate_datatable);无码写。运行时对账见 §2.A:内容席是便宜档模型,Service 路封六内建尤其关键——否则内建 Write 可写码文件,「只改表」的互斥被击穿。
- harness:校验器不过不出席(validate_datatable 门;可达性不变量:合成链非空/DAG/订单可达)。
资产席(工单席,薄)
- prompt 宪法要点:风格锚忠实、元数据完整;资产规划(要哪些)不归它、归主设计席,本席只做清单执行与元数据登记的薄判断。
- context 配方(承重块 + 出处戳):资产清单工单 + 风格锚 + 包体预算(出处戳=工单 ts + 风格锚版本、事实)。省略目录:全量资产库、其他类目——给检索(query_asset 按类目查,不感知底层 provider)。
- 工具面(声称面,白名单):mmx 生成 + 登记(胚胎 B-ASSET-mmx provider +
tier2 toolkit.py:295-308query_asset 占位,「只查/取引用,不生成」);无逻辑写。 - harness:体积门、命名规范门(双端分包上限逼资产走体积门,§1.1.3)。
评审席(工单席,盲)
- prompt 宪法要点:判定纪律——只认证据,不认自述(run_gates/read_verdict 的 verdict 由 judge 纯代码产出,不采信 agent 上报,胚胎
tier2 toolkit.py:16「验收零自评」+ gate_judge 归一契约);刻意致盲——context 配方里不含实现会话的存在(出题的不能是被考的;继承推理等于继承盲区)。 - context 配方(承重块 + 出处戳):规格 + 交付包 + 证据包(出处戳=门跑 ts + commit hash、事实);刻意致盲块——不注入实现会话、不注入前任心路,修复轮只给「上一版代码 + 门失败证据」;失败必带 phaseNow(游戏此刻卡在哪个 phase,胚胎
gate_judge.py:121_latch_phase_now,两条失败支都认)。 - 工具面(声称面,白名单):只读 + 九门(run_gates/read_verdict)+ 快进仿真器(只读);零写工具。运行时对账见 §2.A:评审席是「必须封框架默认工具」理由最硬的一席——它绝不能拿到任何写工具,更不能拿到 Team/AgentCreate(spawn worker 会破盲评隔离、让 worker 看见实现会话);Service 路双补丁对评审席不是可选优化,是致盲纪律在工具层的落地。
- harness:fresh 会话(异档模型当多样性来源,缓解同源风险);判定书 schema 强制(§3② 并存形态);失败必带 phaseNow。
配方密度镜像原则:便宜模型席位(内容席、部分实现席)零裁量、全铺开;贵模型席位(制作人、主设计、评审)给索引让它自拉。这条随席位模型档位调,不是每席一刀切。
2.A 框架默认注入面审计
设席八问的第八问——「框架默认注入的能力面审计过、与白名单对账了吗」——骨架期统一记为未过,由本节逐席补。一句话结论:在 AgentScope Service 路上,一个席位运行时真正拿到的工具面,不等于它配方里声称的那几个工具,而是「声称的 N 工具 + 15 件框架默认工具」;这 15 件里含能写任意路径的内建 Bash/Write,足以旁路任何一席在自己工具层焊死的写白名单。 对账不做,配方就是一纸空文。
2.A.1 框架默认注入面从哪来:get_toolkit,不是 build_toolkit
AgentScope 2.0 有两条把 Python 函数变成 agent 工具的路径,受力面完全不同:
- CLI 纯库路(
Agent(toolkit=...),无 create_app):toolkit 就是项目自己 build_toolkit 的产物,agent 拿到的工具 = 显式声明的那几个,一件不多。cheap CLI = 六工具(cheap_toolkit.py:118-121),tier2 CLI = 九工具 + 可选 MCP(tier2 worker/toolkit.py:368-397)。声称面 = 运行时面,无旁路。凭据:roles.py:66-68明示「本线是纯库 import Agent 跑脚本(无 create_app)」;ws_builtin_tools_patch.py:10明示「CLI 路从来只有六工具」。 - Service 路(
create_app,多租户/多会话/REST+SSE):agent 由框架在每个 chat 回合内部装配,装配的唯一入口是get_toolkit(app/_service/_toolkit.py:27)。项目的九/六工具只能经extra_agent_tools工厂合进框架自建 toolkit 的 basic 组(cheap_service_app.py:459/tier2 service/app.py:277),而框架在合并你的工具之前,已经无条件并入了一整套默认工具。
get_toolkit 无条件并入的清单,逐行坐实(2.0.2 源码,app/_service/_toolkit.py):
| 组 | 工具 | 源码出处(2.0.2) | 条件 |
|---|---|---|---|
| workspace 内建 ×6 | Bash / Edit / Glob / Grep / Read / Write | :107 tools = await workspace.list_tools();定义在 workspace/_local_workspace.py:670-679(硬编码无开关) |
无条件 |
| Planning ×4 | TaskCreate / TaskList / TaskGet / TaskUpdate | :110,注释 :45「Planning tools — always on」 |
无条件 |
| Background ×1 | ToolStop | :113 background_task_manager.list_tools(...) |
无条件 |
| Schedule ×4 | ScheduleCreate / View / Delete / List | :119-142(schedule_tools 组) |
session 配了 chat_model_config 时 |
| Team ×4 / ×1 | source≠team:TeamCreate / AgentCreate / TeamSay / TeamDelete;source=team:仅 TeamSay | :157-168(按 agent_record.source inline 选) |
无条件(变体) |
即:一个未封口的 Service 席位,除了自己那几个工具,还平白多出六内建 + 4 Planning + 1 ToolStop + 4 Team = 15 件无条件默认工具(session 配 chat_model_config 时另加 4 件 Schedule 条件工具组,条件态 19 件)。〔fable 合并期裁定·终审签认 2026-07-06:正名——此无条件并入的主语是框架 get_toolkit,不是项目 build_toolkit(后者只显式组装、从不并入内建);Service 路 15 件无条件并入(Schedule 条件注入不计),纯库 CLI 路无此并入。〕
2.A.2 这些默认工具里,哪些是可击穿平台锁定的默认工具
不是这些默认工具同样危险,分三档:
- 可击穿写边界的默认工具(必须封):内建 Bash / Write / Edit。它们不经任何一席的写白名单——cheap 的六工具白名单和 tier2 的 LOCKED_PLATFORM_FILES 都焊在各自工具里,而框架内建 Write 是另一个工具、根本不过这道检查;更狠的是内建 Bash 的 cwd 是 Service 工作区、可越 workdir 触仓外(
ws_builtin_tools_patch.py:8)。这一档直接击穿护城河。 - 噪声/行为歪引(应封):Planning×4、Team×4、Schedule×4(其中 Schedule×4 仅 session 配 chat_model_config 时条件注入、不计入无条件 15 件,条件态才现)。便宜档是单机单游戏,无团队、无定时任务、不需要 agent 自管任务板;12+ 语义重叠的工具是 M3 flail(反复空转、选错工具)的根因之一(80011 生产实录)。无关工具 schema 既是注意力污染也是行为歪引。
- 低风险残留(可留):Background ToolStop。它是 harness 过程控制、不碰写边界;cheap 封口后有意保留。审计如实登记它是「配方未声称、运行时拿到」的一件,但不建议改。
2.A.3 逐席对账:声称 vs 运行时真拿到
| 席位 | 配方声称工具面 | CLI 路运行时 | Service 路运行时(未封口) | 现状封口 |
|---|---|---|---|---|
| 制作人 | 台账/遥测查询 + 工单铸造,无写 | 胚胎在 A11(两段式 CLI) | 声称 + 15(含内建 Write/Bash,与「无代码工具」直接冲突) | 未落 Service;落时必须封 |
| 主设计 | 契约读写 + schema + 仿真读,无码写 | design_team 纯库、无框架默认(roles.py:66) |
声称 + 15(Team 组尤其冲突:主设计不该 spawn 实现 worker) | 未落 Service |
| 实现 ×N | 白名单内写 + build/test + 只读查询 | cheap 六 / tier2 九,声称=真拿到 | 声称 + 15,内建 Write 旁路 write_whitelist / LOCKED_PLATFORM_FILES | cheap 已封;tier2 未封(A4) |
| 内容 | 表编辑 + 校验器,无码写 | 胚胎在 tier2 validate_datatable | 声称 + 15,内建 Write 可写码文件、破「只改表」互斥 | 未落独立 Service |
| 资产 | mmx 生成 + 登记,无逻辑写 | 胚胎在 query_asset | 声称 + 15 | 未落独立 Service |
| 评审(盲) | 只读 + 九门 + 仿真读,零写 | gate_judge 纯代码 | 声称 + 15,内建 Write 破零写 + Team/AgentCreate 破盲评隔离 | 未落 fresh Service |
一处必须点名的:cheap Service 路已用两个进程内 monkeypatch 封口(apply 序见 cheap_service_app.py:435→443):ws_builtin_tools_patch 把 LocalWorkspace.list_tools 换成恒返 []、关掉六内建;planning_team_tools_patch 包装 get_toolkit、拿到装配好的 Toolkit 后重建干净版,按 .name 剔 Planning×4 + Team×4、丢掉整个 schedule_tools 组。封口后 cheap Service 净工具面 = 六工具 + ToolStop + skills/MCP,与配方声称面基本收敛。这两个补丁都钉 2.0.3、绝不改 venv 本体、版本漂移时响亮告警但仍应用(不应用等于开着白名单旁路,比契约漂移更危险)。
2.A.4 审计发现 A4:tier2 Service 路未封口,平台锁定被旁路
证据链:① tier2 service/ 下 grep 不到任何封口补丁(零命中);② tier2 service/app.py:106-111 的 _extract_function_tools 注释白纸黑字写明有意保留框架工具面(「本壳不想绕过框架自建 toolkit……所以取折中:从 tier2 Toolkit 里取出九个 FunctionTool 实例,交给框架合并」);③ tier2 的 LOCKED_PLATFORM_FILES(10 个平台锁定文件的 frozenset 精确匹配:main.js 装载胶水 / game-core.js 状态机结算 latch / layout.js / tables.js / seeded-random.js / play-runtime.js,及 systems 下 resource·merge·order·reachability 四个具名系统文件——文件级枚举、非目录 glob,tier2 worker/toolkit.py:34-45 定义、:50 判定;缺口⑥终审据此核实闭合)只在 tier2 自己的 write_source 里强制(toolkit.py:160-175),框架内建 Write/Edit/Bash 不经此检查。
主张:tier2 Service agent 运行时可以用框架内建 Write 直接改写 src/main.js 的装载胶水,旁路 LOCKED_PLATFORM_FILES,复现 cheap 侧已被封的同款写边界击穿。现状 tier2 Service 是 spike(服务态干净复跑未完、CLI 线为主),敞口尚未在生产爆发;但北极星 §5 L3 明确要把 tier2 多席 Service 化,届时每一席都会默认继承这 15 件、每一席的写/致盲护城河都在 Service 路失效。
〔fable 合并期裁定·终审签认 2026-07-06:采纳——§5 L3 验收门已显式加一条「tier2 Service 各席工具面已对账封口(内建写工具关、Team 组按席致盲)」,否则 L3 的「盲评审 fresh 会话」在工具层是假盲。终审裁定:门保持归 L3(管多席化面);tier2 服务态转正的现网前置由 W-T2LOCK 止血单承担(见下),两不迁就。〕
tier2 Service 写锁的现网止血已另立 W-T2LOCK 单先行(作战清单 2026-07-06,源出本审计 A4):它不剥工具面,只在框架内建写类工具层对锁定文件写操作 fail-closed,是补丁形态的止血;待 L3 统一「席位工具面白名单」中间件(§2.A.5)落地,W-T2LOCK 并入其中退役。
2.A.5 收窄该每席重贴补丁,还是框架层统一开关
现状是「每个 Service 席位各贴各的进程内 monkeypatch」。cheap 用两个补丁封一个便宜档单席;北极星要立六席,若沿现状,等于六套 monkeypatch × 版本漂移复核成本,且每套都依赖对 get_toolkit 未公开内部结构的假设——AgentScope 每升一个补丁版就要逐条复核。
〔fable 合并期裁定·终审签认 2026-07-06:方向已定——统一「席位工具面白名单」中间件为设计基线:一处声明每席准入工具名单、在 get_toolkit 产出后统一过滤,取代六套散补丁,把「席位=工具面白名单」这条 §0 原则真正焊进一处单源。向 AgentScope 提工具面开关的 upstream PR 可并行推进、但设计不依赖它(PR 是优化,中间件是基线)。终审裁定:中间件落 tier2/gen-worker/service 装配层(get_toolkit 产出后统一过滤),漂移纪律沿 cheap 补丁成例(钉版本、漂移告警仍应用);具体实现随 L3 详设。〕
2.B 场景注册表契约草案
交互场景清单本身是契约,不是 prompt 里的一段话。制作人席怎么分诊、一句话落到哪个下游席、要不要先问创作者、埋什么点复盘——这四件事一旦写进 prompt,就会随每次改 prompt 悄悄漂移;写成注册表,新场景就得显式增列一行、过一次评审,分诊按表驱动。本节把需求基线的八个场景族展成 contracts 形态:先定信封 schema,再逐场景登记四要素。落 contracts/agentic-artifacts/scene-registry.schema.json,与 §3 的九类工件同一子域——场景分诊的产物就是工单(§3①),两者共享席位枚举与 traceId,同域单源省一次跨目录对账。走 contract-first:本草案只冻字段骨架与示例,校验器与正负样本随实现波按 Δ5「无校验器不算契约」补。
schema 骨架。 注册表 = 场景条目数组,每条目是一个分诊路由规则:
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| sceneId | string | ✓ | 稳定标识,点分命名空间(如 modify.behavior、version.rollback);分诊器输出它,遥测按它归类 |
| sceneFamily | enum(8) | ✓ | 立项创作 / 修改 / 版本操作 / 目标委托 / 诊断咨询 / 运营变现 / 素材管理 / 打断接管 |
| intentClass | string | ✓ | 意图类,全局命名空间→现行 cheap_classify 六类的分层映射(见下 D4);分诊 LLM 判它,可信边界=按 intentClass 落路由、不采信 LLM 自报的执行 mode(cheap_classify.py:121) |
| route.entrySeat | enum(seat) | ✓ | 入口席,恒 producer(制作人席)——唯一面向创作者的常驻线 |
| route.terminalSeats | enum(seat)[] | ✓ | 终端承接席,取值域 = 六席(producer/design/impl/content/asset/review);诊断咨询等只读场景为空 |
| defaultConfirmTier | 0|1|2 | ✓ | 分诊建议的默认确认档;工单铸造(§3① confirmTier)可按 payload 收紧、不可放松 |
| confirmFloorRule | {baseTier, irreversibleSources[], saveDataPolicy:{additive:"no-raise", breaking:"tier2"}} | ✓ | 硬地板规则(不是定值,铸单时求值):baseTier 起判;irreversibleSources[](money/saveData/liveState/budget)命中 money/liveState 直接把地板顶到 2、saveData 命中按 saveDataPolicy 细分——additive(旧档缺省可读)no-raise 不顶、breaking(migratorNeeded=true)顶到 tier2;确认档终判推迟到 SpecDelta.saveDataImpact 产出后落值 |
| producesWorkOrder | bool | ✓ | 是否铸工单;诊断咨询为 false(只读即答),打断接管为 false(控制流) |
| controlFlow | bool | 标记该条目是控制流而非意图(打断接管=true);分诊器据此认得「这是打断信号、不是新需求」 | |
| telemetryEvent | string | ✓ | 遥测事件名,camelCase,进 events.schema.json 的 eventRegistry;每次分诊落一条、带 traceId |
| clarifyOnAmbiguous | bool | ✓ | 意图不明是否回问澄清(对应 cheap_classify 的 unclear→回问,不静默判成可执行改动) |
一条示例(场景 A,追加宠物系统):
{
"sceneId": "modify.behavior",
"sceneFamily": "修改",
"intentClass": "behavior",
"route": { "entrySeat": "producer", "terminalSeats": ["design", "impl"] },
"defaultConfirmTier": 1,
"confirmFloorRule": {
"baseTier": 0,
"irreversibleSources": ["saveData"],
"saveDataPolicy": { "additive": "no-raise", "breaking": "tier2" }
},
"producesWorkOrder": true,
"telemetryEvent": "sceneModifyBehavior",
"clarifyOnAmbiguous": true
}
宠物系统碰存档 schema(顾客类型表加互动列),故 confirmFloorRule.irreversibleSources 含 saveData;但按 SpecDelta.saveDataImpact 判定这是 additive(旧档缺省视为未解锁宠物、无需迁移器),故 saveDataPolicy 走 no-raise、地板不顶 2、走档 1——只有当存档变更为 breaking(改删字段、旧档失效)才顶 2。这正是「可逆性替代确认」落到字段级的样子:同一场景,additive 走档 1、breaking 走档 2,且确认档终判推迟到 SpecDelta 已知之后。
全场景登记表。 八族逐条展开,terminalSeats 用六席简称(producer 制作人 / design 主设计 / impl 实现 / content 内容 / asset 资产 / review 评审)。「确定性 modify」指现状 cheap_modify 的纯代码执行路(资产/数值/关卡三类可确定化落点,cheap_classify.py:21 _DETERMINISTIC_CATEGORIES),不必经实现席 LLM。
| sceneId | 族 | intentClass | terminalSeats | defaultTier | floor(不可逆源) | 铸单 | telemetryEvent |
|---|---|---|---|---|---|---|---|
| create.project.fromPrompt | 立项创作 | create | design→impl→content→asset→review | 1 | 0 | ✓(goal-loop) | sceneProjectCreate |
| create.project.fromTemplate | 立项创作 | create | impl→content→asset→review | 1 | 0 | ✓ | sceneProjectCreateFromTemplate |
| modify.asset | 修改 | asset | asset(或确定性 modify) | 0 | 0 | ✓ | sceneModifyAsset |
| modify.config | 修改 | config | content(或确定性 modify) | 0 | 0 | ✓ | sceneModifyConfig |
| modify.content | 修改 | level | content | 1 | 0 | ✓ | sceneModifyContent |
| modify.behavior | 修改 | behavior | design→impl | 1 | 2(saveData 且 breaking) | ✓ | sceneModifyBehavior |
| modify.meta | 修改 | meta(新增) | producer(直改) | 0 | 0 | 视情 | sceneModifyMeta |
| version.rollback | 版本操作 | version.rollback | producer(指针+兼容检查器) | 2 | 2(saveData·恒 breaking) | ✓ | sceneVersionRollback |
| version.fork | 版本操作 | version.fork | design→impl(意图重放) | 2 | 2(saveData·恒 breaking) | ✓ | sceneVersionFork |
| version.browse | 版本操作 | version.browse | —(只读时间线) | 0 | 0 | ✗ | sceneVersionBrowse |
| goal.delegate | 目标委托 | goal.delegate | design→impl→content→asset→review | 1 | 2(budget 超阈时) | ✓(goal-loop) | sceneGoalDelegate |
| diagnose.query | 诊断咨询 | diagnose.query | —(制作人只读即答) | 0 | 0 | ✗(确认后转工单) | sceneDiagnoseQuery |
| monetize.config | 运营变现 | monetize.config | producer(变现位表) | 2 | 2(money) | ✓ | sceneMonetizeConfig |
| publish | 运营变现 | publish | producer→review(审核门)→指针切 | 2 | 2(liveState) | ✓ | scenePublish |
| asset.manage | 素材管理 | asset.manage | asset | 1 | 0 | ✓ | sceneAssetManage |
| control.interrupt | 打断接管 | control.interrupt | —(harness 级,插单重排) | n/a | n/a | ✗(controlFlow=true) | sceneControlInterrupt |
几处判读要点,不是表格能承载的:
- 修改族按对象切场景,动词进 payload。修改族是「对象(资产/数值/内容/机制/meta)× 动词(改/增/删/调/回退)」的矩阵;若每个对象×动词各立一场景,25 格爆炸且无意义——分诊真正要分的是「落到哪个席、哪个可改面」,这由对象决定,不由动词决定。故按对象切五个 modify.* 场景,动词收进工单 payload 的操作类型;唯一例外是「回退」,它不落原对象的可改面、而是整版回退,故单独归版本操作族(version.rollback)。这与现状 cheap_classify 一致——它也只按 category(对象)分类、不按动词。
- 修改族对着 cheap_classify 现状长。asset/config/level 三类命中确定性执行路(纯代码改一处键→值/常量,defaultTier 0、可逆一键撤),behavior 类命中模块重生成(过实现席 LLM 重写玩法文件)。现状分类器已把「危险/大改/改玩法/意图不明一律回问确认」焊死(
cheap_classify.py:122,创始人 2026-06-28),这条直接落成 clarifyOnAmbiguous=true + behavior 类 defaultTier≥1。 - 诊断咨询不铸工单是硬约束。「为什么高峰期卡」先给现场快照 + 遥测佐证判读,只读即答;创作者看完确认要修,才由制作人转一张性能工单(那是另一次分诊、走 modify.behavior)。producesWorkOrder=false 是它区别于修改族的定义性字段——省掉它,诊断问句会被误铸成工单。诊断答复本身落 trace 留痕、不进工件存储(终审裁定,§1.2 场景 C 第四步)。场景 C 的决策史对撞发生在「转出来的那张工单」铸造时,不在诊断这一步——机制 = 铸单 harness 检索决策索引注入 WorkOrder.decisionRefs(§3①)。
- 运营变现与版本回退共享档 2 地板,但不可逆源不同:变现是 money(碰钱),发布是 liveState(碰线上),回退/分叉是 saveData(碰玩家存档——回退真雷是存档不是代码,§4)。碰钱、碰线上永远先问;碰存档一般按 breaking/additive 细分,但回退/分叉是整版切换、必触 breaking 语义(旧存档在目标基线上打不开),故 version.rollback/fork 恒档 2、无 additive 例外。
- 打断接管不是意图、是控制流。它 producesWorkOrder=false、controlFlow=true、terminalSeats 空、confirmTier n/a——登记它是为了让分诊器认得「这是打断信号,不是新需求」:当前工单跑完或干净中止(journal 收口),插单重排,账本无损恢复(goal-loop 铁律)。它保留在注册表、以 controlFlow 标记与意图类区隔。
- 端别边界(v1 范围):注册表 v1 只覆盖 H5 运行主端的版本/发布场景;渠道端(微信/抖音)版本操作走人在环单游固化导出,是月级挑版提审、不经分诊路由(§1.1.3 E、§4 端别边界)。故 version.*/publish 各场景默认对 H5 主端成立,渠道端不由分诊器接管。
全局意图类 ↔ cheap_classify 现状六类映射。 cheap_classify 现役六类(cheap_classify.py:22 _VALID_CATEGORIES)是修改族的局部命名空间,注册表按下表把它们映射到全局场景意图类;其中确定性三类(asset/config/level)命中纯代码执行路,behavior 过实现席 LLM,末两类不落独立 modify.* 场景:
| cheap_classify 六类 | 全局映射 | 说明 |
|---|---|---|
| asset | modify.asset | 确定性执行路(改一处 assets.js 键→值),defaultTier 0 |
| config | modify.config | 确定性执行路(改 core.js 常量),defaultTier 0 |
| level | modify.content | 确定性执行路(关卡数据),defaultTier 0 |
| behavior | modify.behavior | 模块重生成、过实现席 LLM 重写玩法文件,defaultTier ≥1 |
| big-change | (无独立场景)→ 升级事件 / 档 2 路径 | 换品类、整体重做、推倒重写、清档重置(cheap_classify.py:77)已超出局部调整,不落 modify.*,升级到制作人席按新立项或档 2 不可逆确认处置 |
| unclear | (无独立场景)→ clarifyOnAmbiguous 横切开关 | 意图不明、定位不到具体一处(cheap_classify.py:78),绝不静默判成可执行改动,由 clarifyOnAmbiguous=true 回问澄清、不铸独立场景 |
裁决点(本节)〔fable 合并期裁定·终审签认 2026-07-06〕:
- 〔D1 路由席位双值〕采纳——拆成 route.entrySeat(恒 producer)+ route.terminalSeats[];入口恒是制作人席、真正的路由差异在终端承接席,单值字段无法同时表达「谁先收」和「派给谁」。
- 〔D2 confirmTier 从属〕采纳——场景给不可放松的地板:defaultConfirmTier 是分诊建议默认、confirmFloorRule 是硬地板规则,工单铸造的 confirmTier 只能升不能降;碰钱/碰线上地板 2,碰存档按 breaking/additive 细分(回退/分叉恒 breaking、恒 2),确认档终判推迟到 SpecDelta 已知后(缺口⑩口径)。
- 〔D3 打断接管归属〕采纳——保留在注册表、标 controlFlow=true,分诊器单一入口认它、不误判成新需求。
- 〔D4 意图类命名空间〕采纳分层映射——不动现行 cheap_classify 分类器契约:修改族沿用现状六类(asset/config/level/behavior/big-change/unclear)为局部命名空间,其余族用族级前缀(create/version./goal.delegate/diagnose.query/monetize.),注册表做全局意图类→现状六类的映射。终审签认:映射表已覆盖现状六类全量(asset/config/level/behavior/big-change/unclear),完整。
2.C 快进仿真器可行性
数值平衡判定要回答的是一句很具体的话:一组菜价、耐心、解锁曲线摆下去,顾客流、金币流、解锁节奏会不会击穿——太松则一路躺赢无张力,太紧则开局即劝退。这个判断的绝大部分是确定性的:给定数据表和一套玩家打法,经济曲线是算得出来的,不需要人反复真玩几百局去感觉。所以它先落成工具而非席位(§2 已裁「先工具后席」)。工具走哪条路,归结为一个取舍:是让工具去跑真游戏的逻辑(路 A),还是把数据表抽出来在一个独立仿真器里另算一遍(路 B)。
路 A · 工程离屏快进。结论:成立,且是现有 runtime 上增量最小的一条——两档引擎的逻辑层都已具备「脱引擎、受控时钟、可观测」三件套,tier2 更已有跑通的单局雏形。离屏快进靠三个已经落地的性质:
其一,逻辑层与渲染、与真实时间都是解耦的。轻档 LittleJS 的宿主把「推进一帧」实现成纯同步循环:stepFrames(n) 就是 for 里调 n 次 stepOneFrame(game-runtime/src/host/boot-game-host.js:328-329),每步先把受控时钟 mockNowMs 自增一个固定步长再调 game.update,而 game.render 只在有可见画布上下文时才走(同文件 :319、:322)。node 环境下没有可见画布,render 整条被跳过,一帧只剩纯逻辑计算。游戏本体也守同一纪律:update(dt) 吃外部传入的 dt、与 render(g) 分成两个方法(game-runtime/games/_template-shop/src/game-logic.js:213、:226),局内计时是 elapsedMs += dt*1000 累加出来的、不读墙钟。定时器同理——timer-scheduler 到期检查读受控时钟、「无帧不推进」是硬保证(game-runtime/src/plugins/timer-scheduler/impl.js:88)。喂多大的 dt、连着喂多少帧完全由调用方定,一局 60 秒的营业在墙钟上可以零点几毫秒跑完。
其二,逻辑是纯的、随机是受控的,所以可复现。轻档 core.js 的顾客生成节奏、耐心衰减、命中判定全是无副作用纯函数,随机经入参 rng 注入、零 Math.random/Date.now(game-runtime/games/_template-shop/src/core.js:6-7、:68-69),这一层 node 直接单测,实测 8/8 通过。tier2 富档的 game-core.js 同样按「零 DOM/canvas/引擎、时间经 update(dtSeconds) 注入、随机经受控源」的铁律写(tier2/fixtures/mini-fei-e/src/game-core.js:18),它的可达性/无环校验模块更明说「纯数据推演,故能脱离真玩快筛」(tier2/fixtures/mini-fei-e/src/systems/reachability.js:5;2026-07-06 卡牌书评审波核正原引 reachability.js:15-16 的路径与行号漂移)。可复现是仿真的前提——同一组表、同一 seed、同一打法跑一千遍结果一致,曲线才可比。
其三,输入不用真人合成,自动 driver 读可观测状态自己出招。游戏经 _forensicsView().state() / readState() 导出语义状态(轻档 game-logic.js:247,富档 game-core.js:110-147,后者把棋盘、订单、合成链、交单坐标投影成 driver 契约形状),driver 读它自适应出招而非盲打坐标。tier2 的 business-sim.driver.js 就是经营品类的确定性驱动器,赢路径把金币从 20 推到 ≥100、破产路径放任订单流失(business-sim.driver.js:9-13);logic-smoke.mjs 的 driveWinLoop 是同一思路的 node 版纪律玩家。
把三件套接起来,tier2 侧已经是一个跑通的单局仿真:logic-smoke.mjs 无浏览器、createGameCore 脱引擎、自动 driver 驱动、赢局(上限 8000 帧)与输局(5000 帧)双路跑到 latch 终态并读经济结果——整个脚本含 node 冷启动实测 real 0.03s(node v22.22.3)。墙钟估算(外推):这 30 毫秒里 node 冷启动占大头(可比照 core.test 8 个纯函数耗 51 毫秒);在单进程内循环、冷启动只付一次,tier2 mini-肥鹅复杂度跑一千局落在秒级到十秒级;北极星标的系统数更多、单局逻辑更重,即便单局成本涨一到两个数量级,千局仍在分钟级墙钟内。精确值要一次 spike 实测坐实,但量级不构成障碍——这与「反复真玩几百局」的人力墙钟差着好几个数量级,正是「先做成工具」的立论所在。
可复用的九门 harness 件,与用不上的那半: 直接复用逻辑侧全套——_forensicsView/readState 可观测契约、driver 库(经营品类 business-sim.driver.js 现成)、seeded-random 受控随机、timer-scheduler 受控时钟、latch 终态轮询判定。用不上、也不该拉进来的是浏览器那半:CDP 触摸下发、像素回读、canvas 哈希、起 serve+chrome 的编排(game-e2e-cdp-harness.md §1-2 的九门是为「真玩取证」设计的,要证渲染、手感、输入到达画布)。边界一句话:九门证「这一局真能玩、玩起来对」,快进仿真答「这套数值跑一千局会不会崩」——共享逻辑内核与 driver,分走浏览器与批量两端。
路 B · 抽数值表独立仿真。结论:静态结构判定这一层可行且已存在,应保留作前置门;但动态时序仿真这一层是对现有游戏逻辑的重复实现,注定与工程漂移、且保真度天花板低,不推荐作为主体。 路 B 的最大顺风,是数据表化的前提已满足:tier2 的权威数据表是 data/datatable.gold.json、过机器校验,含开局货币/库存、物品、合成链、订单、赢线输线全套。问题出在抽出表之后:路 B 要「在纯仿真器里跑这张表出经济曲线」,而跑表所需的经济动力学(顾客到达怎么排队、合成怎么消耗库存、订单耐心怎么衰减、金币怎么累积与门控)已经在 game-core.js 的三系统(resource/merge/order)里实现了一遍——独立仿真器等于把这套逻辑再抄一份,两份各自演进迟早对不上,正是项目「拒绝孤儿/拼接、单一数据源」红线要防的。保真度天花板也在这里:经营品类里空间摆放是核心系统(桌椅设备摆放影响吞吐,§1.1 街区扩张),独立数值仿真器摆不了桌子,任何「逻辑与空间/表现耦合」的机制它都仿不了。路 B 真正站得住的,是退化到纯静态结构判定那一层——reachability.js 就是现成实例:从开局食材沿合成链做不动点迭代算可达集,再校验每个订单要的物品都可达、合成链拓扑无环。这类「有没有订单要一个永远合不出来的东西」「解锁树有没有死环」读表就能筛出,极轻、不与动态逻辑重复,该保留,但它答不了「数值是否击穿」。
| 判据 | 路 A 工程离屏快进 | 路 B 抽表独立仿真 |
|---|---|---|
| 保真度 | 高——跑真游戏逻辑,唯一近似是「玩家水平」(自动 driver 是纪律最优,曲线偏乐观,可多档策略缓解) | 动态层低——空间摆放/表现耦合的机制仿不了;静态结构层准 |
| 速度 | 千局秒级到分钟级墙钟(单局实测锚点 30ms 含冷启动,外推) | 更快(纯算式),但要先重写动力学才能跑动态曲线 |
| 实现成本 | 最小——tier2 已有 logic-smoke 单局雏形,增量=参数扫描外层 + 曲线聚合;轻档需补一个同形态 node 驱动脚本(机制齐备) |
动态层高且漂移(重写三系统);静态层已存在(reachability) |
| 与「内容席只写表」亲和 | 天然吻合——游戏逻辑不变、只换数据表跑千次,正是主设计席/数值判定要消费的形态 | 同样吃表,但跑的不是真逻辑,曲线可信度打折 |
推荐路 A,并把路 B 的静态判定收编为它的前置门,不作二选一。 完整形态两段:先用 reachability 式静态推演快筛结构性击穿(几毫秒淘汰「订单要不可达物品」这类硬坑),再用离屏快进跑动态经济曲线。路 A 压倒路 B 的核心是它跑真逻辑——数值平衡最怕「仿真器里没崩、真游戏里崩了」,而路 A 与真游戏共享同一份逻辑内核和数据表,不存在第二份会漂移的动力学;路 B 要抽的那张表,正是路 A 换着跑千次的输入轴。
前提与保真度边界(如实登记,非阻断): 离屏快进绑定一条纪律——被测游戏逻辑必须像 game-core.js/轻档 core.js 那样纯逻辑脱引擎、update(dt) 注入时间、经 readState/_forensicsView 暴露经济状态,这条 3 层架构(L3 逻辑纯净)和 tier2 平台预建已在强制。风险敞口在空间摆放类系统(桌椅设备吞吐最容易把逻辑塞进表现层),一旦耦合就快进不了。第二条边界是自动 driver 的玩家水平:driver 是纪律最优打法,跑出的曲线是「高手上界」、偏乐观;要覆盖真实人群需多档策略 driver(菜鸟/中手/高手)扫、取曲线包络。
裁决点(本附节)〔fable 合并期裁定·终审签认 2026-07-06〕:两路并非都不可行(路 A 成立),故不触发「数值席提前转正」——快进先工具的路线坐实,数值仿真席维持 §2 缓立(v2)。两处保真度边界,创始人 2026-07-06 已拍:
- 空间摆放类系统纳入快进仿真:L3/L4 切片硬约束「空间吞吐逻辑也走
update(dt)纯逻辑层、不耦进渲染」,以守纪律换全覆盖(加重 L3 系统设计约束,已认这笔账)。 - driver 档位:L3 先用单档最优 driver 跑通闭环、把多档策略包络列为 L4 增强;L3 阶段的数值判定只保证「上界不崩」,L3 期下沿体验的数值风险如实标注为未覆盖。
裁决点(§2 本节):①主设计席 v1 立瘦版而非并入制作人——两席 context 食谱确实不同(契约深度 vs 台账广度),合并省一席但会让制作人配方变宽、违反角色投影,不省;②数值仿真「先工具后席」(§2.C 坐实路 A 成立);③馆长与玩家缓立。三条骨架裁决,创始人 §7 已批;本节三附节(§2.A 注入面审计 / §2.B 场景注册表 / §2.C 快进仿真器)各自的合并期裁定见其节内〔fable 合并期裁定〕标记。
flowchart LR
U[创作者] -->|一句话/试玩反馈| P[制作人席]
P -->|工单| D[主设计席·瘦]
P -->|工单| I[实现席 ×N]
P -->|工单| CT[内容席]
P -->|工单| AS[资产席·薄]
D -->|规格增量| I
D -->|规格增量| CT
I -->|交付包| R[评审席·盲]
CT -->|交付包| R
AS -->|交付包| R
G[九门/仿真器/校验器<br/>门与工具,不是席] -->|证据包| R
R -->|判定书| P
P -->|版本卡| U
T[遥测] -->|回流工单| P
I -.->|升级事件| P
style G fill:#f8fafc,stroke:#94a3b8,stroke-dasharray: 5 5
3. 九类工件 schema 草案
命题:席位间一切通信 = 工件;工件全部带统一信封,信封三件事——谁产的(席位+配方版本)、凭什么(出处三戳)、跟哪局有关(traceId)。 没有信封的消息不进任何席位的 context。落点:contracts/agentic-artifacts/(实现波按 Δ5 配校验器与正负样本,本档只冻字段骨架)。
统一信封(所有工件共用):
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| artifactType | enum(九类) | ✓ | 见下 |
| artifactId / schemaVersion | string / int | ✓ | 工件自身可寻址、可演进 |
| producedBy | {actorKind(seat/tool/telemetry/harness), actorId, configVersion?} | ✓ | 生产者三元:actorKind 分四类合法生产者(席位/门工具/遥测/harness),actorId 具体标识,configVersion 在 actorKind=seat 时为席位配方版本(配置控制面版本号)、tool/telemetry 可空——坏结果可归因到配方或产它的门/遥测 |
| provenance | {source, ts, nature} | ✓ | 出处三戳:来源(commit/门跑/遥测窗)、新鲜度、性质(事实/推断/假设) |
| traceId / gameProjectId | string | ✓ | 关联生成 trace 与游戏工程 |
九类工件逐类给字段;凡既有契约已定的字段一律引用、不重定义,纯新增字段给设计理由(逐字段对账见 §3 附·契约对账)。下列各表不重列信封五字段;示例 JSON 带一段缩略信封以示合法实例。
① 工单(WorkOrder)——制作人→各席,一切工作的铸造形态:
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| goal | string | ✓ | 产品语言的目标,一句话 |
| scopeWhitelist | {files[], tables[], contracts[], saveStateSubtrees[]} | ✓ | 写白名单,工单级(比档位级更窄);并行工单白名单不相交。files = 「新文件通配前缀 + 必触碰既有文件显式列全」的并集展开,DeliveryPackage.filesTouched ⊆ 展开集、越界须先发升级事件(scope_expand)改单(缺口⑤);contracts[] = 契约路径 + JSON Pointer 锚,圈主设计席工单的契约面(缺口②);saveStateSubtrees[] = 存档 schema 子树授权——save_state 非数据表(缺口④) |
| acceptance | {gates[], machineChecks[], checks[]} | ✓ | 三分(缺口③):gates = 九门/富游戏门闭集引用;machineChecks = 非九门机器门(validate_datatable/schema 校验器/经济仿真非劣化/兼容检查器);checks = 少量人判项。编译不出验收门的 goal 不许铸单(goal-loop 铁律) |
| budget | {rmbSoft, rmbHard, wallClockS, resumeMax} | ✓ | 两段式预算对齐现行 middleware 语义 |
| deps / escalationPolicy | refs[] / enum | ✓ | 依赖工单;何时必须发升级事件 |
| confirmTier | 0/1/2 | ✓ | 三档确认档位;铸单时按场景 confirmFloorRule 与 SpecDelta.saveDataImpact 终判落值(场景规则给不可放松的地板,只升不降) |
| decisionRefs[] | ref[]〔→ decisions 条目〕 | 铸单时 harness 按 scopeWhitelist 机械检索账本决策索引、命中自动注入(缺口⑨终审件);实现席据此先知约束,执行期 EscalationEvent.decisionHistoryHit 为二道网 |
示例(场景 A 实现工单):goal:"顾客可与宠物互动,互动后小费系数上浮",scopeWhitelist:{files:["src/systems/pet*","src/systems/tipCalc.js","src/scenes/PlayScene.js"],tables:[],saveStateSubtrees:["/save/pet"]}(新文件通配、必触碰既有文件显式列全;宠物态走 save_state 子树、经 SpecDelta 登记,不新增表,遵 §1.1.4;顾客类型表归并行的内容工单),acceptance:{gates:["九门"],machineChecks:["经济仿真非劣化"],checks:["撸猫动效可见"]},confirmTier:1,decisionRefs:[](宠物纯新增,决策索引无命中)。
② 判定书(Verdict)——评审→制作人。裁决:并存形态,认领既有胚胎、不另起 schema。〔fable 合并期裁定·终审签认 2026-07-06〕verdict-feedback.schema.json(C6)的 passed 为 const false、自述「不是终判本身……专门喂回 agent 让它接着修的那份载荷」,失败项 minItems:1——一份 accept 判定没有未过门,结构上放不进 C6。故判定书认领的胚胎分两份:投影终判 tier2-verdict 承 decision/perCheck/ftueNotes,在 decision=fix 时引用一份 C6 VerdictFeedback 作续修载荷:
判定书 Verdict = 信封
+ decision ← 引 tier2-verdict.decision(accept/fix/kill,不重定义)
+ perCheck[] ← 投影 tier2-verdict.layerResults.L1.gateResults + richGameGates + findings
+ ftueNotes ← 投影 tier2-verdict.humanPlayability + C5 play-spec.firstPlay(玩家席缓立期权宜项)
+ evidenceRef ← 指向 EvidencePackage(⑥)
+ fixFeedbackRef?← 仅 decision=fix 时,指向一份 C6 VerdictFeedback(保 C6 passed=false 不变量)
+ decisions[]? ← 约束性决定{constraint, scope:{files[],tables[],systems[]}, rationale, standingUntil?}(缺口⑨终审件:评审判定随档落约束,如 D300「合批保持关闭」;账本决策索引之源)
即判定书对 C6 的关系是引用(fix 分支嵌入续修载荷),对终判 tier2-verdict 的关系是投影其决策与逐项结果;两份既有契约都不改。「不另起 schema、认领胚胎」的骨架裁决实质不变,只是认领对象分两份(终判 + 续修载荷各一)。席内/席间边界佐证:C6 喂的续修 middleware 在实现席 ReAct 循环内(席内),判定书是评审席→制作人席的席间终判——把判定书整体等同 C6,会把「席内续修载荷」错当「席间终判」。
③ 版本卡(VersionCard)——制作人→创作者,用户唯一看得见的版本形态:
| 字段 | 类型 | 必选 | 说明 |
|---|---|---|---|
| versionId / baseVersionId | string | ✓ | 本版与其基线 |
| lineId | string | ✓ | 铸卡时所属版本线(不可变);分叉 = 新 lineId + baseVersionId 指分叉点。线状态(active/superseded)与 live 指针是发布域/账本的可变状态、刻意不上卡(卡不可变),时间线视图由账本按 lineId join 呈现(缺口⑦终审件) |
| baselineStamp | {gatesGreen, telemetryNonRegression, qualifiedAt} | ✓ | 基线资格机器戳(§4);「从稳定版继续」解析的对象 |
| appliedIntents | workOrderRef[] | ✓ | 本版应用的意图集——意图重放(§4)的原料 |
| evidenceRef / compatStamp | ref / {saveSchemaVersion, compatibleFrom} | ✓ | 证据包;存档兼容戳 |
| thumb / oneLiner | asset / string | ✓ | 缩略图 + 一句人话变更 |
④ 规格增量(SpecDelta)——主设计席→实现席/内容席。 契约变更是复杂游戏区别于模板小游戏的分水岭;规格增量是主设计席唯一的产出面,把「系统契约/数据 schema 怎么改」钉成可校验、可登记存档影响的工件。
| 字段 | 类型 | 必选 | 说明 | 来源 |
|---|---|---|---|---|
| contractRef | string(契约路径 + JSON Pointer 锚) | ✓ | 本增量针对哪份契约或数据表 schema | 引用 contracts/ 现存文件路径 |
| contractVersionBump | enum(none/minor/major) | ✓ | 契约语义版本 bump 档:none=新增可选字段不升、minor=向后兼容扩展、major=删改字段或改语义;只管系统契约与数据表 schema 的兼容级别,与存档 schema 版本正交 | 引用 play-spec.schema.json:13-14「新增字段不升版本;删改字段或改语义才升版本」+ 版本闸 contracts/prompts/check_version_bump.py |
| changes[] | {op(add/modify/remove), path, rationale}[] | ✓ | 逐条增量,op 对齐 additive/breaking 判据;每条一句 rationale 供盲评审可判 | 新字段·规格增量须逐条可审 |
| migrationNote | string | 条件(contractVersionBump=major 或存档 breaking 必填) | breaking 变更的迁移说明(两端读取方 + CI 一致性怎么跟) | 新字段·承接数据飞轮 §5「升版本要同步两端读取方与 CI」的迁移纪律 |
| saveDataImpact | {changed:bool, migratorNeeded:bool, schemaBump(none/bump), saveSchemaVersion?:string} | ✓ | 存档面影响:是否变、要不要迁移器、是否升存档 schema 版本(additive→none 不升、breaking→bump 升)、变后存档版本号;与 contractVersionBump 正交(契约版本 ≠ 存档版本);喂 VersionCard.compatStamp 与兼容检查器 | 新字段(登记面)·锚 §4.3 存档兼容检查器 + L2 save-progress KV 存档;save-progress 现状是否带 schema 版本字段待 O-6 核实 |
契约语义版本(contractVersionBump)与存档 schema 版本(saveDataImpact.schemaBump)是两根正交的轴,拆开是因为它们各自回答一个不同的问题。前者管系统契约与数据表 schema 的兼容级别,复用 play-spec「新增字段不升、删改改义才升」那套口径;后者只管玩家存档格式要不要升版,additive 扩展(旧档缺省仍可读)不升、breaking(改删字段令旧档失效)才升。一次改动可以只动一根轴——场景 A 给顾客类型表加了一列(contractVersionBump=minor),但存档那头只是加了个可选 pet 子树的 additive 扩展(schemaBump=none),两个版本号各走各的、不互相牵连。
示例 JSON(场景 A · 追加宠物系统,存档表加可选宠物子树、顾客类型表加互动列):
{
"artifactType": "SpecDelta",
"artifactId": "spec-pet-001",
"schemaVersion": 1,
"producedBy": { "actorKind": "seat", "actorId": "主设计席", "configVersion": "designer/1.2" },
"provenance": { "source": "workorder:WO-pet-001", "ts": "2026-07-20T10:00:00+08:00", "nature": "推断" },
"traceId": "t-nightmkt-1420", "gameProjectId": "nightmarket",
"contractRef": "game://nightmarket/datatables/customer_type.gold.json#/columns",
"contractVersionBump": "minor",
"changes": [
{ "op": "add", "path": "/save/pet", "rationale": "宠物养成态需持久化(好感度/皮肤),存档新增 pet 子树" },
{ "op": "add", "path": "/datatables/customer_type/columns/petInteraction", "rationale": "顾客类型表加互动列,标记该顾客类型是否触发撸猫" }
],
"migrationNote": "契约端新增可选列走 minor;存档端新增可选 pet 子树、旧档缺省视为未解锁宠物,属 additive、schemaBump=none 不升存档版本、无需迁移器",
"saveDataImpact": { "changed": true, "migratorNeeded": false, "schemaBump": "none", "saveSchemaVersion": "nightmarket-save/3" }
}
⑤ 交付包(DeliveryPackage)——实现席/内容席/资产席→评审席。 交付包是「我做完了、这是产物 + 我自己先查过」的席间交接。它不含终判,只承实现席的自证与可定位的产物锚。反造假是它的第一纪律。
| 字段 | 类型 | 必选 | 说明 | 来源 |
|---|---|---|---|---|
| commitHash | string(hex) | ✓ | 本工单产物的真实 commit,必须 git rev-parse 得到、不得自述 | 新字段·反造假一手教训(controller 侧 rev-parse 对账是运行时纪律) |
| filesTouched[] | string[] | ✓ | 本工单真实改动的文件,须 ⊆ WorkOrder.scopeWhitelist.files(离场清账核对面) | 引用 WorkOrder.scopeWhitelist(§3①)+ 源工程 files/fileTree(result_out.py:60-62 / tier2-source-project.schema.json:18) |
| sourceProjectRef | {addressingKey(contentHash/sourceHash), versionId?} | ✓ | 交付的源工程寻址锚(评审席据此取回被审工程;VersionCard 不加此锚、只持 versionId,源工程寻址由 W-ASSET-SRC 按 versionId 二跳解析) | 引用 tier2-source-project.schema.json:98(contentHash)/:108(addressing) 与 cheap sourceHash(result_out.py:37-40,65-72) |
| selfTestEvidence | {cmd, exitCode, summary} | ✓ | 席内自测证据(build/test 输出摘要),只自证已自查、不作终判 | 新字段·实现席 harness「build/test」自测面 |
| journalRef | ref(→ journal 记录) | ✓ | 写前意图 journal 指针;改前声明意图、离场时据此清账 | 引用 §2 harness 列 + §5 L1「journal 写前意图 + 离场清账进 harness」 |
示例 JSON(场景 A · 实现席交付宠物系统源工程):
{
"artifactType": "DeliveryPackage",
"artifactId": "delivery-pet-001",
"schemaVersion": 1,
"producedBy": { "actorKind": "seat", "actorId": "实现席#pet", "configVersion": "impl/2.1" },
"provenance": { "source": "commit:9f3c1a…", "ts": "2026-07-21T14:30:00+08:00", "nature": "事实" },
"traceId": "t-nightmkt-1421", "gameProjectId": "nightmarket",
"commitHash": "9f3c1a2b7d0e4f6a8c1b3d5e7f9a1c2b4d6e8f0a",
"filesTouched": ["src/systems/petSystem.js", "src/systems/tipCalc.js", "src/scenes/PlayScene.js"],
"sourceProjectRef": { "addressingKey": "3a…(contentHash)", "versionId": 24 },
"selfTestEvidence": { "cmd": "node --check && esbuild build", "exitCode": 0, "summary": "构建通过,3 文件 node --check 无语法错误" },
"journalRef": "journal://nightmarket/WO-pet-001/impl.jsonl"
}
⑥ 证据包(EvidencePackage)——门/工具(九门·仿真器·校验器)→评审席。 证据包是「机器判出来的东西堆在这里,评审席只认它、不认任何 agent 自述」。它的指针段与 C6(verdict-feedback)的 evidence 段高度重叠——故指针字段一律引用 C6.evidence,不另立;真正新增的只有仿真器产物与真实成本两项。分版落地:瘦版随 L1(仅 gateRunRef/tracePath/screenshots 三指针,即够回放交接序),全量随 L3(补 costActual 与 simRunRef,§5)。
| 字段 | 类型 | 必选 | 说明 | 来源 |
|---|---|---|---|---|
| gateRunRef | ref(→ verdict.json) | ✓ | 九门/富游戏三门终判落盘指针 | 引用 verdict-feedback.schema.json:39(evidence.verdictPath) + 终判本体 tier2-verdict.schema.json |
| tracePath | ref(→ trace.jsonl) | ✓ | 本局生成轨迹指针 | 引用 verdict-feedback.schema.json:40(evidence.tracePath) + contracts/trace/ |
| screenshots[] | string[] | ✓ | 四件套取证图路径 | 引用 verdict-feedback.schema.json:42(evidence.screenshotDir) / tier2-verdict.schema.json:195 |
| costActual | {totalRmb, tokens?:{in,out,cached}} | ✓ | 本局真实成本;权威源 new-api 计费行,由 cost.py 按 traceId 关联 best-effort 回填 | 引用 tier2-trace-event.schema.json:56(cost.cost_rmb) + result_out.py:140-142 |
| simRunRef | ref(→ 仿真器产物) | 条件(optional) | 快进仿真器跑对照的产物指针(经济仿真非劣化判据的取数来源) | 新字段·锚 §2.C 快进仿真器 |
结构上等价于:EvidencePackage = 信封 + C6.evidence(verdictPath→gateRunRef / tracePath / screenshotDir→screenshots)+ {costActual, simRunRef}。evidence.traceId 由信封 traceId 承载,不重列。〔fable 合并期裁定·终审签认 2026-07-06:§2.C 路 A 成立,simRunRef 本期即冻为 optional 字段(占位),不等仿真器工具落地。〕
示例 JSON(场景 A · 宠物系统的九门 + 经济仿真非劣化证据):
{
"artifactType": "EvidencePackage",
"artifactId": "evidence-pet-001",
"schemaVersion": 1,
"producedBy": { "actorKind": "tool", "actorId": "门/工具(九门·仿真器·校验器)", "configVersion": "harness/play.cdp-9" },
"provenance": { "source": "gateRun:2026-07-21T15:02", "ts": "2026-07-21T15:05:00+08:00", "nature": "事实" },
"traceId": "t-nightmkt-1421", "gameProjectId": "nightmarket",
"gateRunRef": "game://nightmarket/runs/1421/verdict.json",
"tracePath": "game://nightmarket/runs/1421/trace.jsonl",
"screenshots": ["…/first-paint.png", "…/after-play.png"],
"costActual": { "totalRmb": 0.42, "tokens": { "in": 38210, "out": 6740 } },
"simRunRef": "game://nightmarket/sim/pet-tip-vs-baseline.json"
}
⑦ 升级事件(EscalationEvent)——任一席(多为实现席)→制作人席;制作人席→创作者(终端升级)。 升级事件是「我这一档判断不了、得往上抛」的出口,升级链的终端裁决人是创作者——档 2「先问」就是一条 presentedTo=creator 的升级事件(缺口①终审件)。红线是发完干净收口、不悬挂——它一定被一个决策(新工单 / 版本决策 / 创作者选择 / 砍功能)接住。
| 字段 | 类型 | 必选 | 说明 | 来源 |
|---|---|---|---|---|
| reason | {code(enum), detail} | ✓ | 升级原因码 + 人读细节;enum 覆盖 契约变更需主设计 / 决策史对撞 / 预算击穿 / 依赖阻塞 / 熔断 / 白名单越界扩单(scope_expand,缺口⑤) | 新字段·枚举锚 §3① escalationPolicy + 四道熔断(相邻胚胎 tier2-verdict.schema.json:183 breakerKind: step_cap/budget/stuck/timeout) |
| blockedWorkOrder | ref(→ WorkOrder) | ✓ | 被阻塞的工单 | 引用 WorkOrder(§3①)artifactId |
| optionsInProductLanguage[] | {label, consequence}[] | ✓ | 翻成人话的选项,交制作人席(再转创作者)裁;禁技术黑话 | 新字段·锚 §4.3「把选项翻成人话」+ §2 制作人席职责 |
| decisionHistoryHit | {priorDecisionRef, conflict} | 条件 | 执行期二道网:实现中撞上约束性决定时携带,priorDecisionRef 指向 decisions 条目(如 Verdict-300#/decisions/0);铸单时一道网 = WorkOrder.decisionRefs(缺口⑨终审件,§3①) |
新字段·锚 §1.2 场景 C 对撞双道 |
| status | enum(open/resolved) | ✓ | 收口态;resolved 时指向接住它的下游工件(不悬挂纪律的机器可判面) | 新字段·锚 §3⑦「发完干净收口不悬挂」 |
| presentedTo | enum(producer/creator) | ✓(默认 producer) | 升级呈递对象;creator = 档 2「先问」的用户面——迁移/重置/放弃这类选项经它到创作者(缺口①终审件) | 新字段·锚 §1.2 场景 B 第四步 |
| answer | {chosenLabel, answeredAt} | 条件(presentedTo=creator 且已答) | 创作者的选择落档、进账本可回放;落定即 status→resolved | 新字段·同上 |
| decisions[] | {constraint, scope, rationale, standingUntil?}[] | 条件 | 升级裁决产生的约束性决定随收口落档(与判定书 decisions[] 同构,缺口⑨终审件) | 新字段·锚 §1.2 场景 C |
示例 JSON(场景 C · 第 1400 次改动「高峰期太卡了」→ 实现席要重开渲染合批,决策史对撞):
{
"artifactType": "EscalationEvent",
"artifactId": "escalation-perf-1400",
"schemaVersion": 1,
"producedBy": { "actorKind": "seat", "actorId": "实现席#perf", "configVersion": "impl/2.1" },
"provenance": { "source": "workorder:WO-perf-1400", "ts": "2026-07-25T09:12:00+08:00", "nature": "推断" },
"traceId": "t-nightmkt-perf1400", "gameProjectId": "nightmarket",
"reason": { "code": "decision_history_conflict", "detail": "高峰渲染优化的最直接手段是重开合批,但决策史显示第 300 次改动为正确性显式关闭了它" },
"blockedWorkOrder": "WO-perf-1400",
"optionsInProductLanguage": [
{ "label": "换一种不碰合批的优化(分帧生成顾客)", "consequence": "改动大一点,但不会让老的显示错误回来" },
{ "label": "重开合批并同时修掉当年那个显示错误", "consequence": "见效最快,但要连带把三年前修过的问题一起重做验收" }
],
"decisionHistoryHit": { "priorDecisionRef": "Verdict-300#/decisions/0", "conflict": "重开 renderBatch 与 D300 约束「合批保持关闭」相斥" },
"presentedTo": "producer",
"status": "open"
}
⑧ 回流工单(LoopbackOrder)——遥测→制作人席。 回流工单是「线上真数据回头指出一个问题」的工件化。它逐字承接数据飞轮校准单的六段口径(不另造),只是把粒度收到单局单信号、把消费方接到制作人席分诊。
| 字段 | 类型 | 必选 | 说明 | 来源 |
|---|---|---|---|---|
| telemetrySignal | {metric, window, delta} | ✓ | 触发段:遥测信号;metric ∈ 次留/完玩率/播放量/帧率 P75/累计分账 | 引用数据飞轮 §3.3 触发+输入段;metric 口径对齐 game_telemetry_game_stat + 次留旁路聚合(R6) |
| corpusWindowRef | ref | 条件(平台级必填,单局可空) | 输入段:回流语料窗口切片指针 | 引用数据飞轮 §3.3 输入段 |
| hypothesis | string | ✓ | 分析段:赢家对照/信号的假设(per-game 轻量对照) | 引用数据飞轮 §3.3 分析段「赢家对照先行、回归其次」 |
| suggestedScene | ref(→ 场景注册表) | ✓ | 产出段:建议路由的场景族(制作人席分诊入口);平台级对应物 = 校准单六去向 | 引用 §1.2 场景 + §2.B 场景注册表;六去向见数据飞轮 §3.3 |
| governanceNature | enum(观察/直接改/转提案/建议) | ✓ | 治理段:去向性质分级 | 引用数据飞轮 §3.3 治理段三性质 + 六去向表 |
| validationWindowRef | ref | 条件 | 验证段:验证窗口指针(对照同品类未更新款) | 引用数据飞轮 §3.3 验证段 |
〔fable 合并期裁定·终审签认 2026-07-06:回流工单 scope 两粒度——game-level(单游戏信号→该游戏制作人席,即本工件的原子单元,场景 C 的性能修复)与 platform-level(校准单→质量轨,月度批 + 样本门 + 六去向)。平台级归数据飞轮 SoT,本档只引用其六段口径、不重定义;两粒度共用六段、粒度不同(单张回流工单向上聚合成校准单的语料一行)。〕
示例 JSON(场景 C 主题 · 遥测发现《夜市一条街》高峰期掉帧 + 次留下滑,game-level):
{
"artifactType": "LoopbackOrder",
"artifactId": "loopback-perf-2607",
"schemaVersion": 1,
"producedBy": { "actorKind": "telemetry", "actorId": "遥测(回流入口)", "configVersion": "telemetry-rollup/1.0" },
"provenance": { "source": "telemetry-window:2026-07-01..07-31", "ts": "2026-08-01T02:00:00+08:00", "nature": "事实" },
"traceId": "t-nightmkt-loopback-2607", "gameProjectId": "nightmarket",
"telemetrySignal": { "metric": "帧率P75@高峰", "window": "2026-07 自然月", "delta": "48fps→31fps,跌破 3s 首屏门相邻的卡顿阈" },
"hypothesis": "高峰顾客并发峰值下渲染未分帧,卡顿与本月次留 -6% 时间线吻合",
"suggestedScene": "diagnose.query",
"governanceNature": "观察",
"validationWindowRef": null
}
⑨ 蒸馏增量(DistillDelta)——各席→馆长席(缓立期由查重门代位)。 蒸馏增量是「这次踩的坑/学的经验/定的术语,值得沉淀」的工件。它绝不直写知识库——经查重门并入,走分道纪律各归其道。v1 消费口径:缓立期 DistillDelta 仅落工件存储归档留痕,馆长门 v2 接手才做查重并入;它不经 docs-gate(那道门面向 markdown 提交面,与工件存储是两个面)。
| 字段 | 类型 | 必选 | 说明 | 来源 |
|---|---|---|---|---|
| kind | enum(坑/经验/术语) | ✓ | 蒸馏物类型 | 引用 §2 馆长席「journal/坑增量只走自己的道」 |
| content | string(人读散文) | ✓ | 蒸馏内容,流畅中文、可检索 | 新字段·锚 AGENTS.md §7「全部简体中文、单一主题、可检索」 |
| dedupeKey | string | ✓ | 查重键;经查重门比对,命中则更新既有条目而非新增 | 引用 §2 馆长席「查重可机器化」;查重门 = docs-gate.sh 范式 |
| targetLane | enum(knowledge/rules/skills/workflows) | ✓ | 回写目标道(kind=坑→rules,经验→knowledge/skills,术语→knowledge) | 引用 AGENTS.md §7 四类 + §2 分道纪律 |
示例 JSON(场景 A 收尾 · 从宠物小费加成一役蒸馏一条坑):
{
"artifactType": "DistillDelta",
"artifactId": "distill-pet-econ-001",
"schemaVersion": 1,
"producedBy": { "actorKind": "seat", "actorId": "主设计席", "configVersion": "designer/1.2" },
"provenance": { "source": "workorder:WO-pet-001", "ts": "2026-07-22T18:00:00+08:00", "nature": "推断" },
"traceId": "t-nightmkt-1421", "gameProjectId": "nightmarket",
"kind": "坑",
"content": "凡改动经济系数(小费加成、售价、掉率)的工单,铸单时必须挂经济仿真非劣化门:宠物撸猫小费加成初版 +30% 快进千局即击穿金币曲线,赢线提前到达使后期内容失去意义。系数类改动不是纯内容改动,走仿真对照再交付。",
"dedupeKey": "economy-coefficient-change-needs-sim-gate",
"targetLane": "rules"
}
3 附 · 契约对账
凡既有契约已有的字段一律引用、不重定义。逐字段对账:
| 工件.字段 | 既有契约字段 | 处置 |
|---|---|---|
| 判定书.decision | tier2-verdict:23-27 |
引用 |
| 判定书.perCheck[] | tier2-verdict:57(gateResults)/:62(richGameGates)/:157(findings) |
投影 |
| 判定书.ftueNotes | tier2-verdict:199,256(humanPlayability/humanTiming) + play-spec:136(firstPlay) |
投影 |
| 判定书.fixFeedbackRef | verdict-feedback.schema.json 整份(C6) |
fix 分支引用 |
| 证据包.gateRunRef | verdict-feedback:39(evidence.verdictPath) |
引用 |
| 证据包.tracePath | verdict-feedback:40(evidence.tracePath) + contracts/trace/ |
引用 |
| 证据包.screenshots[] | verdict-feedback:42(screenshotDir)/:111 |
引用 |
| 证据包.costActual | tier2-trace-event:56(cost.cost_rmb) + result_out.py:142 |
引用(权威源 new-api 计费行) |
| 交付包.filesTouched[] | WorkOrder.scopeWhitelist(§3①)+ result_out.py:60-62/tier2-source-project:18 |
引用(子集约束) |
| 交付包.sourceProjectRef | tier2-source-project:98(contentHash)/:108、result_out.py:37-40(sourceHash) |
引用 |
| 规格增量.contractVersionBump | play-spec:13-14(schemaVersion 约定) + check_version_bump.py(版本闸) |
引用(复用口径) |
| WorkOrder.acceptance.gates[] | 门名枚举 verdict-feedback:63-67 / tier2-verdict:307-309(A_boot..I_control + richGame 三门) |
引用门名闭集 |
| 升级事件.reason.code | tier2-verdict:183(breakerKind) |
借鉴枚举,非同字段 |
| 回流工单.telemetrySignal.metric | 数据飞轮 §3.3 输入段 + game_telemetry_game_stat(次留待 R6 补) | 引用口径 |
纯新增字段(既有契约无、已给设计理由):规格增量.changes[]/migrationNote/saveDataImpact;交付包.commitHash/selfTestEvidence/journalRef;证据包.simRunRef;升级事件.optionsInProductLanguage[]/decisionHistoryHit/status/presentedTo/answer/decisions[];回流工单.corpusWindowRef/hypothesis/suggestedScene/governanceNature/validationWindowRef;蒸馏增量.content/dedupeKey/targetLane;工单.decisionRefs[]、scopeWhitelist.contracts[]·saveStateSubtrees[]、acceptance.machineChecks[];判定书.decisions[];版本卡.lineId(此七处为走查缺口①②③④⑤⑦⑨的终审增补,2026-07-06)。〔fable 合并期裁定·终审签认 2026-07-06:六处字段增补(跨五类工件——交付包+sourceProjectRef、证据包+tracePath、升级事件+decisionHistoryHit/status、蒸馏增量+targetLane、规格增量+migrationNote)采纳。〕
对账中收敛的四处(以既有契约为准、不自改口径):① 判定书整体本不能映射到 C6(passed=const false、装不下 accept)——改为投影 tier2-verdict + fix 分支引用 C6;② decision/perCheck/ftueNotes 真源已在 tier2-verdict——引用不重定义;③ 证据包 gateRunRef/screenshots 与 C6.evidence 重叠——引用 C6.evidence,只新增 simRunRef/costActual;④ 回流工单尺度(平台级校准单 vs 单局→制作人席)——字段对齐六段,尺度按两粒度并存(见 §3⑧ 裁定)。
回流工单对齐数据飞轮校准单六段:
| 校准单六段(数据飞轮 §3.3) | 回流工单字段 | 说明 |
|---|---|---|
| 触发(自然月出单 / 累计≥100 提前 / 遥测信号) | telemetrySignal{metric,window,delta} | metric 用既有口径:次留 D1 / 完玩率 / 播放量 / 累计分账(+ 北极星补帧率 P75) |
| 输入(回流语料窗口切片) | corpusWindowRef | 平台级必填;单局信号可空(输入=telemetrySignal 本身 + 该局 trace/verdict) |
| 分析(赢家对照先行、回归其次) | hypothesis | per-game 轻量对照;平台级承接品类层/全局层分层对照 |
| 产出(修订提案,限六去向三性质) | suggestedScene | 单局→制作人席分诊场景;平台级→六去向 |
| 治理(按去向分级过门,走 git 版本化) | governanceNature | 观察 / 直接改 / 转提案 / 建议报告 |
| 验证(验证窗口 + 同品类未更新款对照) | validationWindowRef | 即时判据下一窗坐实、留存判据可跨窗;劣化即 revert |
防学偏五条、金标不纳入回流面等纪律属平台级校准单,不落单张回流工单。
裁决点(§3 本节)〔fable 合并期裁定·终审签认 2026-07-06〕:判定书认领既有胚胎——投影终判 tier2-verdict、fix 分支引用 C6 续修载荷(并存形态,§3②);工单/版本卡新立;信封统一。这三条骨架级冻结,创始人 §7 已批;六处字段增补(跨五类工件)合并期已采纳(见上)。字段增删是填肉自由度。九门 MCP 化维持 skill 的「主张非现状」判定:v1 不动现行 harness/middleware 调用形态,工件层只引用其产物。
4. 版本语义
命题:版本语义是 W-ASSET-SRC(源工程长期存储/版本寻址)之上的语义层,本档一行存储都不造。 A3.5 与 W-ASSET-SRC 解决「每版源工程可寻址、可取回、可重建」;北极星在其上补四件语义——用户看时间线,模型看基线资格,谁都不看 git log:
- 版本卡时间线:每张卡 = 通过验收的工单产物(schema 见 §3③),卡带 lineId 标线归属;线状态与 live 指针留在账本/发布域,时间线视图按 lineId join 呈现(缺口⑦终审件)。落点:game-cloud 既有版本行为宿主、卡片字段作扩展。〔O-6 待核实:现行版本表字段与 tier2_source_project_version 的落地状态——W-ASSET-SRC 在飞,以其执行计划为准对齐,不双写。〕
- 基线资格机器戳:「从稳定版继续」解析为「证据全绿且线上指标不劣化的最近版本」。门全绿取证据包;「不劣化」的指标窗口锚 D1 次留旁路聚合(R6 已落)与错误率。〔O-6 待核实:遥测窗口按版本切片的现状——若埋点无 versionId 维度,这是前置缺口,如实报。〕
- 存档兼容检查器:规格增量的 saveDataImpact 字段(§3④)是登记面;回退/分叉前,检查器比对目标版本与当前存档的 schema 版本,不兼容则把选项翻成人话(迁移/重置/放弃)交创作者——档 2 确认,碰玩家持久化数据永远先问。胚胎:L2 save-progress 插件的 KV 存档。边界(缺口⑧终审裁定):v1 检查器只管创作者预览与新进玩家;回退后存量线上玩家的批量存档迁移是运营窗口的人在环动作,机制随 L2 版本闭环实装另设计。〔O-6 待核实:save-progress 现状是否带 schema 版本字段;§1.1.3 已坐实现行 value ≤ 4KB、无 schemaVersion,故这是走 L2 插件库通道的前置增补需求,不在本单实现。〕
- 意图重放取代 merge:场景 B 的「保留雨天」= 取 V21 的工单(goal + acceptance),在 V19 基线上重新实现、过同套验收。AI 重做一个功能足够便宜,「合并冲突」这个概念对零技能创作者可以整个不存在。前置:工单工件持久化(§3①)+ A3.5 版本寻址。约束:重放的是意图,不是 diff——重放结果与原实现代码不同是预期行为,验收门等价才是判据。
映射到运行时现实:席位配方的版本化由配置控制面承担(per-POST 现装配,已落);游戏工程版本走 A3.5/W-ASSET-SRC;live 指针 = 现行 publish 审核门后的指针切换(胚胎已在,回退 = 指针回切)。〔O-6 待核实:AgentScope session 三加载路径中「加载已有工程」的 workdir 指向机制,与「按 versionId 取回重建再装载」的接缝——这是场景 B 的执行通道。〕
端别边界。〔fable 合并期裁定·终审签认 2026-07-06〕上面四件版本语义——版本卡时间线、意图重放、即时热发——只对自研 H5 运行主端成立:H5 无备案锁、可高频改(§1.1.3 E)。微信/抖音渠道端受备案锁约束(备案后改内容/代码须重新备案),版本节奏是月级「攒批→统一备案→整包提审」;渠道端没有「千次改动即时热发」,它消费的是 H5 主线里挑出来的里程碑版本——按基线资格戳(机制二:门全绿 + 线上指标不劣化)选一个合格版本,单游固化导出、提审上架。故版本语义分两个节奏面:H5 主线高频、渠道端月级挑版导出。
裁决点(§4 本节):①版本语义对 W-ASSET-SRC 是消费者不是竞争者,依赖排序上 L2 切片(§5)必须落在 W-ASSET-SRC 首段之后;②「基线资格」的指标窗口与阈值是放量后校准值,骨架期只冻结构不冻数值。
5. 倒排切片阶梯
命题:从现有 runtime 到北极星,每级切片独立可验收、且对 16 周主线各有回馈——阶梯不是「远期大楼的施工顺序」,是「每层都住人」。
flowchart TB
L0["L0 现状(已落)\n单席生成+九门+RepairMiddleware\n+A11 两段式+配置控制面"] --> L1
L1["L1 工件化最小切片\n工单/交付包/判定书三工件+瘦版证据包\n+journal 写前意图+离场清账"] --> L2
L2["L2 制作人席+版本闭环\n分诊/三档确认/场景注册表\n+版本卡+基线戳(踩 W-ASSET-SRC)"] --> L3
L3["L3 多席协作\n主设计瘦版+内容+资产薄+盲评审\n规格增量/证据包/升级事件上线"] --> L4
L4["L4 北极星\n标的游戏全程产出\n数十天/千次改动/多版本"]
| 级 | 交付 | 验收门 | 主线接缝(16 周) |
|---|---|---|---|
| L1 | 三工件 + 瘦版 EvidencePackage(仅 gateRunRef/tracePath/screenshots)的 schema + 校验器;现行 tier2/cheap 链路的隐式交接钉成显式工件;journal 写前意图 + 离场清账进 harness | 一局 tier2 生成全程工件可回放(操作定义:给定 traceId,能从工件存储枚举该局全部工件、按 producedBy + 时间戳重放交接序);trace 含装配记录 | 复用波⑤ T5-8 记 context 装配、兑现验收门②「trace 含装配记录」;验收门①「工件可回放」为 L1 三工件 schema 自建、T5-8 不覆盖(除非 L1 把三工件也建模成装配注入块)。C5/C6 已立零新造;修复质量与 W-REPAIR-CTX 相邻互不越界(物理文件 middleware.py 可能同住,错峰隔离) |
| L2 | 制作人席配方 v1(分诊/三档确认/场景注册表进 contracts)+ 版本卡 + 基线资格戳 | 场景 B 真跑:一次回退 + 一次意图重放,全程工件留痕 | 硬依赖 W-ASSET-SRC 首段——其执行计划尚未成文,L2 起点被此未定档前置卡住,非可紧随;版本卡语义可回馈 A11 产品面 |
| L3 | 主设计瘦版 + 内容席 + 资产薄席 + 评审席 fresh 会话化;规格增量/证据包/升级事件三工件;快进仿真器工具(已有 tier2 logic-smoke 单局雏形,增量=参数扫描 + 曲线聚合) | 场景 A 真跑:宠物系统级需求端到端,含存档 schema 变更登记;tier2 Service 各席工具面已对账封口(内建写工具关、Team 组按席致盲,见 §2.A)〔fable 合并期裁定·终审签认 2026-07-06〕 | 内容席校验器范式可反哺 W-TPL 模板产线;资产席接 W-ASSET-MAT-VERIFY |
| L4 | 标的游戏《夜市一条街》全程产出;数值仿真/馆长按需转正;回流工单接通 | 标的 3 场景全真跑 + 复杂度指标(系统 ≥8、改动 ≥1000、版本卡 ≥20) | 北极星本体;为 tier2 商业化档位提供能力上限证据 |
红线:L2 起每级碰生产窗口,按 staging-ops 排;任何一级与主线波次争资源,升级回创始人,阶梯让路。
裁决点(§5 本节):L1 先于制作人席——先把工件钉成契约、再立消费它的席位,顺序不可倒(先立席位会让席位间用自由文本交接,工件永远补不上);L2 对 W-ASSET-SRC 的硬依赖如实标注,不并行抢跑。
5.1 阶梯与 16 周主线接缝对账
先说一条总纪律:北极星阶梯整体不在 16 周产品主线的关键路径上。主线的验收定义是那条 create→…→revenue 全链路闭环加 55 P0,而 L1–L4 补的是 tier2 复杂游戏「多 agent 工作室」的能力上限,属于生成运行时的纵深、不是 55 P0 里的任何一项产品功能。所以每一级的现实窗口不是「占用某个主线波次」,而是「搭在主线已铺好的接缝或空档上」,且都排在 7 月中旬内测冲刺让路之后——冲刺期工程侧全力压的是生成成功率 ≥80% 放量、五链路真机 e2e、A11 计费三条命门,北极星让路,与 §5 红线同向。时间锚:W1≈6/9 起跑,阶段一 W1–4 ≈ 6/9–7/6、阶段二 W5–8 ≈ 7/7–8/3、阶段三 W9–12 ≈ 8/4–8/31、阶段四 W13–16 ≈ 9/1–9/28,内测硬里程碑 = 7 月中旬;当前 2026-07-06 处阶段一收尾 / 阶段二初。
| 级 | 现实起点窗口 | 相邻 / 依赖的在飞工单 | 触碰 55 P0 判定 |
|---|---|---|---|
| L1 | 契约与 harness 部分(三工件 schema + 校验器 + journal 写前意图 + 离场清账)是 contract-first、不碰生产,内测让路后任意生成线空档可起;trace 装配记录部分挂阶段四观测线的波⑤ T5-8 节奏(波⑤ 依赖 ②③④) | 复用 = 波⑤ T5-8「context 装配可观测」;C5/C6 已落 contracts/play-loop/;相邻 = W-REPAIR-CTX |
不碰。三工件、journal、装配 trace 全在生成运行时内,非 55 P0 产品功能 |
| L2 | 不早于 W-ASSET-SRC 首段落地;而 W-ASSET-SRC 执行计划尚未成文,时点未定,现实落到内测之后、阶段三段更实;本级起碰生产窗口(版本卡落 game-cloud,按 staging-ops 排) | 硬依赖 = W-ASSET-SRC(§4 裁决点①、§5 裁决点);可回馈对象 = A11,已收尾 | 不碰验收口径,additive 触边。版本卡建在 game-cloud 既有版本行为上作字段扩展,project 5 P0 含「版本」,L2 是其上的语义层、不改 project 版本 P0 的验收定义 |
| L3 | 阶梯串行在 L2 之后,更远期;多席落地碰生产窗口 | 内容席校验器范式反哺 = W-TPL(2026-07-06 立项、opus 填肉在飞);资产席接 = W-ASSET-MAT-VERIFY | 不碰。主设计 / 内容 / 资产 / 盲评审四席均为生成运行时席位,非 55 P0 产品出口 |
| L4 | 不在 16 周内,最远期 | 北极星本体;为 tier2 富游戏商业化档位提供能力上限证据 | 不碰。标的《夜市一条街》全程产出是能力验证,不进 MVP 上线验收 |
三处需要把话说透的判断:
L1 的两条验收门分属两个来源,不是一个。 验收门写的是「一局 tier2 生成全程工件可回放;trace 含装配记录」。后半句「trace 含装配记录」精确对应波⑤ T5-8 的产出——T5-8 记的是「这局装配了什么」:prompt / 配方版本、注入块清单(块名 + 版本/哈希 + 字节数)。前半句「工件可回放」T5-8 不提供:T5-8 的粒度是 context 装配块,不是 §3 定义的九类工件流转,谁产的工单被谁消费成什么交付包这条线,得靠 L1 自己交付的三工件 schema + 校验器落进 trace。所以「复用波⑤ T5-8」这句在验收门②上是实的,在验收门①上是 L1 自建、T5-8 不覆盖——除非 L1 把三工件也建模成 context 装配的注入块,让 T5-8 顺带记下它们的块名与字节。
L2 的硬依赖是真的硬,但被依赖方还没排期。 W-ASSET-SRC 是 2026-07-05 已拍板的拆线首段、标注「优先」,可它的执行计划才切、尚未成文,O-6 的依赖项也写着「W-ASSET-SRC 执行计划成文」。这意味着 L2 的现实起点被一个自身未定档的前置卡住:接缝表标「硬依赖」没有错,但必须如实带上「首段本身未排期」这个不确定性,不能读成「W-ASSET-SRC 马上就位、L2 可紧随」。
L1 与 W-REPAIR-CTX 语义互不越界成立,物理文件可能撞车。 W-REPAIR-CTX 只做两件小的——剩余修复次数 + 预算态格式化进注入 content、tier2 移植 _game_log_brief,边界红线明写「截图引用与上版 diff 不在本单」;它改的是 RepairMiddleware 续修反馈的信息量(on_reasoning 注入 content),碰 tier2/gen-worker/worker/middleware.py:833-835。L1 加的是实现席的 journal 写前意图协议 + 离场清账。一个改注入文本、一个加写前声明,职责不重叠;但两者都落在续修 / 实现席 harness 这条线上,journal 写前意图很可能与 W-REPAIR-CTX 同住 middleware.py,这是 lane 层面的接触点(见冲突项 C-2)。
冲突项清单(只列不裁,争资源升级创始人):
| 编号 | 级 | 冲突对象 | 性质 | 建议让路方向(仅建议) |
|---|---|---|---|---|
| C-1 | 全阶梯 | 7 月中旬内测冲刺三命门(≥80% 放量 / 五链路真机 e2e / A11 计费) | 人力 + 生成线部署窗口相争:北极星每级都吃 opus/fable 会话与 mini-desktop 窗口,与冲刺命门抢同一批稀缺资源 | 阶梯整体让路,北极星任何一级不进内测冲刺窗口 |
| C-2 | L1 | W-REPAIR-CTX(在飞小单) | 文件 lane 接触:L1 的 journal 写前意图协议与 W-REPAIR-CTX 的注入 content 补强可能同住 middleware.py |
W-REPAIR-CTX 是已定界的先行小单、L1 随阶梯后置,L1 让路并在其落地后接其上;两单错峰、worktree 隔离 |
| C-3 | L2 | W-ASSET-SRC | 依赖排序 + 后端生产窗口相争:L2 版本卡 / 基线戳落 game-cloud 版本域,与 W-ASSET-SRC 源工程存储同占后端版本域与部署窗口 | L2 硬让 W-ASSET-SRC 首段先行(§5 裁决点已定此向),L2 只在其后消费、不与之抢窗 |
| C-4 | L3 | W-TPL(在飞,与 W-NSTAR 同级) | 生成线 lane 交叉:内容席校验器范式与 W-TPL 模板产线机器门都动 cheap-worker 的校验器 / rubric 面(性质偏协同:L3 产出「反哺」W-TPL) | 以协同为先——L3 内容席范式作为 W-TPL 产线输入交接,不同期对同一校验器面并行改写;真撞窗口时 L3 让路 |
| C-5 | L2 / L3 / L4 | 主线生产部署窗口(阶段二真机验收批次、阶段四观测波②⑤ 生产上线、W-ASSET 各段部署) | 生产窗口稀缺相争:L2 起每级碰生产,与主线部署批次共抢 mini-desktop 错峰窗口 | 北极星碰生产各级一律排在主线部署批次之后的低峰空档,按 staging-ops 排队,不与主线同窗 |
| C-6 | L3 | W-T2LOCK(在飞止血单) | 协同非争抢:W-T2LOCK 先给 tier2 Service 写锁现网止血,L3 的「席位工具面白名单」统一中间件是其收敛终点(§2.A.4/2.A.5) | W-T2LOCK 先落止血、L3 统一中间件落地后并入退役,两单同向、不抢同一改写面 |
6. 填充工单清单(回填状态)
八单(O-1..O-5/O-7/O-8/O-9)已回填,回填产物入 §1–§5;O-6 挂起,等 W-ASSET-SRC 执行计划成文再起。各单答不出的问题一律标〔fable 合并期裁定〕或〔走查断点〕回终审,未自行拍板。
| 单号 | 目标 | 范围白名单 | 验收 | 依赖 | 状态 |
|---|---|---|---|---|---|
| O-1 | §1 标的规格填肉:系统清单细化、数值曲线骨架首版、资产清单到表格粒度 | §1;质量 SoT、sim-business skill | 系统 ≥8/表 ≥10;三场景细节自洽 | 无 | ✅ 回填完成(§1.1/1.1.1/1.1.2/1.1.4) |
| O-2 | 双端渠道约束核实:微信/抖音小游戏包体/存档/API 真实限制 | §1.1.3;runtime-and-multichannel skill、渠道 SoT | 每条约束带权威出处;对架构的力标注 | 无 | ✅ 回填完成(§1.1.3);渠道定位 + 端别边界 fable 已裁 |
| O-3 | §2 六席配方完整化 + 每席框架默认注入面审计 | §2;tier2/gen-worker、cheap-worker 源码 | 每席四层配方成文;审计给源码出处 | 无 | ✅ 回填完成(§2 六席 + §2.A);A4/D1 fable 已裁 |
| O-4 | 快进仿真器可行性调研 | 新增 §2.C;引擎工程与九门 harness | 两路各给可行性结论 + 依据;推荐一路 | 无 | ✅ 回填完成(§2.C,推荐路 A);两保真度边界创始人已拍 |
| O-5 | §3 九工件 schema 完整化 + 每类示例 JSON + 与 C5/C6/trace 契约对账 | §3;contracts/play-loop、contracts/trace | 九类字段表齐;对账表零冲突 | 无 | ✅ 回填完成(§3 完整化 + 契约对账);六增补字段 fable 已采 |
| O-6 | §4 版本语义映射核实:版本表现状、tier2_source_project_version、save-progress schema 字段、session workdir 接缝、遥测 versionId 维度 | §4;game-cloud 版本域、W-ASSET-SRC 决策稿、L2 插件源码 | 五处待核实全部落地为「现状 + 出处 + 缺口」 | W-ASSET-SRC 执行计划成文 | ⏸ 挂起——等 W-ASSET-SRC 执行计划 |
| O-7 | 场景注册表契约草案:场景族 × 四要素成 contracts 形态 | 新增 §2.B;agentic-seat-context-design §6 | 场景族全覆盖;每场景四要素齐 | O-3 | ✅ 回填完成(§2.B);D1–D4 fable 已裁 |
| O-8 | 三场景走查初稿:按 §1.2 写完整席位-工件流文字推演 | §1.2 扩写 | 三场景每步可指认工件 schema 字段 | O-3/O-5 | ✅ 回填完成(§1.2);场景 C 走查时判「断」,终审补 schema 后回写为通;缺口台账十条已裁(§7) |
| O-9 | 阶梯与 16 周主线接缝对账 | §5;16 周主计划、作战清单 | 接缝表成文;冲突项清单 | 无 | ✅ 回填完成(§5.1);五冲突项列 |
7. 检查单过尺留痕 + 需求基线〔提案〕件裁决总表
创始人 2026-07-06 拍定:骨架六裁决点(主设计席立瘦版/数值仿真先工具后席/馆长·玩家席缓立/判定书并 C6 不另起/L1 工件化先于立席/L2 硬依赖 W-ASSET-SRC 的排序)全部按骨架裁定通过。填肉阶段用走查证据挑战的项,已在合并期由 fable 逐条裁定;终审(2026-07-06)对全部合并期裁定逐处复核签认(各节标记已更新为〔fable 合并期裁定·终审签认 2026-07-06〕),并对走查缺口台账十条逐条裁定(见本节末终审裁定表)。
设席八问(v1 六席):六席的存在理由、致盲对象、回写道、产出工件已在 §2/§3 落位;三件套配方 §2 已完整;进配置控制面版本化=全部(席位=配方组合,天然进);胚胎认领=逐席标注;第八问(框架默认注入面审计)已由 §2.A 补完——审计坐实 Service 路 get_toolkit 无条件并入 15 件框架默认工具,cheap 已双补丁封口、tier2 未封(审计 A4,fable 已裁为 §5 L3 验收门一条);收窄方向 fable 已定为「席位工具面白名单」中间件(§2.A.5)。第八问从「未过」转「已审计、有裁定、终审签认(2026-07-06)」。
注入五查/场景四要素:属 L2/L3 详设的过尺点。场景四要素已在 §2.B 场景注册表落地(意图类/路由双值/确认档地板/遥测埋点);注入五查(制作人席 context 投影、评审席致盲配方)骨架期记应过项,L2/L3 详设逐条过。
需求基线〔提案〕件裁决总表:
| 〔提案〕件 | 裁决 | 理由 |
|---|---|---|
| 主设计席 | 采(瘦版) | 契约变更需独立责任线;瘦到规格增量 + 词表两件 |
| 数值仿真席 | 改 | 先工具(快进仿真器)后席;判定确定化优先 |
| 馆长席 | 缓 | 机器门 + 抽查代位;v2 按蒸馏量转正 |
| 玩家席 | 缓 | 真实遥测回流优先于合成玩家;FTUE 权宜进判定书 |
| 九类工件 schema | 采 | 判定书并 C6(不另起);工单/版本卡新立;统一信封 |
| 版本卡/基线资格戳 | 采 | 踩 A3.5/W-ASSET-SRC,本档只做语义层 |
| 兼容检查器 | 采 | 锚存档 schema 登记(SpecDelta.saveDataImpact);save-progress 现状待核 |
| 意图重放 | 采 | 取代 merge;重放意图不重放 diff,验收等价为判据 |
| 星形账本通信/禁自由对话 | 采(边界澄清) | 席间工件、席内自由(design_team 是席内结构,见 §2) |
| 九门 MCP 化 | 弃(v1) | 维持 harness/middleware 现状调用形态;工件层只引用产物 |
走查缺口台账(fable 终审 2026-07-06 已逐条裁定)
§1.2 三场景走查作为证伪测试,暴露以下 schema/配方缺口与软依赖;下表保留走查时的发现原貌(证伪记录不改写),逐条裁定见表后「终审裁定表」——九条闭合、一条归属他单,场景 C 据缺口⑨的闭合回写为通。
A. schema/配方缺口(需补字段/工件/机制,触及冻结面):
| # | 缺口 | 暴露场景 | 现状 | 影响 | 建议方向(不自拍板) |
|---|---|---|---|---|---|
| ① | 制作人↔创作者「决策请求/诊断答复」工件缺位 | B 第四步、C 第四步 | optionsInProductLanguage[] 只长在 EscalationEvent(席→制作人);制作人→创作者只有 VersionCard(版本结果通知) | 档 2「先问」(B 迁移/重置/放弃)与诊断答复(C)无工件承载、不可回放进账本 | 补一类「制作人→创作者 ConfirmRequest/DiagnoseReply」工件,承 optionsInProductLanguage |
| ② | WorkOrder.scopeWhitelist 缺契约/schema 维度 | A 第二步 | scopeWhitelist={files[],tables[]} 两维 | 给主设计席铸的工单圈不出「只许改这几份契约」 | scopeWhitelist 增 contracts[]/schemas[] 维 |
| ③ | acceptance.gates[] 取值域二义 | A 第五步 | 契约对账锁九门闭集,但示例含「经济仿真非劣化/validate_datatable」等非九门机器门 | 「gates=九门/checks=人判」二分装不下非九门机器门 | acceptance 三分:九门 gates/非九门机器门 machineChecks/人判 checks |
| ④ | save_state 分类 | A 第五步 | §1.1 列为第 13 张「数据表」,实为运行时状态 schema | scopeWhitelist.tables 白名单 + 内容席 validate_datatable 对它不适用 | 明确 save_state 变更走 SpecDelta 登记 + 实现席代码,不进内容席表面 |
| ⑤ | filesTouched ⊄ scopeWhitelist.files | A 第六步 | 白名单 ["src/systems/pet*"] 通配前缀,示例 filesTouched 含 tipCalc.js/PlayScene.js |
新增机制天然跨既有文件,离场清账误判越界 | 铸单时白名单显式列全触碰文件,不用「只圈新文件」的通配 |
| ⑥ | LOCKED_PLATFORM_FILES 目录锁 vs 文件锁(潜在硬断点) | A 第六步 | §2.A 审计 A4 记 11 锁定文件含「systems/*.js 等」,未给全清单 | 若 systems/ 目录级锁,实现席写不了玩法系统文件、场景 A 断在写码 | 补全 11 文件清单,判定 systems 是目录锁还是特定文件锁 |
| ⑦ | VersionCard 缺「线状态/live」字段 | B 第八步 | 有 versionId/baseVersionId,无 live/archived/forked-away | 分叉后旧线标记、live 指针在工件层不可见 | VersionCard 增 lineStatus/isLive 字段 |
| ⑧ | 线上玩家批量存档迁移无主 | B 第五步 | §4 兼容检查器只覆盖创作者单份开发存档 | 回退降级后全体线上玩家存档不兼容,谁负责、什么机制未定 | 明确线上批量迁移责任方(产品/审核台轨?)与降级迁移机制 |
| ⑨ | WorkOrder 缺 decisionHistoryHit + 决策史条目 schema 缺位(场景 C 断点核心) | C 第六步 | decisionHistoryHit 只在 EscalationEvent(执行时);决策史条目无 schema,判定书 Verdict 装不下决策语义 | 场景 C 立身机制「铸单时自动对撞」无数据基础、无字段落点 | 补「决策史条目」工件或扩判定书「决策语义」段;WorkOrder 加 decisionHistoryHit(铸单时)+ EscalationEvent 兜底两道 |
| ⑩ | confirmFloor additive/breaking 细分 + 确认档时序 | A 第一/五步 | 场景注册表原记「saveData 命中即 floor 2」,不分性质、且分诊时拍死 | 与 §1.2 场景 A 档 1 冲突;additive 变更被误升档 2 | confirmFloor 分 additive(不顶 2)/breaking(顶 2);确认档终判推迟到 SpecDelta 已知后(§2.B 已采纳此方向,终审已签认——见裁定表⑩) |
终审裁定表(2026-07-06,fable):
| # | 裁定 | 落位 |
|---|---|---|
| ① | 闭合——不加第十类:升级事件方向扩「制作人席→创作者(终端升级)」,增 presentedTo/answer 字段,档 2「先问」= presentedTo=creator 的升级事件;诊断答复裁为 trace 留痕、不工件化(只读问答工件化会让账本被咨询噪音淹没) | §3⑦ 表 + §1.2 B 第四步/C 第四步 + §2.B 判读要点 |
| ② | 闭合——scopeWhitelist 增 contracts[]〔契约路径 + JSON Pointer 锚〕 | §3① 表 + §1.2 A 第二步 |
| ③ | 闭合——acceptance 三分{gates 九门闭集 / machineChecks 非九门机器门 / checks 人判} | §3① 表 + §1.2 A 两张工单示例 |
| ④ | 闭合——save_state 定性为运行时存档 schema(§1.1 清点改「12 表 + 1 存档 schema」),白名单增 saveStateSubtrees[] 维,其校验器 = 兼容检查器 | §1.1 清点/表行 + §3① 表 |
| ⑤ | 闭合——白名单语义 = 「新文件通配前缀 + 必触碰既有文件显式列全」并集展开,filesTouched ⊆ 展开集,越界发升级事件 scope_expand 改单、禁静默 | §3①⑤⑦ + §1.2 A 第五/六步示例 |
| ⑥ | 闭合(源码核实)——锁 = 10 个显式文件路径 frozenset 精确匹配(toolkit.py:34-45/:50),systems/ 只锁四个具名平台系统文件、非目录 glob,场景 A 可写、硬断点不成立;fixture 分工约定(agent 只写表现层)比锁窄,实现席写玩法系统文件归 L3 分工规格演进;§2.A.4 计数订正(11→10) |
§1.2 A 第六步 + §2.A.4 |
| ⑦ | 闭合——VersionCard 增 lineId(不可变);线状态/live 刻意不上卡(卡不可变,可变状态归账本/发布域,视图 join 呈现) | §3③ 表 + §4.1 + §1.2 B 第八步 |
| ⑧ | 归属他单——定性为开放实装项:v1 检查器只管创作者预览与新进玩家,存量玩家批量迁移 = 运营窗口人在环、机制随 L2 版本闭环实装另设计;前置事实归 O-6 | §4.3 边界句 + §1.2 B 第五步 |
| ⑨ | 闭合——不加第十类:decisions[]{constraint, scope, rationale, standingUntil?} 落判定书 + 升级事件、账本建决策索引、WorkOrder.decisionRefs 铸单机械注入(一道网)、decisionHistoryHit(priorDecisionRef)执行期二道网;场景 C 回写为通 | §3①②⑦ + §1.2 C 第六步 + §2 制作人席配方 |
| ⑩ | 闭合(随 N3)——confirmFloorRule 结构化{baseTier, irreversibleSources, saveDataPolicy},additive 不顶/breaking 顶 2,终判推迟到 SpecDelta 已知后 | §2.B 字段表 + §3① confirmTier |
B. 软依赖(已知前置/他单负责,如实引用不写成已就位,非本档缺陷):
| 依赖 | 暴露场景 | 现状引用 | 归属 |
|---|---|---|---|
| 快进仿真器工具落地 | A 第四/七/八步 | 数值仿真席缓立 v2、可行性 §2.C 坐实路 A 成立;工具未落地时「数值影响判定」退化人工判读、EvidencePackage.simRunRef optional 占位 | §2.C/§5 L3 |
| 实现席 journal 写前意图协议缺 | A 第六步 | §2 明标现状实现席无 journal 协议、DeliveryPackage.journalRef 依赖 §5 L1 切片补 | §5 L1 |
| 源工程版本寻址/取回通道 | A 第六步、B 第六步 | sourceProjectRef 寻址锚、意图重放「按 versionId 取回 V19 重建装载」压 W-ASSET-SRC 源工程存储 + session「加载已有工程」workdir 接缝;W-ASSET-SRC 首段未排期、接缝 O-6 待核 | W-ASSET-SRC / O-6 |
| 存档面定容 + schemaVersion | A 第三步、B 第四/五步 | §1.1.3 坐实现行 H5 存档 value≤4KB、单 key 白名单、L2 save-progress 无 schemaVersion;saveDataImpact.saveSchemaVersion 依赖存档面重新定容 + 加版本,走 L2 插件库通道、不在本档 | L2 插件库 / O-6 |
| 遥测 versionId 切片维度 | A 第九步、B 第三步、C 第三步 | baselineStamp.telemetryNonRegression、帧率按版本切片依赖埋点带 versionId 维度;现状 O-6 待核 | O-6 |
评审与后续:八单(O-1..O-5/O-7/O-8/O-9)已回填、O-6 挂起等 W-ASSET-SRC 执行计划成文;Codex+Opus 双评审 N1–N14 已修入;fable 终审已毕(2026-07-06:台账十条裁定、场景 C 补 schema 回写为通、20 处合并期裁定签认)。下一步 = 创始人拍;获批后按 frontmatter sot-impact 申报收口,SVG 门面图(席位-工件流 + 切片阶梯两张)随定稿波按 feature-design-doc house style 补,当前以 Mermaid 为事实源。