lili 64eb7a4eac feat(gate-fixtures): 卡 menu 族 fx4c×3 升产物型判例 + 剧情金标正例 p11a-s1 固化入仓
判例库补两类被门证实的证据落位,门判据改动前的全量回归多两组锚:

- 卡 menu 族 amgen-fx4c-{1,3,4}(复现窗 2026-07-03)从 pending 升为 product_fixtures:
  每份固化 src 源码(卡 menu 现场:menuStartBtn 仅 render 副作用赋值 + 非方向键起局)+
  evidence 摘要;bundle/index.html 构建产物与约 1MB 生成 trace(verdict 全 null)不入仓,
  附 tools.mjs build-saa 重建命令。裁决两防线:案 1/3 驱动器约定漂移(误杀)、案 4 并发
  flaky(脆弱写法),细化归卡 menu 归因单。
- 剧情品类金标正例 p11a-s1「深渊回声」(丰富度 7/11、九门全绿)落
  cheap-worker/fixtures/golden-samples/narrative/,给策划知识包 v2 正例复验当靶子;
  narrative.json 的 _note 指针从「产物未入仓」翻为已固化。

manifest 新增 product_fixtures 键表达「有载体、真跑需九门 CDP 环境」的第三态(区别 cases
可运行 / pending 无载体);产物型判例不进 run.mjs 零依赖 stage。run.mjs 全量回归绿
(node 三段 29 过、python 段无 pytest 合法 SKIP)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 14:01:02 -07:00

155 lines
13 KiB
JSON

{
"topic": "gate-golden-fixtures",
"purpose": "验收门(九门/形状门/check门/latch/tier2·cheap 门)的『误杀·漏放』金标判例集中位。每一个被证实的误杀或漏放永久变成门自己的 fixture;门判据任何改动都必须先过本回归全量。",
"contract": "门判据改动必过全量判例:改 tools.mjs / check-undef.mjs / play.cdp.cjs / gate_judge.py / cheap_gates.py 前,先 `node contracts/gate-fixtures/run.mjs` 全绿。",
"run_entry": "node contracts/gate-fixtures/run.mjs",
"single_source_of_truth": "判例真身随判据就近而居(单一事实源,不在本库重抄);本库=集中登记 + 统一运行入口 + 新增无家可归的判例。carrier 指向判例真身。",
"gates": [
{ "id": "shape-gate", "judge": "game-runtime/tools/amodel-gen/tools.mjs", "fn": "_shapeGateErrors", "lang": "node", "driven": true, "note": "参数形状/返回值幻觉静态门" },
{ "id": "check-undef", "judge": "game-runtime/tools/amodel-gen/check-undef.mjs", "fn": "scanUndefinedIdentifiers/scanImportChain", "lang": "node", "driven": true, "note": "未定义标识符 + import 断链静态扫描;缺 esbuild 时判据零依赖降级、单测整体 skip" },
{ "id": "latch", "judge": "game-runtime/games/_wg1-gen/_shared/play.cdp.cjs", "fn": "isTerminal (H门 latch,行内谓词,无导出)", "lang": "node", "driven": true, "note": "九门 CDP 真玩取证;本库仅回归其 latch 终态同义词谓词,完整真玩复跑见 pending" },
{ "id": "tier2-verdict", "judge": "tier2/gen-worker/worker/gate_judge.py", "fn": "verdict→反馈映射", "lang": "python", "driven": false, "note": "缺 pytest 时整段 skip;有 pytest 时 run.mjs 驱动" },
{ "id": "cheap-gates", "judge": "cheap-worker/cheap_gates.py", "fn": "cheap 门", "lang": "python", "driven": false, "note": "缺 pytest 时整段 skip" }
],
"cases": [
{
"id": "shape-void-return-consumed",
"gate": "shape-gate",
"form": "游戏源片段(输入)→ 期望门错误『拦(形状门)』",
"carrier": "game-runtime/tools/amodel-gen/tests/check.test.mjs",
"expect": "拦",
"source": "base2 实证:drawButton 等返 void 的绘制/音效 API 返回值被赋值或链式消费,带病过 check、运行时短路。泛化到全 void 方法。"
},
{
"id": "shape-scenefsm-define-batch",
"gate": "shape-gate",
"form": "游戏源片段 → 期望『拦』",
"carrier": "game-runtime/tools/amodel-gen/tests/check.test.mjs",
"expect": "拦",
"source": "base3(2048)实证:sceneFsm.define 用单对象 {menu,play} 或数组批量注册,场景全没注册→卡菜单。"
},
{
"id": "shape-zero-false-kill",
"gate": "shape-gate",
"form": "合法游戏写法 → 期望『放(零误杀)』",
"carrier": "game-runtime/tools/amodel-gen/tests/check.test.mjs",
"expect": "放",
"source": "base1/4/5 实证的合法写法:独立语句、if(guard)call()、try/catch、比较、注释/字符串里的 API 名、非插件键同名 void 方法——一律不得报。"
},
{
"id": "undef-gen3-cy",
"gate": "check-undef",
"form": "游戏源片段 → 期望『拦』且文案点名标识符",
"carrier": "game-runtime/tools/amodel-gen/tests/check-undef.test.mjs",
"expect": "拦",
"source": "gen3 型实证:函数体内用了未定义变量 cy(与 cx),运行时才炸、浪费整局。"
},
{
"id": "undef-gen6-stepUntilMs",
"gate": "check-undef",
"form": "游戏源片段 → 期望『拦』",
"carrier": "game-runtime/tools/amodel-gen/tests/check-undef.test.mjs",
"expect": "拦",
"source": "gen6 型实证:顶层调用未定义 stepUntilMs。"
},
{
"id": "importchain-broken-named",
"gate": "check-undef",
"form": "跨文件 import 图(fixtures/undef-scan)→ 期望『拦』",
"carrier": "game-runtime/tools/amodel-gen/tests/fixtures/undef-scan/broken-named.js",
"expect": "拦",
"source": "非遗型 a:具名 import 的名字对方没 export(spawnWave 不在 lib.js)。"
},
{
"id": "importchain-broken-ns",
"gate": "check-undef",
"form": "跨文件 import 图 → 期望『拦』",
"carrier": "game-runtime/tools/amodel-gen/tests/fixtures/undef-scan/broken-ns.js",
"expect": "拦",
"source": "非遗型 b:namespace 成员缺 export——esbuild 仅 warning、build 退出码拦不住,须显式收集。"
},
{
"id": "importchain-broken-resolve",
"gate": "check-undef",
"form": "跨文件 import 图 → 期望『拦』",
"carrier": "game-runtime/tools/amodel-gen/tests/fixtures/undef-scan/broken-resolve.js",
"expect": "拦",
"source": "非遗型 c:import 的模块文件不存在(./lib-typo.js)。"
},
{
"id": "undef-zero-false-positive",
"gate": "check-undef",
"form": "全形态合法声明 + 8 目录现存正样本 → 期望『放(零误报)』",
"carrier": "game-runtime/tools/amodel-gen/tests/check-undef.test.mjs + fixtures/undef-scan/ok-entry.js + games/_template*·_fewshot* 生成侧文件",
"expect": "放",
"source": "零误报红线:var/let/const/函数提升/类/参数/catch/解构默认值嵌套/import 绑定、typeof 守卫、globalThis、白名单全局、属性/键/label/字符串/注释同名词,以及 6 模板+2 few-shot 目录的现存正样本,一律不报。"
},
{
"id": "latch-terminal-synonyms",
"gate": "latch",
"form": "取证 state.phase(输入)→ 期望裁决(终态/非终态)。判例从判据源码抽取 isTerminal 谓词的比较字面量集重建等价谓词(不 eval、不改判据)。",
"carrier": "contracts/gate-fixtures/cases/latch-terminal-synonyms.test.mjs",
"expect": "放(gameover/over/win/lose 均判终态,latch 达成) + 拦反向漂移(play/menu 等非终态不得判终态)",
"source": "2026-06-25 base5 实证:五款真实基线真玩到 over/win/lose、score↑,却因 latch 只认 gameover 被判终态不可达而误杀。修复=终态同义词集(play.cdp.cjs:1074-1075)。本判例=该误杀的永久回归。"
},
{
"id": "python-gate-suite",
"gate": "tier2-verdict/cheap-gates",
"form": "verdict/文案/play-spec 金标 → 期望裁决(pytest 断言);缺 pytest 时整段 skip",
"carrier": "tier2/gen-worker/tests/test_gate_judge.py · test_gate_judge_cheap.py · test_run_gates_stale_verdict.py · cheap-worker/tests/test_cheap_gates.py · test_golden_specs.py · test_auto_vs_golden.py(消费 cheap-worker/fixtures/golden-specs·genre-rubrics)",
"expect": "全绿",
"source": "既有 Python 门单测与 W-GENRE 四品类金标 play-spec/rubric,已就近而居;本库经 run.mjs 在 pytest 可用时统一驱动、登记为门金标的一部分。"
}
],
"product_fixtures_note": "产物型判例:有复现产物载体 + 期望裁决,介于 cases(可运行、被 run.mjs stage 驱动)与 pending(仅叙述、无载体)之间。真跑需九门 CDP 浏览器环境(driver 起局 + latch 驻留取证),故不进 run.mjs 零依赖 stage;完整端到端复跑待 harness 托管化(同 pending.base5-full-cdp-replay)。载体只固化判例核心证据(src 源码 + evidence 摘要);构建产物(bundle/entry/index.html)与生成过程 trace(verdict 全 null、约 1MB)不入仓,附重建命令。",
"product_fixtures": [
{
"id": "amgen-fx4c-1",
"gate": "latch/driver + 首局门(卡 menu 族)",
"kind": "产物型判例(需九门 CDP 环境,不进 run.mjs 零依赖 stage)",
"brief": "接水果——篮子接下落物、三条命、难度递增(自「点圆得分」模板改造)",
"carrier": "contracts/gate-fixtures/products/amgen-fx4c-1/",
"contents": "src/(6 文件:assets/core/game-logic/game/host-config/render.js,卡 menu 源码证据)+ evidence/service-run-summary.json(costRmb 5.1068 / repairs 2 / budgetSoftTripped false / trace 摘要 2765 步)。未入仓:bundle.iife.js·bundle.iife.js.meta.json·entry-bundle.js·index.html(构建/宿主产物)、trace.jsonl(生成过程流式事件、verdict 全 null、约 884KB、无九门裁决)、README.md 与 assets/(_template 克隆残留与空资产 stub)。",
"expect": "该放(游戏起局合法)——起局靠点击 menuStartBtn(非方向键 tap),本身可玩;卡 menu 是误杀。归因(已钉):驱动器约定漂移——runKeyCycle 驱动器无起局逻辑、点不到非方向键起局即把游戏卡在 menu(E_live/H_progress latch/首局门 coreLoop 全判死)。本判例锚定『驱动器非方向键起局约定』:驱动器一旦漂移回无起局逻辑,就对这类合法游戏复现误杀。属误杀防线。裁决细化归卡 menu 归因单(复现窗 2026-07-03)。",
"rebuild": "把 src/ 放回 game-runtime/games/amgen-fx4c-1/ 后 `node game-runtime/tools/amodel-gen/tools.mjs build-saa amgen-fx4c-1`(esbuild 打 SAA 信封 __GameBundle,产 bundle.iife.js/entry-bundle.js/index.html);九门真玩取证需 mini-desktop 浏览器环境。",
"source": "卡 menu 族复现(traceId fix4xx-1,复现窗 2026-07-03)。由 pending.amgen-fx4c-menu-1-3-4 升格:复现产物已固化入仓、期望裁决已标注,故从『待补』翻为『已固化(产物型)』。"
},
{
"id": "amgen-fx4c-3",
"gate": "latch/driver + 首局门(卡 menu 族)",
"kind": "产物型判例(需九门 CDP 环境,不进 run.mjs 零依赖 stage)",
"brief": "太空躲避——飞船闪避坠物(自「点圆得分」模板改造)",
"carrier": "contracts/gate-fixtures/products/amgen-fx4c-3/",
"contents": "src/(6 文件,卡 menu 源码证据;_forensicsView 在 menu 态已把 menuStartBtn 中心暴露为 tap-targets)+ evidence/service-run-summary.json(costRmb 11.2632 / repairs 1 / budgetSoftTripped true / trace 摘要 2913 步)。未入仓同 fx4c-1(bundle/entry/index.html 构建产物、trace.jsonl 约 912KB、README/assets stub)。",
"expect": "该放(游戏起局合法)——同 fx4c-1 的驱动器约定漂移案:起局靠点击 menuStartBtn,driver 无非方向键起局逻辑即误判卡 menu。本判例锚定『驱动器非方向键起局约定』,属误杀防线。裁决细化归卡 menu 归因单(复现窗 2026-07-03)。",
"rebuild": "把 src/ 放回 game-runtime/games/amgen-fx4c-3/ 后 `node game-runtime/tools/amodel-gen/tools.mjs build-saa amgen-fx4c-3`;九门真玩取证需 mini-desktop 浏览器环境。",
"source": "卡 menu 族复现(traceId fix4xx-3,复现窗 2026-07-03)。由 pending.amgen-fx4c-menu-1-3-4 升格。"
},
{
"id": "amgen-fx4c-4",
"gate": "latch/driver + 首局门(卡 menu 族)",
"kind": "产物型判例(需九门 CDP 环境,不进 run.mjs 零依赖 stage)",
"brief": "点击命中类——命中计分、连击、漏 5 只结束(产物 L3 注释未标品类名)",
"carrier": "contracts/gate-fixtures/products/amgen-fx4c-4/",
"contents": "src/(6 文件,卡 menu 源码证据:menuStartBtn 仅在 render() 副作用里赋值)+ evidence/service-run-summary.json(costRmb 13.0113 / repairs 2 / budgetSoftTripped true / trace 摘要 3202 步)。未入仓同 fx4c-1(bundle/entry/index.html 构建产物、trace.jsonl 约 1.0MB、README/assets stub)。",
"expect": "该拦(游戏写法脆弱)——归因(已钉):并发 flaky,menuStartBtn 仅在 render() 副作用里赋值,rAF 饥饿(并发)下 render 未及时执行→menuStartBtn 恒 null→handleTap 点不到起局→卡 menu。本判例锚定『起局句柄不得依赖 render 副作用时序』:放行这种并发下 flaky 的起局写法即漏放。守门=首局门 coreLoop / E_live / H_progress。裁决细化归卡 menu 归因单(复现窗 2026-07-03)。",
"rebuild": "把 src/ 放回 game-runtime/games/amgen-fx4c-4/ 后 `node game-runtime/tools/amodel-gen/tools.mjs build-saa amgen-fx4c-4`;九门真玩取证需 mini-desktop 浏览器环境。",
"source": "卡 menu 族复现(traceId fix4xx-4,复现窗 2026-07-03)。由 pending.amgen-fx4c-menu-1-3-4 升格。"
}
],
"pending": [
{
"id": "base5-full-cdp-replay",
"gate": "latch (play.cdp.cjs H门 完整真玩取证)",
"reason": "base5 五款真实基线的完整端到端 CDP 真玩(含 latch 驻留校验)需要浏览器 + 五款游戏的持久化取证快照;这些快照未入仓,修复已固化进判据。当前以 isTerminal 谓词行为回归(latch-terminal-synonyms)覆盖其核心(终态同义词误杀),完整端到端复跑待补。",
"to_promote": "把五款基线的产物工程 + 取证快照入仓,或让 harness 托管化后可零依赖回放,再加一条端到端 stage。"
},
{
"id": "wg1-verdict-baselines",
"gate": "九门(play.cdp.cjs 全量)",
"reason": "wg1/gen-worker/results/*.json(约 28 份 verdict)是产物级金标基线,但重现需跑完整 gen+play(模型 + 浏览器),无零依赖复跑载体。",
"to_promote": "登记为参照基线;待 harness 托管化(离线可回放 verdict 输入)后,选取代表款(如 saolei result==win、breakout latch)升为端到端回归。"
}
]
}