44 Commits

Author SHA1 Message Date
lili
1981a6be01 feat(storage): 闭合 Agent 到 Runtime 的 OSS 游戏链路
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
增加不可变源码检出、两阶段 finalize/activate、Runtime 同源对象读取与 iframe 安全边界,并用 fail-closed CI 门固定契约。Git 仅提交平台实现、契约、迁移和 SoT,不包含具体游戏源码、素材、bundle 或验收证据。
2026-07-30 05:21:44 -07:00
lili
cbfd4d871b feat(acceptance): 闭合 playtest v3 与 A+ 可信消费链
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
固化 Match-3 生产者、视觉、音频与双 Judge 证据闭包。

将《山海行纪》r1.1 绑定新的不可变 release,并以生产预检现场核验 bundle、Registry/2 和 25 项 Writer 快照。

同步地图1平衡锁值、跨游戏回归修复、验收契约与 SoT 证据。
2026-07-28 20:16:13 -07:00
lili
85f48228cd feat(cheap-gen): W-AXIS 波3 知识层补强+收尾——tsc 顾问门+recipes+暗资产接线+n=5 基线台账
Some checks failed
contract-gates / contract-gates (push) Has been cancelled
docs-gate / docs-gate (push) Has been cancelled
- tsc 顾问门:typescript devDependency + tsc-advisory 测试档;顾问性(永不阻断),
  金标 10 款零误伤抽验
- recipes/ 五篇高频场景索引(命中矩形/计时器/资产回退/场景机/结算演出,「抄这段形态
  +头号病根」)+ littlejs-game-dev §0.5 卡壳就查接线
- 暗资产接线:plugin-capability-map(11 注入+1 取证+6 储备逐件裁定)+
  engine-capabilities-brief(≤3KB 蒸馏)+ api.d.ts/game-host.d.ts 补插件指针;
  三方一致性对账门 plugin-surface-gate.py(含 cwd 锚定修)挂 pre-commit+Gitea Actions
- hard_genre_batch 参数化(五品类 n=5 批跑驱动,checkpoint 续跑)
- n=5 基线台账入库(gitignore 例外 add -f,只入台账不入游戏产物):
  wax-baseline.jsonl 25 局逐局记录(含判定仪器订正批注:cap1500 重判/图像盲 M3 重判,
  只加字段零改值)——终数:操作口径 14/25=56%、质量口径 18/25=72%;
  品类 narrative/heritage 5/5、trpg 4/5、puzzle/sim-business 2/5(缺口逐局有名有姓,
  根因见 07-10 v2 plan §1);旧「80%/39%」口径正式作废存照

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 04:27:18 -07:00
lili
7f0a825382 feat(platform): L1 宿主 rafLoop 异常隔离——帧回调熔断+取证旗,静默冻死改可观测降级
背景:mini-desktop 浏览器验证坐实 stub 通道 RAF 主循环无 try/catch,游戏 render 抛任意异常即 RAF 链断、
画面永久冻结、零可观测(《山海行纪》M0 arc 崩溃的放大器;游戏侧根因已另修)。
改动:stepOneFrame 游戏回调纳入 try/catch,ctx.log('err') 留痕+错误计数(host 句柄暴露 frameErrorCount);
单帧出错不断 RAF 链;连续 MAX_CONSECUTIVE_FRAME_ERRORS=10 帧(常量注释可调)才停循环并挂
window.__gameRenderError={message,stack,frame} 供取证面与九门读取;正常路径逐字不变(时钟自增在隔离外保帧时序)。
边界如实:real 通道由 littlejsengine 掌帧、其 RAF 在引擎内部,本文件不接管(代码注释标明)。
证据:新测 6/6(node 模拟 RAF+可切换抛错假游戏,覆盖四条验收行为);整库 266/266、manifest 19/19;
主会话真跑复验。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:20:45 -07:00
lili
7cac2cb1b6 feat(polaris): 《山海行纪》M2——build 体系全表化+仿真参数扫描首跑,四判据 1080 局全绿
武器 12×8 级(五族)/被动 14×5 级/进化 12/难度 D0–D5/暴击轴/聚灵珠全入 balance 表零魔法数;
build-model.js=派生数值与理论 DPS 唯一解释器(sim/单测/扫描器同源);sim 多武器核(proj/zone 双形态、
五族索敌、链跳/爆裂/减速/灼烧,AoE 收集-降序结算防下标漂移);出击页滚动列表+难度选择、暂停 build 总览;
canvas-ui-kit v1.0→1.1 additive(createScrollList 滚动数学+拖拽单击消歧,零绘制)。
门证据:build 四判据 1080 局全绿(12 武器定向胜率全≥40%/最强 85%≤85%/随机中位 55% 带内/被动相关
|r|max=0.25;②③带沿如实注记,确定性种子主会话复跑逐值一致);扫描墙钟实测回填书 §8.3(单局 mean 1.88s、
6 worker 180 局/分,原「<1s」外推偏乐观一个量级,夜批结论不变);UI 三项 headless 断言全真→触发器②
证据面建议不触发 Phaser 复评(CDP 补证待窗口,终判在主会话);游戏 27/27+三场景+压测 p95 1.43ms+
整库 269/269+manifest 19/19,M0/M1 零倒退;主会话真跑复验。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:20:09 -07:00
lili
948ee24f30 feat(polaris): 《山海行纪》M1——浏览器崩溃修根因+六件L2插件沉淀+手感断言表接通
崩溃修根因(mini-desktop CDP验出play首帧IndexSizeError arc半径-0.5):render.js drawGround 地纹哈希位提取
用有符号右移 h>>16,h≥2³¹ 时 (h>>16)%3=-2→半径1.5+(-2)=-0.5;修位提取语义 >>→>>>(两处),非钳症状;
校验型canvas桩回归(arc按DOM语义拒负半径+桩自检)修前红/修后绿,覆盖四方向走位扫格。
六件L2插件沉淀(各五件套impl/api.d.ts/manifest/PLUGIN.md/test,纯additive零改既有):
virtual-joystick(浮动原点/死区/越界跟手纯核+轨迹注入driver=G_input孪生)/hit-feedback(档位表单入口+取证events[]:
eventName/frame/timeMs/sourceId,音画同帧构造性保证)/entity-pool/swarm-steering(均匀网格+软分离)/
auto-targeting(网格逐环≡线性最近300布局对账)/canvas-ui-kit(卡片弹层终态几何恒可点+顶栏)。
手感断言表11条逐条接通(2/5/6/10/11号真机校准与真引擎视觉证据如实标待窗口,真机p95≤16.7ms未验不冒称);
sim换装三件沉淀纯核零回退(724杀/p95 1.174ms与M0逐值一致);balance增FEEDBACK档位表全标草案。
证据:游戏13/13、整库260/260、manifest 19/19、包体258,905B(gz 89,268B)过0.6MB门;主会话真跑复验。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 11:13:27 -07:00
lili
2ce0ed3a9d feat(save-cap): W-SAVE-CAP 存档面定容+schemaVersion——单槽版本信封,北极星三款共享基建
契约先行(sdk-interface.d.ts+镜像 additive):白名单新增恰等键族 save:{gameId}:{versionId}(≤65536 码元,
写入必须 {schemaVersion≥1, data} 信封,宿主闸 fail-closed);idle: 族 4096 逐字不动;弃多 key 分片。
宿主闸抽纯函数模块 storageGate.ts(四闸合一可 node 直测);save-progress 插件 v1.0.0→v1.1.0 additive:
setVersioned/getVersioned 逐级迁移/缺级兜底/降档读新档不毁档/无版本旧档按 0 版进链+探针两计数。
证据:插件单测 18/18、game-runtime 31/31、宿主闸负向演示脚本入仓真跑全断言过、vue-tsc+vite build 绿。
三书 M 门影子存档降级口径解除条件就位(卡牌 M2/割草 M4/夜市 M5 切换)。设计页 docs/plans/2026-07-06-002。
2026-07-06 09:24:44 -07:00
lili
f9393ccbb8 feat(cheap-gen): 阶段一B #12 collision Aabb 统一接受 {x,y,w,h} 与 {x,y,hw,hh}
附A #12(最后一处·几何约定统一):collision Aabb 用中心+半宽高 {x,y,hw,hh},与 hud-ui Rect/
drawButton 的 {x,y,w,h}(左上角+尺寸)不一致——AI 易混,skill 原要专门警告"非 {x,y,w,h}"。
加 _normAabb 归一化:circleVsAabb/aabbVsAabb/raycastAabb 现同时接受 {x,y,w,h}(自动按左上角换算中心)
和 {x,y,hw,hh}(原样),AI 可用与 Rect 一致的 {x,y,w,h}、不必记区别。低风险(存量 {x,y,hw,hh} 透传不变)。

全链路同改:collision/impl.js(_normAabb + 3 直接函数归一化)+ api.d.ts Aabb 文档 + skill:113。
验证:collision 16/16(存量 center-form 不破)+ 确定性({x,y,w,h} 与等价 {x,y,hw,hh} 三函数结果全一致)。
注:SpatialHash broadphase(进阶、便宜档罕用)仍取 center-form {x,y,hw,hh};AI 常用的直接查询函数已统一。

至此附A 15 处可改签名全部完成(#1-#15)+ 正交泛型门修复。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
619351052d feat(cheap-gen): 阶段一B #1 ctx.random/ctx.time 改可调用(双 API·向母语直觉,最高频)
附A #1(最高频·每游戏用):ctx.random/ctx.time 原是对象、须 .next()/.nowMs(),AI 直觉 ctx.random()/
ctx.time() 当函数调会抛错——prompt/形状门都教"是对象不是函数"当幻觉拦。改成双 API:既可直接调用
(ctx.time()=毫秒、ctx.random()=[0,1))又保留全部方法(.nowMs()/.elapsedMs()、.next()/.range()/.reseed()),
向后兼容(框架/插件内部仍用方法形态)。

单点实现:boot-game-host 复用 createHostDevContext(单一 context 源),故 buildContext 一处包装即覆盖
host-dev + 真游戏。加 _callableTime/_callableRandom 双 API 包装器,ctx 装配处 time/random 包装。

全链路同改:plugin.js(包装器+装配)+ tools.mjs(CTX_METHODS 加 time/random、API 门错误文案翻转)
+ prompt.mjs/cheap_roles.py 双源(调用形态翻转:两形态都对、但 ctx.nowMs() 漏 .time 仍错)+ skill:144。
验证:core plugin 31/31(核心不破)+ 确定性(ctx.random()/time() 可调用 + .next()/.range()/.reseed()/
.nowMs()/.elapsedMs() 双 API)+ 形状门 11/11 + [check] PASS(双形态同段)+ cheap-worker 16/16 + 双源一致。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
fb01654311 feat(cheap-gen): 阶段一B #14 palettePost 加 applyPreset 常用后处理观感预设
附A #14:palettePost 原不内置成品观感,AI 要逐项配 vignette/dither/scanline 的 enabled/strength
才出效果。加 applyPreset(name) 一键套预设:'none'(全关)/'soft'(柔暗角)/'retro'(扫描线+暗角)/
'crt'(扫描线+暗角+抖动)/'dither'(抖动),委托 setPost。换色色板(from/to RGB)仍由游戏注入
(那需源色、非预设态)。全链路同改:impl(applyPreset 委托 plugin.setPost)+ api.d.ts 声明 + skill:117。
验证:palette-post 12/12 + 确定性(retro 开扫描线+暗角、none 全关)。prompt 不细列 palettePost 故仅 skill。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
8196e07c2c feat(cheap-gen): 阶段一B #8+#9 audioMusic 音效放开语义名 + play 强度容错
附A #8:playSfx 原限 blip/thud/chime 三预设,AI 直觉用 'click'/'hit'/'win'/'coin' 等语义名会静默失败。
加 SFX_ALIASES 语义名→预设映射(click/jump/coin→blip、hit/fail/land→thud、win/success/levelup→chime),
未识别名兜底 blip(不静默)——AI 用任意音名都出声。
附A #9:play(intensity) 入参是情绪强度 0..1、非曲目名,AI 误传字符串 → NaN 强度。play/loop 对非数容错
为默认强度;api.d.ts/skill 文档钉死"入参是强度非曲目名,曲子先 loadSong"。

全链路同改:impl(SFX_ALIASES + playSfx 兜底 + play/loop 容错)+ api.d.ts(playSfx 放宽 string + 文档)
+ skill line118。验证:audio-music 16/16 + 确定性(playSfx 任意名不抛、play 非数不抛)。prompt 不提 audioMusic 故仅 skill。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
5cb73a6d82 feat(cheap-gen): 阶段一B #4 gamefeel 加 CoyoteTimer/ComboWindow 工厂方法(免 new+传 time)
附A #4:gamefeel 的 CoyoteTimer/ComboWindow 是 class、须 new 且要传受控 TimeSource——AI 拿不到
受控 time、做不出来。加工厂方法 gamefeel.createCoyoteTimer(opts)/createComboWindow(opts):
用 init 时捕获的受控时间源自动注入,AI 直接调、免 new + 免找 time。全链路同改:
- gamefeel/impl.js:init 捕获 ctx.time,加两个工厂方法(new CoyoteTimer/ComboWindow(time,opts))
- gamefeel/api.d.ts:GamefeelPlugin 接口加两个工厂声明
- skill line115:列工厂方法(免 new + 自动注入受控 time);内置 inputBuffer 改 gamefeel.inputBuffer
验证:gamefeel 18/18 + 确定性(init 后工厂可调、返带 isAvailable/hit 的实例)。prompt 不提 gamefeel 故不同改。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
b29a379f9c feat(cheap-gen): 阶段一B #3 collision 几何查询函数挂实例(向母语直觉)
附A #3:collision 实例原只有 spatial,7 个几何查询函数(circleVsCircle/circleVsAabb/
aabbVsAabb/satVsPolygon/raycastCircle/raycastAabb/raycastSegment)仅模块级导出——但 skill:113
本就把它们列在 collision 能力下,AI 直觉 collision.circleVsCircle(...) 取不到=真 gap。
把 7 个纯函数挂上实例(引模块级、不依赖 this),api.d.ts CollisionPlugin 接口同补。skill:113
原措辞现在成真、无需改。验证:collision 16/16 + 确定性(实例 circleVsCircle/aabbVsAabb/raycastAabb
可调且算对)。注:Aabb{x,y,hw,hh} 与 Rect{x,y,w,h} 的几何约定统一(#12)风险高、留后续careful。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
d79e1b9f89 feat(cheap-gen): 阶段一B #2+#13 physics 几何挂实例 + ProjectileState px/py→x/y
附A #2:physics 实例原为空 {}、几何运动函数仅模块级导出,AI 直觉 physics.integrateProjectile(...)
取不到。把 6 个运动原语(integrateProjectile/springStep/criticalDamping/moveWithConstraint/
clampSpeed/applyFriction)+ Projectile 类挂上实例(引模块级纯函数,不依赖 this),api.d.ts 接口同补。
附A #13:ProjectileState 位置 px/py → x/y(向母语直觉,与 Vec2/命中矩形的 x/y 统一)。impl/test/
PLUGIN.md 同步(px/py 仅 ProjectileState 字段,replace_all 安全)。

注:physics 当前无 prompt/skill 指引(便宜档 niche、projectile 罕用),本次是完整性 + 正确性
(实例可用 + 字段直觉),不改生成侧行为。验证:physics-lite 16/16 + 确定性(实例 integrateProjectile/
clampSpeed 可调、ProjectileState 返 x/y)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
bdcd7d472c feat(cheap-gen): 阶段一B #10 juice 加 burst(x,y) 便利方法(向母语直觉)
附A #10:AI 母语直觉是 juice.burst(x,y),旧 API 只有 spawnEmitter('burst',x,y)、burst 仅预设名
——prompt 原本教"particles-juice 没有 burst"当幻觉拦。加 burst(x,y,overrides?) 便利方法委托
spawnEmitter('burst',...) 后,直觉名直接可用。全链路同改:
- particles-juice/impl.js:加 burst(x,y,overrides) 委托 plugin.spawnEmitter('burst',...)(引 plugin 自身不依赖 this)
- particles-juice/api.d.ts:实例接口加 burst 声明
- prompt.mjs + cheap_roles.py 双源:删"particles-juice 没有 burst"(它现在有了)
- skill line116:spawnEmitter 旁注 burst(x,y) 母语别名
验证:particles-juice 18/18(含 burst 别名 spec 等价测试)+ 确定性 burst≡spawnEmitter('burst')
+ [check] PASS(juice.burst 被 API 门认可)+ 双源一致。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
8c361f4a5b feat(cheap-gen): 阶段一B #6 sessionScore 加 add 别名(向母语直觉)
附A #6:AI 母语直觉是 score.add(10),旧 API 只有 addScore——skill 原本把 add 当
幻觉拦(❌ add → ✅ addScore)。改签名加 add 别名后,直觉名直接可用,翻转 skill。
全链路同改:
- session-score/impl.js:加 add(delta) 别名(引 plugin 自身委托 addScore、不依赖 this)
- session-score/api.d.ts:实例接口加 add(delta): number 声明
- skill:line 145 由"❌ add→✅ addScore"翻为"add=addScore 别名直接可用";line 126 方法表注别名
- prompt.mjs/cheap_roles.py 无需同改(它们不提 addScore,仅 skill 提)
验证:session-score 插件测试 7/7(含 add 别名断言)+ 确定性验 add≡addScore + cheap-worker 16/16。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
dc49f5f866 feat(cheap-gen): 阶段一B #5 drawButton 改返命中矩形(黄金首件·治 #1 翻车点根因)
降AI参与·阶段一B 改签名第一处(附A #5)。逐插件改逐插件回归的黄金样板。
drawButton 由返 void 改为回吐它绘制的归一化命中矩形 {x,y,w,h}——AI 的直觉写法
const btn = hudUi.drawButton(g,{x,y,w,h},{label}); if (hudUi.pointInRect(px,py,btn)) 现在就对,
治了 #1 翻车点(drawButton 返 void 误用→变量恒 undefined→命中短路→卡菜单)的根因,而非教绕路。

全链路同改(漏一个造新脏数据):
- hud-ui/impl.js:drawButton 模块函数 + 实例方法回吐归一化矩形 r(g=null 也回吐、绝不 undefined)
- hud-ui/api.d.ts:模块函数 + 实例方法 两处 :void → :Rect + JSDoc
- tools.mjs 形状门:删 drawButton 特例分支(api.d.ts 改后自然掉出 void 名集),
  泛化判据留给仍真返 void 的方法(drawText/drawPanel/drawBar/play/flashScreen)
- prompt.mjs/cheap_roles.py(双源)/skill:指引由"返void绝不接"翻为"回吐命中矩形可直接 pointInRect"
- check.test.mjs:drawButton 测试反转(赋值不再拦)+ 链式测改 drawText
- test_roles.py/test_toolkit.py:footgun 断言 + 形状门 drawButton 测试随签名更新

验证(逐插件回归矩阵):
- 形状门单测 11/11(amodel-gen)+ cheap-worker test_roles/test_toolkit 16/16 + hud-ui 19/19
- 确定性 impl 铁证:drawButton 回吐 {x,y,w,h}、g=null 不 undefined、回吐矩形直接 pointInRect 闭环
- 真生成代码(菜单+按钮游戏)用了 drawButton、check 未拦 drawButton,证明 #5 不破坏生成
- 双源 drawButton 文案一致;prompt.mjs node --check + cheap_roles.py py_compile 绿

正交发现(非 #5):该局九门 gen 栽在 save.get() 方法名幻觉(save 插件无 get)——
是另一处方法名摩擦,记为阶段一B 后续/补密度候选,不在 #5 范围。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 01:39:05 -07:00
lili
d55030bf4a feat(runtime): 删 gamedef 运行时核心(gd-runtime/build-from-source/2d-api)
gamedef 声明式 JSON + new Function 解释路线的 game-runtime 核心,随
gamedef 判废一并清除:
- 4 测试:src/host/{gd-runtime.test,gd-archetypes.test,build-from-source.test,gameplay-pitfalls.test}.mjs
- 4 被引文件:src/host/{gd-runtime.js,build-from-source.mjs,runtime-api-2d.d.ts,runtime-api-2d.md}

这 8 文件互相引用闭环、仅被彼此与那 4 个 gamedef 测试引用;A-model 全线
(src/core / src/plugins / host / _template / _generic)不依赖它们。
src/core/game-host.d.ts L25 一句史化石注释提及 gd-runtime(非 import),
属"绝不动"的 A-model 核心,保留,列入残留报告。

验证(必跑·删后绿基线):
- 核心 node --test src/core+src/plugins = 211 pass / 0 fail
- games/_generic 壳 = 5 pass / 0 fail(确认未误伤 _generic 标准插件壳)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 02:04:46 -07:00
lili
88d3a23787 feat(amodel-gen): 根治B(input→L1 handleTap)+driver起局扫点+5 footgun蒸馏+wanglanmei E2E→studio可玩
根治 B(缩 M3 错面,结构性根除"点击在错 phase 消费/永不消费→启动不了"):
- input 订阅收归 L1(_template/src/game.js wrapper):L3 只写实例方法 handleTap(x,y)/handleKey(key),
  L1 在 pointerdown/keydown 直达派发;_template/src/game-logic.js 范例改用 handleTap。
- tools.mjs check:拦 ctx.getInput + 必须暴露 ≥1 输入方法;prompt.mjs/README/skill 同步输入契约。
- 机制+门双实证(node 全链路:menu→点开始→play、点客加分、点空白不加分;check 对 getInput/零输入方法拦截)。

driver(play.cdp.cjs):occupied 族起局从固定点 (195,422) 改中线纵向扫点,robust 命中各游戏「开始」按钮
  (原固定点落空→死菜单假阴;实测 wanglanmei「开门营业」在 y≈502)。

资产通道(boot-game-host.loadHostAssets + gen.mjs --assets-dir):M3 只决定怎么用资产、不造。
入库工具 publish-amgen.mjs:staged bundle → game_runtime_package(package_json.engineBundle,status=1)→ studio /play。

5 个 M3 footgun 蒸馏进 prompt.mjs + skill(均 wanglanmei-v2 实测翻车):
  ① scene update 回调签名 (dt) 非 (running,dt)  ② ctx.random.next() 非 ctx.random()
  ③ ctx.time.nowMs() 非 ctx.nowMs()  ④ _forensicsView 的 phase/targets 必须在 state() 内实时算(否则定格 boot 快照)
  ⑤ update(dt) 的 dt 是秒,毫秒计时要 ×1000。

验证:M3 生成 wanglanmei-tycoon-v2(+上述 5 footgun 修复)→ 九门 PASS(score 0→364,distinct 43/43)
  → 入库 → studio /play/80002/80002 加载+boot+渲染菜单真玩(art 走程序化回退,水彩 art 需引擎资产线 E2/E3)。
  (root-fix A 门可信化先于 cbe42933 提交;SAA Java 驱动绑定另track 暂不入此 commit)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 05:48:03 -07:00
lili
db3c42c5de feat(amodel): 运行时日志基建(ctx.log+插件自带+harness捕获) + 九门A(play-spec透传)+B2(F_wiring) + 预算
创始人指令:游戏要有日志,读日志诊断运行时问题,模板+可选插件自带日志。

日志基建:
- plugin.js:受控面 ctx 加 log(tag,...args) → window.__gameLog 环形(800)+ console;用受控 time.nowMs。
- boot-game-host.js:B2 插件 Proxy wrap 顺手记插件语义调用进 __gameLog(跳 draw/update/current/get 等高频)→ 插件自带日志免逐个改;recHook 仍记 __engineCalls 供 F_wiring。
- _template game-logic.js:ctx.log 生命周期(init/scene play/over)→ 模板自带。
- play.mjs smokeBoot:抓 __gameLog 写 staged evidence/game-log.json + 末12条进 out.logTail(boot 成败都抓,失败时最有诊断价值)。
- 实证:scaffold→smoke logtest → logCount:165、game-log.json 有 [p:sceneFsm:define/start]+[game:init];读日志诊断可用。

九门对齐(C 之 A+B2,recon ad3c564):
- A(SaaGenNodes validateAmodelStaged):amodel 路 validate-ok→play 短路了 scaffoldNode(唯一写 play-spec.json 处)→ 补写 play-spec.json(从 design 产 K_PLAY_SPEC)→ 九门可驱动(治 E_live/G_input/H_progress 机制)。
- B2(boot-game-host):插件 recHook wrap → F_wiring callCount>0(实证 e2e 从 [E_live,F_wiring] → [E_live,H_progress],F_wiring 已过)。叠加式,factory/gamedef 零回归。

预算(gen.mjs):maxSteps 45→70 / maxWallMs 12→20min —— SAA design 富化 brief 比 raw(7步)需更多步。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-22 22:21:29 -07:00
lili
c44681b580 feat(runtime): A-model 地基——4 编排插件 + 2 skill + _template/catch-fruit + SAA 改写评审版
- 新增 4 编排层插件(session-score/hud-ui/scene-fsm/timer-scheduler),barrel 注册 12 件,各 impl/api.d.ts/manifest/PLUGIN.md/test,全 node 测绿;audio-music manifest 描述修红门
- skill littlejs-game-dev(code 层:12 插件 API/结构/写-vs-调/资产-mmx/工厂契约)+ sim-business-game-design(design 层:经营模拟范式 + 反"无趣"配方)
- _template(游戏克隆起点,10/10)+ catch-fruit(sonnet 扮生成 agent 只凭 skill 产出,25/25,真浏览器可玩 + canvas 自适应修复)
- docs/agent-specs SAA→A-model 改写评审版(Opus+Codex 双评审收口;D1=A 全压 A-model/D6=A 押 SAA,D6 已 mini-desktop 活验证 1/1)
- staging-ops 加「ssh 绕代理直连内网 IP」配方

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-21 09:58:52 -07:00
lili
5bc0afb4bb fix(saa): 复审整改 C2 客观门必达集 + M3 碰撞尺寸不拷顶层 + Phase 3 玩法坑离线门
CodeRabbit/Codex 双复审整改(针对 4e5a7bbf):

- C2(critical, SaaGenNodes.objectiveGatesPass):改「A-E 五门全在场且 pass,缺任一即失败」。旧「出现才查」会被 harness 中途崩(runDriver 在 D/E 前抛、未 try/catch)钻空子——verdict 只剩 A_boot/C_frame 即 sawObjective=true 放行=崩掉的游戏判过。缺门=未跑完=失败才安全。
- M3(major, gd-runtime RESERVED += w/h/r):碰撞尺寸 w/h/r 不拷实体顶层——它们是 rt.overlap 读顶层的命中框(缺省16),拷上去静默改存量游戏命中框且违反 prompt 契约「顶层 e.w 永 undefined」。
- Phase 3(OpenGame +6.9 离线 linter):build-from-source 加两族【零误伤】玩法哑火坑门——①.tags 是 Set 误用数组法/下标/length ②漏 rt. 前缀裸引擎调(补 LOGIC_BANS 不拦 getEngine/getInput/restart 的洞,含此坑源装配过却运行期夭折)。命中→repair,真玩前修省一轮 CDP。self 跨 behavior 泄漏因误伤过门款(gd-tictactoe/simon 带 bug 却过门,self 确 per-behavior)降级待非阻塞 warning 通道。新增 gameplay-pitfalls.test.mjs:正例拦坑 + gd-breakout/tictactoe/simon 零误伤,32/32 全绿(含既有回归)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 12:28:41 -07:00
lili
4e5a7bbfb9 feat(saa): M3 生成质量收敛——客观门解耦 + 流式 anthropic 思考 → e2e 11/12(91.7%)
rc 门解耦修复(SaaGenNodes.playNode):play.cdp.cjs 退出码=九门聚合(verdict.pass?0:1),driver 门(G/H/I)挂→rc=1 反向否决客观 pass,致 Phase 1 客观门解耦形同虚设、空跑救场烧 token;改 rc∈{0,1}+objectiveGatesPass,all9 旧口径保留可回退。

思考治理(SaaStudioGraph):关 openai 路 M3 adaptive thinking(内联污染 JSON+撞 max_tokens 截断);改走 Anthropic Messages 协议(原生 thinking 块分离)+ StreamingCallChatModel 流式收取(治阻塞整取 SocketTimeout;#4407 对 spring-ai 1.1.2+生成无工具调用不触发,n=1 实测确认)+ webClient NO_PROXY + max_tokens 256k。

配套:gd-runtime 去脚枪(Plan A·S2 自定义标量拷实体,治冻屏) + play.cdp seek-food 驱动 + Phase 1b prompt 解耦 + e2e 旋钮(protocol/maxTokens)。

实测 conc=12 gamedef:thinking-off 8/12(67%,E_live 哑火×4) → thinking-on 11/12(91.7%,哑火修 3/4,残留 #7 打地鼠);代价 ~10x 慢 + 1.6x token。按创始人拍板以 n=12/91.7% 宣告达标(放宽原 plan003 n>=30 门)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 11:26:26 -07:00
lili
db14845d12 fix(review): U1 资产渲染——ce-code-review 整改(P0 assets 层级 + P1 契约同步 + 校验洞 + P2 群)
6-reviewer ce-code-review 揪出并整改:
- P0(api-contract,读 schema 实证): assets 在 source-project.schema sourceProject 顶层(非 gameDefinition,
  后者 additionalProperties:false)→ 原加进 GAMEDEF_KEYS 丢合规顶层 assets。改:validateSourceProject 从顶层
  sp.assets 抽取(容差回退 gd.assets)并入 cleaned.assets;GAMEDEF_KEYS 移除 assets;测试改顶层。
- P1(api-contract+project-standards 双证): runtime-api-2d.d.ts 同步—GameDefinition.assets / RenderComponent
  shape:'sprite'+asset?/ref? / AssetSpec / createRuntime boot.assets(contract-first)。
- P1(adversarial conf100 复现): 非字符串 asset.ref(对象)绕过校验→零 repair 信号死循环 → ref 须非空字符串。
- P2(adversarial+maintainability): id/ref key 空间歧义 → drawSprite 经 asset.ref 查 boot.assets(宿主按 ref 键)。
- P2(maintainability): 数组化循环复用 GAMEDEF_KEYS 去重 / placeholderColor 补 music 色 / 弃 c.sprite 别名 / 32px 具名 DEFAULT_SPRITE_SIZE。
- P2(project-standards+api-contract): 宿主预载半-wired → game-host.d.ts + boot-game-host.js 加 HOST TODO 指针。
测试: 重写 assets(顶层/非串ref/非数组/端到端) + sprite 7 路(ref键/无图/image=null/抛错/悬空/music/asset:0)。node --test src/host 31/31 绿。

残留(已 TODO 指针 + plan U1 剩余 + task 记录): 宿主 loadAssets→boot.assets 真 wiring(浏览器耦合、node 难测)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 01:32:07 -07:00
lili
73d3391696 feat(engine): U1 引擎资产渲染地基 + asset 孤儿闭合(死代码修)
plan 2026-06-19-001 Plan B · U1。
- build-from-source: GAMEDEF_KEYS 纳入 assets(原缺→line 101 strip 掉=六类资产产物永不被消费的死代码,
  评审 P0);assets 六类(sprite/character/effect/scene/ui/music)/ref 校验转 repair 信号。
- gd-runtime: drawEntity 加 shape:'sprite' 分支 → 经 boot.assets(additive,宿主 init 预载图源)drawImage 居中;
  无图源降级类目色占位 rect(前向兼容,宿主预载落地后自动转真图,不崩不空屏)。
- game-host.d.ts: additive 扩 boot.assets(assetId→{image})落实 init「装资产」意图,零破坏既有 boot。
- 测试: build-from-source「assets 存活白名单+六类/ref 校验」、gd-runtime「sprite drawImage/无图占位双向」。
  node --test src/host 31/31 绿(无回归)。

剩余 U1 wiring(单列·触宿主实现侧): 宿主 init 预载管线 asset ref→image map→boot.assets;
六类资产 demo 截图 + 孤儿闭合截图需 mini-desktop CDP。R11 代理判据待真图源接通后验。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 00:57:26 -07:00
lili
95b2572e65 docs(game-runtime): U1 约定正式化 runtime-api-2d.d.ts(rt 接口 TS 契约 · 第10类契约 additive)
plan 2026-06-18-001 U1 正式化产物(plan「1-2 轮后正式化」已满足:4 轮迭代+跨品类 9/9 实证+clickable 基元,约定已稳)。
手写 TS 契约(同 api.d.ts/game-host.d.ts 范式),与 gd-runtime.js 同形:
- gameDefinition 声明式模型:Render/Physics/Clickable/Marker 组件 + EntityDef/BehaviorDef(code)/RuleDef/SceneDef。
- rt 面(behavior 侧):实体 getEntity/entities/query/spawn/destroy + Entity 实例形 + input(轮询)/time(确定性,无 nowMs)/
  dt/random/score-win-lose(latch)/clamp-dist-overlap/fx/view。
- ForensicsState:固定取证键 + 逐实体 id 投影命名位(ball.x…)+ tag=target → targets[]。
- createRuntime(boot,gameDefinition)→Runtime(init/update/render/state/destroy/errors)签名。

落 game-runtime/src/host/(同 game-host.d.ts 之理:内部宿主↔behavior 接线面,非跨仓 SSOT);
additive 第 10 类契约,**不动现 8 契约**(故未改 source-project.schema.json;clickable 入其 kind 枚举=additive,
留 6c6g/创始人 决,contract-first 补正)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 06:38:50 -07:00
lili
80aaa116ab feat(game-runtime): clickable 声明式点击基元(harness 探针证 9/9)+ tap-targets prompt 迭代——治便宜模型 tap-handler 顽疾
plan 2026-06-18-001 U3 迭代3-4轮(据快走查根因)。

根因(全budget+stage2 都不解,3轮prompt不解):便宜/强模型均**顽固把 tap 命中门控在分离 state 实体/计时器/turn 上**
  → 盲点驱动点不中 → tap-targets 类系统性 E_live/F_wiring/G_input/H 挂。即「让模型写 tap-handler」这条路便宜模型走不通。

引擎线根治(gd-runtime.js):新增 **clickable 声明式基元** `{kind:'clickable',score?,mark?:{shape,color,r},hitW?,hitH?}`——
  运行时内置:本帧点中带此组件且 !occupied 的实体 → 自动翻 occupied+spawn 标记(可见)+计分+fx。**离散点击类声明它即可、免写 handler**。
  验证:gd-runtime 单测 16(含 clickable 派发) + 全套 60/60;**手写纯声明式(behaviors:[])clickable tap-targets gamedef 过 harness 9/9**(E_live distinct=8/F_wiring/G_input/H 全过)——证基元+管线正确。
GAMEDEF_SYSTEM:教 clickable(替「写 tap-handler」)+ 参照2 改纯声明式 clickable few-shot(经探针证 9/9)。
runtime-api-2d.md:补 clickable 组件文档。

**关键测量定论(终结本机迭代)**:便宜模型 tap-targets 单管线生成**高方差**(同 brief 一轮 8/9 一轮 5/9)——
  N=1~2 小样 lili-mac 早读**信噪比不足**,无法可靠优化「模型产出过门率」(我前几轮在追噪声)。
  **管线/运行时/约定已证正确(手写金样两品类均 9/9)+ 引擎补了 clickable 基元**;**模型产出 cutover 率是统计量**,
  需大样+全 repair 预算 → **authoritative=mini-desktop SaaFullGraphE2eTest -Dsaa.e2e=1**(多 brief+5+3 repair+stage2)。
快走查工具:加 stage2 救场升档(QC_STAGE*)+ gamedef assert 字段 coerce 到 score(治 design 造 moves/totalRound 等取证读不到字段)。

设计决策待 6c6g:design↔gamedef 的 assertAfterPlay 字段词汇契约(design 应约束到 gamedef 暴露集 score/remaining,
  或运行时暴露更多)——触共享 DESIGN_SYSTEM。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 06:13:18 -07:00
lili
fd5b245baa feat(saa): U2 接缝 + U3 真产 gameDefinition + U4 多模型回退(gamedef 路 additive 灰度)
plan 2026-06-18-001 U2(后端接缝)/U3/U4 · 后端线 · 真结构化生成上产线(saaSourceMode=gamedef,默认 factory 字节不变)。

U3 真产 gameDefinition:
- SaaPrompts 新增 GAMEDEF_SYSTEM(与现 SYSTEM 物理隔离,公平性铁律)+ buildGameDefMessages;内容=runtime-api-2d.md
  约定提炼(schema/rt 面/命名约定/硬约束)+ 内联 scan-clean few-shot;硬约束由 build-from-source 静态扫描兜底。
- SaaStudioNodes.generateNode gamedef 分支:产结构化 gameDefinition(looseParse 脏 JSON 容错)落 K_SOURCE_PROJECT;
  factory 路(含 regenerate 消费 base 源)字节不变。

U2 后端接缝(gamedef→可玩,scaffold/build/play/harness/build.mjs 全零改):
- build-from-source.mjs 加 CLI(node build-from-source.mjs <src> <out> / --validate;被 import 不执行)。
- SaaGenNodes.validateNode(gameRuntimeRoot,sourceMode) gamedef 分支:经 build-from-source.mjs 子进程校验+装配
  sourceProject→factorySrc(下游 scaffold/build 零改消费);CLI 失败回喂 repair。
- 确定性点改解锁:modifyNode(sourceMode) gamedef 路真改源不 fail-loud;modifyRouter(sourceMode) gamedef
  deterministic→validate(装配 patched 源重验)/ factory→fail-loud;assetNode 幂等(已有 assets 跳过,不覆盖点改)。

U4 多模型回退链:generateNode 主模型(含 stage1/stage2)耗尽 180s×3 重试后,回退同 role 跨家档(M_CODE/FIX_FALLBACK
  =MiniMax-M3)再试;接现 callWithTimeoutAndRetry/looseParse/救场阶梯不另起限次。GenModels record 收敛入参。

线程:AigcExecutorProperties.saaSourceMode(默认 factory)→ SaaGraphDispatcher → SaaStudioGraph.build 9 参重载 →
  assemble → generate/validate/modify/modifyRouter;8/7/5 参 build 旧重载 delegate "factory" 不破现调用。
worker prompt.py 不动(gamedef 为 SAA 路专属、http worker 仍 iife,无 shared prompt 漂移=无 split-brain)。

验收(lili-mac 快走查):mvn test-compile 过(main+test);模型无关单测 SaaStudioGraphTopologyTest 30/30
(含新增 gamedef deterministic→validate 路由证)+ SaaStudioNodesRegressionTest 8/8,零失败;build-from-source CLI
  实证(--validate exit0/2、assemble 产正确 import 路径工厂)。**gamedef 全链过门率≥60% cutover 门需 NEWAPI_KEY+
  mini-desktop(authoritative,未在本机跑)**。默认 factory 路行为字节不变(灰度 opt-in)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 00:05:18 -07:00
lili
160d9bc3e0 fix(game-runtime): U1/U2 双评审整改(correctness×adversarial)——driver 命名路径 + 边界静态扫描 + rt 加固
子代理双评审(ce-correctness + ce-adversarial)对引擎线 9+9 条发现,逐条核证为真后整改:

gd-runtime.js:
- [HIGH] state() 派生九门 harness driver 命名路径:逐实体按 id 投影顶层位(ball.x/paddle.x/bird.vy…
  +w/h/r/angle)+ tag='target' → targets[{x,y,idx,occupied,safe}](对齐 gatespec driver 契约)。
  此前 driver 读 undefined→无法驱动→机制门必挂(plan U1 step5 要求,原缺)。
- [High] addScore 守 num(NaN/字符串不污染 score 共享契约);[High] 冻结 rt 纯 API 面
  (input/fx/time/view+本体,防 behavior 改写共享 API 串味全局,实体仍可变)。
- [Med] 重复实体 id:addEntity 保先到者可寻址+记信号,reap 仅删 byId 指向的死亡实例(不误删存活者)
  + 实体上限 5000(防失控 spawn 静默膨胀)。
- 移除 rt.time.nowMs(墙钟=非确定性逃逸口);elapsed 帧末推进(首帧 now()=0);输入沿恒帧末清
  (含 latch 后,杜绝滞留);overlap 显式 0 被尊重(不被 truthy 误当默认)。

build-from-source.mjs:
- [keystone] 校验边界静态扫描 behavior.code/rule.condition:拦死循环(while(true)/for(;;))、沙箱逃逸
  (process/require/eval/.constructor/Function/globalThis)、确定性逃逸(Math.random/Date)、DOM/网络、
  condition 副作用(;/赋值/win-lose-spawn-destroy)→ 转 validationErrors 回灌 repair。同步 JS 不可进程内
  硬中断+new Function 不沙箱,故在边界拦截(模型代码只在浏览器执行,esbuild 仅静态打包);信任模型写进 header。
- [Med] 非数组 components/entities 强制数组化(不抛裸 TypeError);behavior code 须非空字符串;
  id 唯一性+null/undefined id 不入引用集(杜绝 'null'/'undefined' 假命中);循环引用 JSON fail-loud
  (带 validationErrors);`<`→< 转义(inline-injection 安全,防 </script> 提前闭合宿主内联 script)。

runtime-api-2d.md:补「边界硬拦截」「取证/driver 命名约定」(实体命名 ball/paddle、目标打 target 标)——交 U3 prompt 教模型。

验收:node --test 全 runtime 套件 59/59(原 50 + 9 条修复验证:命名路径/addScore守卫/rt冻结/重复id/
nowMs移除/非数组/非串code/静态扫描/循环引用+</script>转义);archetype few-shot 经核证 scan-clean(不教被拒模式)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:39:57 -07:00
lili
c8526f1dd6 docs(game-runtime): U1 运行时约定文本 runtime-api-2d.md(交 U3 prompt 嵌入)
plan 2026-06-18-001 U1 交付物「约定文字同步喂进 prompt → 交 U3 落 SaaPrompts 新 SYSTEM」。

新增 game-runtime/src/host/runtime-api-2d.md——写 gameDefinition behavior 逻辑时能用的全部 rt 面
的人/模型可读契约:gameDefinition 结构 / behavior 代码契约(new Function('rt','self','dt',code)+
trigger 语义+四条硬约束)/ rules / rt 面全 API 参考 / 组件 / 4 原型 few-shot / 常见坑(治真实模型
漂移:禁约定外 helper、禁 Math.random、终态置 latch、behavior 不画图、关键事件挂 fx)。

U3 的 GAMEDEF_SYSTEM prompt 直接嵌入本文。状态 v0(已过 4 类原型表达力证),保留补 idiom 余量。
落点同 game-host.d.ts 之理(内部宿主↔behavior 接线面 → game-runtime/src/host/);
是否升格 contracts/ 跨仓契约由 6c6g(contracts owner)定。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:11:14 -07:00
lili
4292f4e793 test(game-runtime): U1 收敛判据——rt 约定跨 4 品类表达力覆盖(并作 U3 few-shot 库)
plan 2026-06-18-001 U1 验收「3-5 类游戏 behaviors 用约定全跑通、零约定外 helper 漂移」。

新增 game-runtime/src/host/gd-archetypes.test.mjs——4 类原型 gameDefinition 经 createRuntime 真驱动:
- ① paddle-intercept(realtime+连续输入键/指针 + overlap 反弹 + lose latch)
- ② event-clicker(event+离散 justTapped + addScore + rule 胜)
- ③ dodge-spawn(realtime + rt.spawn/query/destroy + rt.random + overlap lose)
- ④ runner(realtime + physics 组件重力积分 + justTapped/justPressed 跳 + spawn 障碍 + 碰撞 lose)

headline 断言 = runtime.errors() 为空(零约定外 helper 漂移/零抛错)+ 各原型出合理状态转移
(移动/计分/终态 latch + 输入响应 + physics 重力 + spawn 真生成)。证 rt 面够表达目标品类谱。

定位:此为「约定表达力」证(手写金样,非真实模型输出)——真实模型 idiom 漂移收集随 U3
(GAMEDEF_SYSTEM prompt + NEWAPI_KEY)落;这 4 份金样并作 U3 prompt few-shot 库源。
验收:node --test src/host/gd-archetypes.test.mjs 4/4;全 runtime 套件 50/50 无回归。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:08:51 -07:00
lili
b112f888cf feat(game-runtime): U2 build-from-source 装配器(gameDefinition → 可玩工厂源文本)
plan 2026-06-18-001 U2 · 引擎线 · 解锁「源 → 可玩」装配链。

新增 game-runtime/src/host/build-from-source.mjs:
- validateSourceProject(sp) → {ok,errors,gameDefinition}:轻量校验 + top-level strip
  (产线容错必做——剥模型塞的 schema 外键);引用完整性(entity.components→components[].id /
  scene.entityRefs→entities[].id)+ behavior 缺逻辑 code 揪错。守 game-runtime「本机零依赖」
  不引 ajv(inner 键宽松保留运行时用的 vx/vy/tags,待 schema 迭代再收紧)。
- assembleFactoryFromSource(sp,{runtimeImportPath?}) → generated-factory.js 源文本:
  对齐已冻装载契约(game-host.d.ts:default export 工厂 → GameInstance{init,update,render,
  destroy,_forensicsView}),五法委托 U1 createRuntime;gameDefinition 内联为 JS 字面量、
  behavior.code 作数据串随之内联(运行期 new Function 编译)。校验失败 fail-loud(err.validationErrors
  供 buildNode 回灌 repair feedback)。

接现有零改下游:产出文本 → scaffoldNode 落 generated-factory.js → scripts/build.mjs(esbuild,
不动)→ bundle.iife.js → 九门 harness(零改);entry-bundle.template.js 不动。

验收(lili-mac 快走查):
- node --test src/host/build-from-source.test.mjs 5/5——校验+strip / 装配产物含装载契约要件 +
  node --check 过 / fail-loud / **端到端功能证**(装配文本经 createRuntime 真跑到 win + fx 真接线);
  全 runtime 套件 46/46 无回归。
- 真 esbuild 链探针(探针目录已清,不入仓):金样 gameDefinition → assemble → scaffold(正确深度)→
  真 build.mjs → bundle.iife.js(215KB,语法过,__GameBundle 全局在);metafile 实证
  gd-runtime.js + boot-game-host.js + littlejsengine 全内联。

范围说明:U2 的后端 Java 接线(SaaGenNodes.buildNode/scaffoldNode 从 K_SOURCE_PROJECT 装配、
SaaStudioNodes.modifyNode deterministic 解除 fail-loud)属后端线、需 mvn/mini-desktop 验证,
随 U3 后端线一并落(plan 允两线并行)。本提交 = U2 引擎线核心(本机可验的装配地基)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 23:04:46 -07:00
lili
000f87d98b feat(game-runtime): U1 运行时约定基座 createRuntime/rt(2D 适配器 behavior 侧 API)
plan 2026-06-18-001 U1 · 引擎线 · 真结构化 gameDefinition 产线化地基。

新增 game-runtime/src/host/gd-runtime.js:
- createRuntime(boot, gameDefinition) → 建可变世界(entities 实例)+ 产 rt 对象;
  rt 即 U2 装配器编译每 behavior 时 new Function('rt','self','dt',code) 注入的那个 rt。
- rt 面(落 plan KTD2):实体 getEntity/entities/query/spawn/destroy(.x.y.vx.vy.alive
  .components.tags+.get/set/destroy);输入轮询 input.isDown/justPressed/justTapped/pointer
  (包 ctx.getInput 受控事件);时间随机 time.now(相对 elapsed,非绝对钟)/dt/random/randRange
  /randInt(走 boot.ctx 受控种子,禁 Math.random/Date.now);分数胜负 score/addScore/setScore
  /win()/lose()(置 latch 终态 gameover,不可逆=H门);工具特效 clamp/dist/overlap(AABB)+
  fx.burst/beep(经 ctx.getEngine 真调引擎粒子/合成核=满F门,无引擎优雅 no-op)。
- behaviors 各带逻辑 JS 经 new Function 编译(init 跑一次/其余每帧),抛错隔离+回灌质量信号;
  rules condition 编 JS 布尔(win/lose latch、score/advance 上升沿);物理组件 opt-in 积分;
  声明式渲染器逐实体按 render 组件画 rect/circle/fill(behaviors 只逻辑不画)+极简 HUD。

受控面铁律:经 boot.ctx(PluginContext)注入,不触裸引擎/DOM;缺 ctx fail-loud。
迭代状态 v0(plan「别冻早」):契约 runtime-api-2d.d.ts 待收 3-5 类真实模型输出补 idiom 再正式化。

验收(lili-mac 快走查):node --test src/host/gd-runtime.test.mjs 10/10 过——
三条必验(rt.random 同种子可复现/win latch 驻留不可逆/fx.burst 真触发 ctx.getEngine)
+ 集成(behavior 编译跑通/rule latch/spawn-destroy-回收/输入轮询/物理积分/渲染出图)+缺 ctx 守卫。
全 runtime 套件 41/41 无回归。测试文件就近 src/host/(贴 npm test 的 src/**/*.test.mjs 约定,
非 plan 所写 test/unit/——遵仓内既有 co-located 约定)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-17 22:53:38 -07:00
lili
d754b71e65 fix(host): attachInput 补 keydown/keyup window 桥接(getInput 契约 key 两态)
boot-game-host.js attachInput() 原只桥 pointerdown/move/up,漏 keydown/keyup → ctx.getInput() 键盘通道空,所有方向键/空格游戏(2048/Tetris/Asteroids)输入死。对齐同仓 host-dev/host.js:427-428 范式挂 window 桥 ev.key。纯增量、零兼容风险(inputBridge _assertType 白名单已含 keydown/keyup)。W-G1 scale-20 两轮对抗诊断实证:失败严格沿键盘 vs 指针分界。属 L0 域冻结契约修复,经创始人授权隔离执行,供 cherry-pick 到 dev/2.0.0。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 10:34:43 -07:00
zizi
3108009500 feat(runner-v2): P3 L0 通用装载壳——L1 生成 worker 的产出靶载体(node 5 门验过)
P3 第一块基石:把 wanglanmei-ref/entry-bundle.js 的「studio-consumable 引擎包入口」泛化为「任意生成游戏」通用壳——L1 worker 只写 generated-factory.js(一个 GameHostFactory),套本壳 esbuild 打 __GameBundle bundle 即得 studio 可消费引擎包,避免 20 个 prompt 各造一遍 7 插件 wiring。

新增(零改既有契约):① src/host/generic-host-config.js=buildGenericHostConfig(标准 7 能力插件集+六锚偏序+390×844 视口+wiring,零wanglanmei专属);② games/_generic/entry-generic.js=通用入口壳(动态 import 引擎 Option C node-safe 与 entry-bundle 同款;调用形 {canvas,seed} 逐字对齐 inject.ts:248;暴露 window.__GameBundle.{GameHostFactory,bootGameHost,default});③ games/_generic/generated-factory.js=占位 stub(L1 出码替换靶)+ P0 latch 终态范本(到 TARGET 置 gameover 驻留不可逆,_forensicsView().state().phase 暴露给 watchGameEnd);④ test/generic-shell.test.mjs=node 侧守门零依赖。

5 门验过(6c6g node,主笔亲跑复核):①esbuild iife __GameBundle.bootGameHost=function ②import-safe(node-load window 零触)③回归 src 161/161+games 57/57 ④B1 raw 203.8KB/gz 69KB ✔ ⑤占位工厂经受控面 init→tap→latch gameover 驻留。dist/ 已 gitignore 不入库。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 10:40:35 +00:00
zizi
5d3f7a87f0 feat(runner-v2): P2 通用宿主泛化落地——引擎游戏真渲入 feed 真玩(mini-desktop 真机门验)
P2 = 把 P1 装载契约从「装载王蓝莓一款」泛化为「装载任意 GamePackage」,经发布主链入 feed、
真人浏览器真玩。4 决策落实(O2(b)纳入 Phase C / DB-manifest 内嵌 / 灌库桩 / __GameBundle)。

三轨实现
- 后端:GamePackage schema 加 engineBundle additive 可选字段;buildGamePackage 加 engineBundle put
  (P3 生成路用,P2 恒 null→put 跳过→字节零变,单测 packageBytesReproducible 证);灌库桩
  p2_seed_engine_bundle.mjs + 四态脚手架 p2_scaffold_4state.sql(W-CLEAN 后重建已发布游戏)
- 运行时:P1 bootRef 泛化为 bootGameHost(opts)(引擎骨架照搬+参数化工厂来源/插件/视口),
  bootRef 退化薄包装;固化 build:ref-bundle 产 dist/ref-bundle.iife.js(--global-name=__GameBundle)
- studio:inject.ts 引擎包分支(pkg.engineBundle? → 内联 script 暴露 window.__GameBundle →
  bootGameHost 挂引擎真渲;否则旧 startRuntime 路保兼容);掏空壳改引擎分支(Phase C);CSP 不放外域

对抗代码复审逮 2 mustFix(主 agent 亲核亲修 + 6c6g 复验)
- 灌库桩读错产物(ref-bundle.js harness vs .iife.js)→ mini-desktop 灌库返工死循环
- 引擎分支漏发 game_start → 会话/play_count 静默吞、门②检不出 → 补发(DB session 行实证已修复)
+2 shouldFix(兜底可观测信号 / 灌库 SQL @pj 防撞 max_allowed_packet)
+ 真机门逮 2 环境缺陷已修(seed charset=utf8mb4 防双编码断 checksum 链 / 四态脚手架补 W-CLEAN 空库)

mini-desktop 真机门 6 门(逐门实数,主 agent 肉眼复核证据)
①build:ref-bundle 265374B/__GameBundle 真入包 ②Java 编译过+字节复现单测 ③studio staging 重建消 mock
④灌库 status=1∧checksum 64hex∧engineBundle 键齐∧manifest sha256 一致 ⑤真人 feed 点卡→引擎真渲
暖阳小卖部(warm=1246073px)非「重构中」+game_loaded+game_start+防 demo 三锚+console 零错+DB session 行
⑥回滚:无 engineBundle→demo 壳/错误态,向后兼容未破。证据 game-studio/evidence/p2-feed/

诚实 gap:game_end(到结算)未在自动化窗口内达成=ref gameover 需分钟级真玩+srcdoc 坐标盲点的取证局限,
非引擎/渲染能力缺陷(机制已通,留人工真玩到打烊补全)。受控面 6 项+game-host.d.ts 零改。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 20:36:32 +00:00
zizi
99b6c82dec feat(runner-v2): P1 王蓝莓上引擎=游戏宿主装载契约 spike 实(mini-desktop real 引擎 5 门全过)
Runner v2 全弧第一相(HJ-RUNNER-ARC-001 / P1):用王蓝莓把"上层游戏宿主装载契约"
从零 spike 到"引擎真掌帧 + 游戏美术与引擎粒子同屏可玩",解锁 P2 泛化 / P3 生成。

契约与共享件
- 新增装载契约 game-runtime/src/core/game-host.d.ts(第9类 additive·暂名):
  GameHostBootContext / GameInstance / GameHostFactory;游戏=纯模块工厂,零引擎 import,
  能力经下层 ctx.getEngine()(受控面 6 项零改),绘制面 render(g) 的 g=引擎 mainContext
- makeEngineCaps 闭包提升为可 import 模块 host-dev/engine-caps.js(createEngineCaps):
  host-dev/ref/未来生成游戏共用;engineMode 短路 / __engineCalls 探针 / null-engine 语义逐行不变

王蓝莓 real 通道(games/wanglanmei-ref)
- 增 ?engine=real:主循环从浏览器 RAF 改挂 engineInit 五回调(掌帧唯一源=引擎);
  游戏美术绘制面从 #game 改引擎 mainContext(同屏合并);bundle 延后到 setupReal 内以
  mainContext 建(getContext2d 闭包快照修);保 ?engine=stub 逐像素确定性回滚
- game-shop.js 抽为独立 GameHostFactory(零引擎 import,P3 生成 agent 可复制范本)
- entry.js 动态 import('littlejsengine')=node-import-safe ∧ esbuild iife 入包两全
- 驱动 e2e-input.cdp.cjs real 改造:禁 stepFrames 手摇(防双掌帧),真触摸+轮询;
  门②同屏像素判据(暖色 warmHits ∧ 引擎粒子 brightHits 同张 #game-engine)

真机验收(mini-desktop real 引擎,5 门)
引擎掌帧 dFrame=31∈[20,45] / 同屏 warmHits=682∧brightHits=13028 同张 #game-engine /
particles.spawnEmitter+synthSfx call-ID 运行时真调引擎 / CDP 517 真触摸跑通整局
(第1天接待18·营收¥79.9·连击9) / console 零错;本机 88 单测全绿(含修复 4 红+补回归)
证据:games/wanglanmei-ref/evidence/p1-real/(e2e-evidence.json pass=true + 5 截图肉眼复核)

诚实 caveat:门② brightHits 在结算屏混入亮 UI,同屏合并由 warmHits(美术落引擎画布)+
call-ID(粒子真调引擎)+ 引擎架构(粒子渲同一 mainContext)三证成立,非阻断。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 18:32:50 +00:00
zizi
e591e9b705 feat(t1b-beta): A1-A4 引擎能力接线落地——受控面工厂/粒子/音频/手感经 getEngine 薄包装(easing 改判)
承 A0 引擎掌帧地基,按创始人「引擎↔插件边界模型」(引擎有→薄包装·引擎无→自研补层·
同一职不留两条并行路)接线 A1-A4。host.js 注入真 engineFactory,getEngine() 在 host-dev 真活。

A1 受控面+引擎工厂地基+easing 门面:
- host.js makeEngineCaps 一处构造 EngineCapabilities{particles,audio.synth,math};
- 新 host-dev/engine-math.js 包装引擎 lerp/smoothStep + Ease 曲线(11 条等价曲线门面);
- api.d.ts additive 扩 EngineEasing + EngineMath.easing?(不破已冻 lerp/smoothStep)+ 块级降级措辞校准为 null no-op;
- 受控面 random/time 保确定性(引擎粒子用全局 rand 不可种子对齐→random 留插件自管,真缺件)。

A2 particles 薄包装+删 sim:
- EngineEmitterSpec additive 扩 10 可选字段(count/coneAngle/speed/gravityScale/sizeStart-End/colorStart-End/additive);
- spawnEmitter 改走 getEngine().particles 映射引擎 ParticleEmitter,删自研逐粒子积分 sim;null-engine→no-op 句柄;
- juice 全段(hitStop/屏震/闪白)补层保留;测试转向映射纯单测+真渲出现(逐像素确定性随 sim 退役,§1.4 记账)。

A3 audio 包装+删 vendored+补 ×0.3:
- 删 vendor/zzfx.js+zzfxm.js;audio.synth 包装引擎 zzfxG/zzfxM;
- 播放层补 ×0.3 主音量(引擎样本不烤 0.3,gain 层施)+ SAMPLE_RATE=44100 本地常量;
- impl.js 走 getEngine().audio.synth,null-engine→合成 no-op(不回退 vendored)。

A4 gamefeel easing 改判=门面包装(对抗门源码证伪纠偏):
- easing 改走 getEngine().math.easing 门面(quadIn→Ease.POWER(2) 等),内置降名 builtinEasing 作 null-engine fallback(纯数学族特例);
- backInOut/elasticInOut 引擎 IN_OUT 拼接差 6.6%/17%(另一条曲线)→门面刻意不暴,这二者恒走内置=真缺件补层;
- collision/physics-lite/palette-post 加边界裁定注释(真缺件补层,源码精校:引擎仅 isOverlapping/isIntersecting 返 boolean,无 Manifold/任意几何/RayHit)。

对抗门两逮(均前置于实现·零返工):
- A4 easing 误判 fatal:前轮按小写 quadIn grep 假阴性误判「引擎无 easing」;引擎实有 Ease(esm.js:15118)→创始人拍本波包装;
- collision 注释 under-claim:已精校为源码准措辞。新红线 §1.5:引擎能力普查禁按预期名 grep,须读 export 块/.d.ts。

本机门全绿(亲验):
- node --test 168/168 绿;all-plugins+host-bundle 双 esbuild rc=0(35594B/209516B);
- 真接线门①引擎真入产物 littlejsengine 163641B;门③负扫=0 插件直 import+vendor 已删+0 自研 sim+0 假注释;Q4 引擎 import 仅 entry.js+host.js。

A6(mini-desktop real 像素门 + 真接线门② runtime probe call-ID)待主会话驱动。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 11:48:28 +00:00
zizi
75243fe8db fix(core): host-dev context 补 getEngine()=null 桩——P2 契约自洽(契约加 getEngine 须参考实现跟上)
createHostDevContext 镜像 getAudioContext 范式补 engineFactory 选项+getEngineShared(无工厂返null+告警一次+lazy单例+工厂抛错降级)+ctx.getEngine();155测全绿(契约加方法+桩跟上不破现有测试,#6风险实证清除)。集成段注入真实engineFactory背书littlejsengine=引擎import唯一落点
自核(对抗复审agent解析失败死,关键检查主会话亲验):zzfxG返样本数组(synthSfx正确避开会播放的zzfx,播放归缺件补层)+schema packageUrl/immutable declared非required(存量manifest仍合法)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 05:20:49 +00:00
zizi
28a57b8e00 feat(contracts): T1b-β P2 三契约冻结(grounded 据真签名+插件真调用面)——待对抗复审
①受控面引擎能力透传通道 PluginContext.getEngine()→EngineCapabilities(api.d.ts):白名单3项particles.spawnEmitter/audio.synth/math.lerp+smoothStep(YAGNI核6件impl真调用点);铁律=封装禁裸Vector2/引擎import只活集成段host背书engineFactory不散进插件impl(保引擎可换+满足门1真接线);random/time集成段换引擎RandomGenerator/timeReal背书(契约形状不变)
②GamePackage manifest加packageUrl+immutable(additive,复用后端packageUrl镜像走DB-manifest降级,checksum复用旧字段供门4防demo假阳性)
③SDK StoragePlugin根契约上提(sdk-interface.d.ts):前端contract.ts定稿对象形态上提+含R4-P1 array排除契约语义声明

grounded工位核impl逮关键澄清:hitStop/屏震非通道项(impl.js:582-615=受控面输出+游戏层render.js:915应用闭环,插件不调引擎;屏震引擎化=render.js切相机属agent生成域)→通道收敛6件→3项,§7/§6 A2同步澄清;audio.synth留契约A2据SIZES定用否
JSON校验过+.d.ts括号平衡

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-13 05:12:35 +00:00
zizi
878ad3f7da feat(game-runtime): T1b-α集成段三门全PASS——SIZES九件全≤配额(全栈gz16.5KB),mini-desktop真浏览器证据(probe链/vfx像素哈希×3/CDP真输入),host-dev宿主页+参考件轮1计划
- 门①构建绿:all-plugins barrel+host-dev 双构建日志留档
- 门②SIZES增量实测:九件单件全≤配额,插件gz净增13263B(自律线60K),core基准gz 3222
- 门③浏览器证据:六锚点FNV-1a链verify.ok=true/burst-trail-drift三预设哈希×3重跑一致+几何命中+直方图非空/vignette-dither开关对照哈希互异/CDP dispatchTouchEvent真点击→probe第7条firstInput旁证
- 模板哲学红线被门③实证:particles不内置颜色致首版全黑,host作引擎供色后过——验证门逮住设计而非绕过
- α不接littlejsengine裁定留痕(host.js顶注/index.html/REPORT §4.1),受控面桩即引擎接缝点
- 遗留:probe前四锚tMono=0(冻结lane件,注入时钟拆分留β)
- games/wanglanmei-ref/LOOP-LOG.md:参考件内部预判轮1计划(五要素挂点/插件用法图/mmx资产单13次/红线五条)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 12:39:15 +00:00
zizi
384d303831 feat(game-runtime): T1b-α 八件插件三lane交付——155/155全绿,模板哲学红线全程实证
- lane-math(47测):P1 collision(空间哈希broadphase+圆AABB凸SAT带MTV+射线;brute-force对照fuzz不漏报)/P2 physics-lite(弹道解析解对照+弹簧三阻尼态+6000次fuzz无NaN+时间步收敛;与P1零编译依赖,碰撞经回调注入)/P4 gamefeel(输入缓冲/coyote/缓动13函数/连击窗,全受控时钟驱动)
- lane-vfx(27测):P3 particles-juice(发射器+burst/trail/drift中性预设+hit-stop/屏震/闪白/缩放脉冲;同seed逐字段复现;屏震amplitude=每轴上界裁定三处注记)/P5 palette-post(调色引擎零成品色板,空映射恒等专项断言;vignette/Bayer抖动/扫描线)
- lane-sys(43测):P6 audio-music(vendor ZzFX+ZzFXM bit-for-bit上游比对maxdiff=0,删模块期new AudioContext改受控注入;情绪分层声部矩阵;null上下文静默降级)/P9 save(命名空间+32KB守卫+坏档容错;alpha本地adapter,SDK契约补丁列β不虚称)/P10 runtime-probe(六锚点FNV-1a链防篡改四式;借channel-probe形状零渠道语义,grep实证)
- 主会话收编四关:155/155亲验/9 manifest全过/品类语义grep全为负向注释/禁用API 14命中全为红线声明注释零真调用;lane-math REPORT按§6代落盘

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 11:56:07 +00:00
zizi
6f854851f5 feat(game-runtime): core-protocol-v0 冻结(Gate0.1 受控面补丁,38/38 绿)
- 受控面 v0 六项冻结:getContext2d/onFrame/getInput/getAudioContext/time/random
- getInput=归一化事件订阅面(5枚举,host注入桥+_emit测试口,dispose自动清理防泄漏);getAudioContext=lazy单例无工厂返null告警降级
- per-plugin 派生随机流(FNV-1a子种子,序列互不影响同seed复现,向后兼容回退);useContext 守卫(友好错误带插件名)
- 向后兼容增量不bump版本;manifest schema 未动;三 lane 按此冻结面开工

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 11:28:52 +00:00
zizi
f59991b9f3 feat(game-runtime): T1b-α Gate0 七件落地(core-protocol-v0-rc)
- core 协议:Plugin 接口/注册器(重名拒绝/生命周期正序逆序/dispose幂等/错误隔离不连坐)+受控面 PluginContext(禁直透 littlejsengine)——前任agent核心设计17测绿收编(死于收尾的工具调用解析失败,续作字节级未碰)
- _example 空插件样例五件全(克隆母本)+PLUGIN-TEMPLATE 六节规格+manifest schema+零依赖校验器(负例自检逮6违规)
- scripts:esbuild锁参build/增量法size/test.sh遍历;browser-evidence harness纯计算口径冻结(FNV-1a/直方图/几何,CDP四函数=集成段占位)
- 22/22 测全绿(RESULT.txt 留档);ESM JS+JSDoc+手写d.ts 零工具链纪律全程
- rc 状态:待 Gate0.1 受控面补丁(input/audio+per-plugin派生RNG+useContext守卫)后冻结 core-protocol-v0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 11:10:12 +00:00