109 Commits

Author SHA1 Message Date
lili
490dc6293d fix(saa): 包级 assets 接通源 sourceProject.assets[]——闭合产消断链(兑现 engine-E2/E3 消费侧 TODO)
gen-done 出包历史上把包级 assets 硬置空(setAssets(emptyList)),丢掉源
gameDefinition 已落库的六类源资产(game_source_project.source_json 顶层
assets[6]),造成产(asset 节点写源)→消(组包)断链。

改 SaaGraphDispatcher.buildCallbackReqVO(in-JVM SAA 路,即 generic/engine
任务真实落包路):新增 extractSourceAssets(s,traceId) 从图终态 K_SOURCE_PROJECT
抽顶层 assets[] 忠实映射进 reqVO.assets;DifyCallbackTxService.buildGamePackage
读 reqVO.getAssets() 即自然带进 GamePackage.assets。

- 形态:源 assetSpec={id,category,ref,provider}(source-project.schema.json
  #/$defs/assetSpec),运行时 gd-runtime 经 gdef.assets 同形消费;geom:<cat> ref
  系几何占位资产引用,原样透传,不伪造包契约 strict AssetSpec 的
  type/url/hash/bytes/mime(无真图/真 sha256,伪造即脏数据)。
- best-effort 非阻断(严格 additive):源缺失/空白/非 JSON/无 assets 键/非数组/
  异常一律回退空集,绝不外抛、绝不打断 SAA 生成;存量无源回调字节零变化。
- 复用既有 parseTrace + TRACE_MAPPER(只读,无共享可变状态),不引新依赖。

不动 AigcGenerateExecutor:440:该处为进程内 clicker/merge 旧路(generic/engine
经 dispatchGeneric 早返,不达此行;worker 回调由独立 reqVO 驱动),作用域无
sourceProject,改它即凭空伪造,故按现状保留(对齐 run_batch.py assets:[])。

验证:mvn -o clean install -pl game-module-aigc-server -am 编译 BUILD SUCCESS;
DifyCallbackServiceImplTest+AigcGenerateExecutorTest 41 tests 0 fail(含
in-process 路 getAssets().isEmpty() 断言仍过,确认未回归)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-21 10:50:40 +08:00
lili
ad22be9b3a feat(saa): Phase 2 Template-First gamedef 骨架机制(flag 旁挂默认关;A/B 负面=不迁移到便宜 thinking-off)
机制(OpenGame +10.1 杠杆试落):
- SaaSkeletons 加载器:archetype→3 金标准过门纯净骨架(gd-breakout/tictactoe/simon,verdict.pass=true+rt纯净+过 Phase3 坑门),按 (tick/input) profile 映射;经济类(merge/idle/tycoon)无近似骨架不登记=走无骨架,绝不喂低质骨架。
- 注入:SaaPrompts buildGameDefMessages(openai 首生成)/historyFirstUser(anthropic 首轮) 追加骨架段(结构参照、非照抄,题面不符以题面为准);救场轮不注。
- pom 拷 contracts/agent-loop/skeletons/*.json 进 classpath。flag -Dsaa.gen.skeletonFirst=1 开,默认关=生成字节零变、零回归。

A/B 实测(thinking-off + skeleton conc=12 vs A 基线):
- 7/12(58.3%) ≤ A 8/12(67%),失败仍 E_live 哑火(#4,5,9,11,12) → 骨架没把基线拉向 91.7%。
- 结论:+10.1 骨架杠杆【不迁移到便宜模型+thinking-off】——哑火是推理缺口(thinking 补)、非结构样例缺口(骨架补不了)。thinking-ON(anthropic 91.7%)仍是唯一真杠杆。
- 处置(创始人定 A):保留机制 flag 关、可逆——换更强模型/配合 thinking 时或有用;默认不启用。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 12:53:02 -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
0cd1496399 feat(saa): U5 openai 格式 M3 路 — thinking:disabled(extraBody)+ openai NO_PROXY
Plan A U5「切 OpenAI 格式」(创始人 2026-06-19):
- model(): MiniMax 系经 OpenAiChatOptions.extraBody 注入 thinking:{type:disabled} 关推理(治 chat.completions 内联 <think> 污染;探活实证 reasoning:effort:none 不被网关认、唯 thinking:disabled 有效);仅 model 名含 minimax 注入,deepseek 字节零变
- openAiApiNoProxy(): openai 路同 anthropic 旁路系统代理(macOS clash 把 Tailscale IP 走代理→502);dispatcher openai 分支改用之

实测(openai+M3+thinking off,K=10/diverse-10):0 超时/0 <think>残留/0 502 = 路干净;成功率 1/10(10%)。
三臂对照(同 diverse-10/K=10):deepseek(anthropic) 30% > M3(anthropic+thinking,超时假象) 10% = M3(openai+thinking off,干净) 10% → M3 在 gamedef 生成上真逊 deepseek,非协议/超时假象。失败主因 llm_error(无有效 bundle)+ 到门者 F_wiring/G_input/E_live/H_progress(driver/引擎接线)——两模型同款,杠杆在 pipeline/接线非换模型。
不碰 gd-runtime/build-from-source(Plan B 域)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 11:47:46 -07:00
lili
1cd199cb3c feat(saa): U5 M3-only override(bake-off)+ 10 品类多样验证集
Plan A U5「只用 M3」(创始人 2026-06-19;deepseek 留作最终模型对照):
- SaaStudioGraph.Models.allSame(model): 全 11 角色统一模型工厂(bake-off 用)
- SaaGraphDispatcher: saaForceModel 非空→Models.allSame(全角色统一、无跨家回退)+ 单模型路日志;空→stage1 默认(deepseek 主力,字节零变)
- AigcExecutorProperties.saaForceModel(默认空=字节零变)
- SaaFullGraphE2eTest: -Dsaa.e2e.model flag(全角色统一模型)+ [config] 打印
- saa-e2e-briefs-diverse10.txt: 10 个不同玩法品类(覆盖 U4 全 8 driver 家族 a-h),优于按行序前 10(仅 4 品类聚集)

验证:编译绿(test-compile exit 0)。默认 saaForceModel 空→stage1(deepseek)字节零变,仅 dispatcher=saa 生效。
实测对照(K=10/diverse-10/anthropic):deepseek 主力基线 3/10(30%,主因生成 llm_error,到门者败于 F_wiring/G_input/E_live/H_progress);M3-only 基线量测中。
不碰 gd-runtime/build-from-source(Plan B 域)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 10:22:45 -07:00
lili
5fde4e2609 Merge remote-tracking branch 'origin/dev/2.0.0' into feat/mac-gamedef-qc-concurrent 2026-06-19 09:35:43 -07:00
lili
b3f2fe8e85 feat(saa-e2e): U5 量测前置 — e2e 接线 anthropic 协议 + 可配端口基址(默认字节零变)
U5 收敛环前置(量测面 additive,默认全字节零变):
- -Dsaa.e2e.protocol(默认 openai)→ props.setSaaModelProtocol:补 U1 量测面孪生(P1-6)。旧版无此接线 → 会量 openai 默认路而非 anthropic = 违 R1「量==发、在用协议=anthropic」。
- -Dsaa.e2e.playPortBase/cdpPortBase(默认 4320/9222)→ props.setSaa{Play,Cdp}PortBase:与本机 superpowers-chrome(持 9222)等进程共存防撞(量测可 cdpPortBase=9322;serve-and-play 净场只杀本槽端口、不误杀他者)。
- [config] 打印增 protocol/playPortBase/cdpPortBase。

验证:pilot 实跑 [config] 行确认三 flag 生效(sourceMode=gamedef, protocol=anthropic, playPortBase=4320, cdpPortBase=9322);编译绿。默认 openai/4320/9222 = 现行字节零变。
注:同次 pilot 揭网关 deepseek 全系(flash/pro/chat/v3)在 svip 组无渠道(全 503 model_not_found)阻塞生成,唯 MiniMax M3/M2.7 可用——属网关侧、待创始人裁;本提交仅 harness 接线,与模型可用性正交。
不碰 gd-runtime/build-from-source(Plan B 域)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 09:33:57 -07:00
lili
12abfbac4a feat(saa): U3 gamedef 量测路 + 有界并发池 harness(默认 K=1 字节零变)
003-U1 U3「量对路 + 有界并发(量测用)」:
- AigcExecutorProperties: saaConcurrency(默认 1)/saaPlayPortBase(4320)/saaCdpPortBase(9222) — 默认全为生产字节零变值
- SaaGraphDispatcher: newSingleThreadExecutor→newFixedThreadPool(K) + Semaphore(1)→Semaphore(K) + K 个错开端口槽池(第 i 槽 playPort=base+2i/cdpPort=base+i);runGraphAndCallback 起手 take 槽 + acquire 许可、整 job 持槽、finally 必归还防泄漏;端口覆盖放 runGraphAndCallback(保 buildInputs 签名不变,反射测兼容);构造期 null-properties 兜底(K=1+默认端口,修 TraceTest NPE);allocPortSlots/normalizeConcurrency 抽为可单测纯函数 + 共享面审计结论入注释
- SaaFullGraphE2eTest: 加 -Dsaa.e2e.sourceMode(默认 factory,量 gamedef 须显式设=修发现②量错路) + -Dsaa.e2e.concurrency(默认 1)
- 新增 saa-e2e-briefs-gamedef.txt(34 条多品类≥30) + saa-e2e-briefs-holdout.txt(12 条留出集,与调优集及内置 ALL_BRIEFS 零重叠)

量对路(发现②修复):旧 e2e 只 setDispatcher("saa") 未 setSaaSourceMode → props 默认 factory(iife),量的是旧路;现 setSaaSourceMode(sourceMode),量 gamedef 真基线须 -Dsaa.e2e.sourceMode=gamedef。
K=1 字节零变:newFixedThreadPool(1)≡单线程串行 + Semaphore(1) + 仅槽 0=[4320,9222],与改造前逐字一致。共享面审计(只读 serve-and-play.sh,脚本未改):K>1 下端口为唯一真冲突点,净场 lsof|kill 只杀本槽端口、static-serve 只读共享根、evidence 按 gameId 隔离 → 跨 job 安全。
并发口径(plan 2026-06-19 创始人指令对齐):K 是量测用「真玩并发」上限,受 Mac 实时九门帧预算硬限(C_frame/E_live,~3-4),非 M3 API 限;生成端(网络限)的宽并发(gen≫play 时)留 U5 量 gen:play 占比后按需解耦,不在本单元。
验证:编译绿;GateLogic+TraceTest+NodesRegression+PickAnswer 指定集独立复跑 exit 0、零失败标记;agent -am 全 SAA 包 101/0/0/3skip。真跑 K 路校准(verdict 对等+结构隔离)延 U5 执行期。
默认 K=1/sourceMode=factory 现行字节零变;不碰 gd-runtime/build-from-source(Plan B 域)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 08:48:53 -07:00
lili
08aa0c13d0 feat(saa-prompt): U4 DESIGN_SYSTEM 8/8 driver 决策树 + gatespec 约定
003-U1 杠杆③(上下文)+②(门约定):
- DESIGN_SYSTEM 规则③补齐至 8/8 driver(对齐 play.cdp.cjs:206-214):补 tap-pairs/key-cycle/drag-aiming/aim-fire(各含何时选/worked-example/反例/命门),旧 none 重标 (i)
- 命门:障碍/目标跟踪类须显式产命名实体(nextGap/nextPlatform/ship.angle)+ 消除类 tap-pairs 得分落 score;drag-aiming 抛射 launch 常数 gd 路难导出→诚实标「优先 iife 源」
- GAMEDEF_SYSTEM 同步 driver 命名/进展约定;门约定:消除类 tap-pairs+score 过 H、I_control 按 control-scheme 分型(不改门本体)

验证:编译 BUILD SUCCESS;回归 49/0(SaaStudioNodesRegressionTest 14〔原8+新6 gatespec 保真:8 driver verbatim+逐 driver 字段+ballPath 归一隔离〕+ topology 30 + pickAnswer 5)。
只动 SaaPrompts 常量 + 测试;不碰 gd-runtime/build-from-source/.agents。

跨 Plan 遗留(转交 6c6g/Plan B):drag-aiming gamedef 路需 gd-runtime entityView 增 launch{gravity,powerScale} 投影通道才能解析瞄准;aim-fire 双路 targetsPath 命名分叉(iife asteroids / gamedef targets)已分别教对;真效(driver 选对率)留 U5 量。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 08:26:41 -07:00
lili
766749d3c1 feat(saa): U2 连续对话救场(text 历史)+ P1-1 交替修 — 简化自 thinking 保留
003-U1 U-B(创始人 2026-06-19 定:简化为 text 历史):
- 历史保留:anthropic 路把上一版【答案文本块】跨轮入历史(K_MSG_HISTORY_GAMEDEF/FACTORY 隔离;ReplaceStrategy+节点内 read-append-write),连续对话救场=模型看上一版答案+失败 verdict 增量修(SaaPrompts.historyRepairUser 去"重出完整模块")
- P1-2(对抗验证反编译证):stock spring-ai-anthropic 1.1.2 出站 buildMessages 丢 thinking 块→内存留 thinking 一下发即拍平成 text→"interleaved 保留"不可达;故 appendHistory 滤 thinking 块(isThinkingMsg=metadata 含 signature)只留答案,简化 boundHistory(最近 K=3 轮 text)。真 interleaved 留 plan T-FUTURE-1
- P1-1(对抗验证证会 HTTP 400 硬崩):失败轮 append 悬空 user→连续 user→Anthropic 拒。双保险修:失败轮整轮不入历史 + assembleConversation 末条 user 去尾
- openai 路 historyEnabled=false 字节零变(useHistory=historyEnabled&&!regeneratePath;builder/SYSTEM 一字未动)

验证:serde/fidelity/失败路 6/0(含 FlakyChatModel 失败路回归门 assertStrictAlternation)、回归 45/0、全 saa 包 92/0/6、烟测 1/0;真网关多轮交替 wire 验证证 P1-1 修有效(system+user+assistant+user 无 400)。
不碰 gd-runtime/build-from-source/.agents(Plan B/6c6g 域)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 08:16:07 -07:00
lili
19f666cd5d feat(saa): U1 用对 M3 — Anthropic 协议 client(flag 旁挂)+ 多 Gen 取答案 + per-role thinking budget
003-U1「用对 agentic M3」:
- AigcExecutorProperties: saaModelProtocol(默认 openai)/saaAnthropicBase(host 根)/saaThinkingBudget
- SaaStudioGraph: RoleModelFactory + anthropicModel(host 根 baseUrl·x-api-key·Proxy.NO_PROXY·per-role budget=min(全局,maxTokens-1024)≥1024 才开 thinking) + openAiFactory(逐字等价旧路) + factory-based build 重载
- SaaGraphDispatcher: ensureGraph 按 saaModelProtocol flag 选 openai/anthropic 工厂(openai 默认路调用不变)
- SaaStudioNodes: pickAnswerText 遍历 getResults 取「无 signature 末块」为答案(单 Gen=旧路字节等价),替 callAndRecord/judgeVision 的 getResult().getText()

实测定死(spike + 创始人 2026-06-19 网关治本):x-api-key→M3 原生 thinking 分离 block(getResults size=2,thinking 带 signature);Bearer / 带 /anthropic 前缀 = 坑。
验证全绿:编译;烟测 size2 取对答案;P0-2 专项(全 11 角色 assemble 不崩,SaaAnthropicAssembleTest 2/0/0);回归 43/0/0(openai 字节零变);依赖树 spring-ai-anthropic 1.1.2 无漂移/无 autoconfigure。
flag 默认 openai 现行字节零变;不碰 gd-runtime/build-from-source(Plan B 域)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 06:18:55 -07:00
lili
ff46b90ee7 fix(flyway): 删 5 个 module 迁移重复副本——消同版本重复致 dev/2.0.0 启动失败(P0 #3)
Flyway 在 classpath 撞同版本即拒启(Found more than one migration with version):V6/7/8/9/18 既在
huijing-server 聚合(V1-V25,已应用到 live = 单一事实源)又各在 module-server 重复(06-18 各 lane 加功能误放)。
删 module 副本、留 huijing-server 聚合:
- V6/V8/V9/V18 两边 md5 完全一致 = 纯去重
- V7(trade) 仅注释差异(列定义同;game_trade_grant 表在 V21 不在 V7)→ 留 huijing-server 已应用版
  (改已应用迁移会 checksum 漂移;module 副本的注释改动弃)
全仓扫描:删后无重复版本、无 module-only 迁移(30=25 聚合+5 副本)。库停 V17 未污染。
注:依赖自身 db/migration 的 module 测试若存在需后续改 test-scoped schema(本修以解 boot 为先,redeploy -DskipTests 不受影响)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 05:55:09 -07:00
lili
de3bf4cb62 fix(compliance): 消 CompliancePolicyController bean 名冲突(P0 孪生,补齐 84c6bd02 漏修)
84c6bd02 仅修 ComplianceAppealController 一对;隔离 :48090 门又拦下孪生:CompliancePolicyController
(admin/app 同名裸 @RestController) → 默认 bean 名再撞 → 仍 ConflictingBeanDefinitionException 启动失败。
全仓扫 108 个裸 controller,这是唯一剩余同类冲突。各加显式 bean 名:
admin→compliancePolicyAdminController / app→compliancePolicyAppController。
修后全仓再无重名裸 controller(扫描实证)+ 无 @Service/@Component 同类冲突 → dev/2.0.0 后端应可启动。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 04:59:19 -07:00
lili
84c6bd0233 fix(compliance): 消两个 ComplianceAppealController bean 名冲突——dev/2.0.0 后端无法启动(P0)
admin 与 app 两包下同名类 ComplianceAppealController 均用裸 @RestController → Spring 默认 bean 名
都是 complianceAppealController → ConflictingBeanDefinitionException → 整个 context 启动失败。
staging 重部署隔离 :48090 安全门拦下此回归(live 未切、零回归)。各加显式 bean 名消歧:
admin→complianceAppealAdminController / app→complianceAppealAppController。
路径 /compliance/appeal 相同非冲突(框架按包名 controller.admin.*→/admin-api、controller.app.*→/app-api 加前缀区分)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 04:50:24 -07:00
lili
079778fc03 feat(saa-prompt): DESIGN_SYSTEM 补 flap-to-gap/seek-x driver——闭合 driver 词汇缺口上半(cause#2)
规则③ 由 (a)paddle/(b)tap-targets/(c)none 扩为含 (c)flap-to-gap(Flappy:bird.y/bird.vy/nextGap.y)
+(d)seek-x(Doodle:bird.x/nextPlatform.x);键到 gd-runtime 现有按实体 id 投影(无需改引擎),要求代码
agent 把控制体+下一障碍建成命名实体(bird/nextGap/nextPlatform)每帧更新。

实证(deepseek flappy/doodle/runner):driver 选型已修——模型现正确产 flap-to-gap/seek-x(此前 wrong/none)。
cause#2 下半未闭:便宜模型不稳产 nextGap/nextPlatform 障碍跟踪实体(doodle 经 repair 产出、flappy/runner 仍缺)
→driver 半接→仍挂;属生成能力(障碍实体生成)+ repair 反馈须点名缺失实体,留 6c6g/003-U1(余 4 driver
tap-pairs/key-cycle/drag-aiming/aim-fire 同法,契约见 play.cdp.cjs)。SaaPrompts 经 mvn BUILD SUCCESS。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 03:04:23 -07:00
lili
d5d3d09b0f fix(gen-qc): cutover 早读三修——并发化 + assert 进展过滤 + M3 thinking 关闭/宽松解析
1) 并发化(gamedef_quickcheck): ThreadPoolExecutor 跨局并行,每局独立 port/cdpPort(4400+i/9300+i)
   + flush 日志;局内 repair 链恒串行→聚合过门率与串行等价。
2) assert 进展过滤(SaaPrompts.extractGatespec 产线 + quickcheck 镜像): 有进展断言时只留进展断言
   (increased/decreased/changed/比较),丢终局态断言(phase/result==gameover/win、误编码 score=="gameover")
   ——bot 限时常到不了终局但 score 已涨=真有进展(tictactoe 0→9/saolei 0→12 假阴修正);无进展断言则全留
   (规避类 result==win 为唯一信号)。终局完成度另由 expectLatch 把关。
3) M3 协议修(_client._extra_body + extract_json_obj): MiniMax-M3 OpenAI 端点默认 thinking=adaptive、
   <think> 内联进 content→复杂局飙 token→max_tokens 截断丢 JSON(假"parse 失败")。官方关法 thinking=
   {type:disabled}(按 model gate MiniMax);严格 json.loads 失败回退 json_repair(镜像后端 looseParse)+
   <think> 剥离兜底。

实证: M3 parse 6/13→2/13、过门 2→3/13,与 deepseek(4/13)同档=M3 不弱(旧 2/13 系截断伪象)。
SaaPrompts 经 mvn 反应堆 BUILD SUCCESS;Python 经 py_compile+单测+真跑。快走查口径;权威 cutover≥60% 在 mini-desktop。
产线 follow-up(6c6g): Java M3 fallback 路同款 thinking 截断潜伏 bug,须补 thinking:disabled。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 03:04:23 -07:00
lili
730b399dd6 test(saa): 003-U1 验收门工具化——SaaFullGraphE2eTest n≥10 + minSuccessRate 硬门 + token 成本会计
把 SaaFullGraphE2eTest 从「内置 5 条 / 只断≥1 跑通」改造成可作 flip 前置硬门的客观量测工具
(plan 2026-06-18-003 / 003-U1;该路代码 001-U1~U4 已在 dev/2.0.0 落地,本单元只工具化验收门):

- brief:内置扩 5→12 条多品类(偏 realtime/physics/tap-targets/clickable)+ -Dsaa.e2e.briefFile
  外部文件(行式,去空白/跳空行/跳 # 注释,解析空则回退内置);-Dsaa.e2e.n 取前 K(未设=全量)。
- 成功率门:-Dsaa.e2e.minSuccessRate 可配硬断言;默认不设=仅存在性(保 003-U1「先实测真基线再收敛」、
  不破普通构建),显式 0.8 即 flip(003-U2)前置硬门。
- 成本会计:从回调 trace best-effort 抽 prompt+completion token + 升 stage2 计数作成本证据;
  -Dsaa.e2e.maxTokensPerGame 仅软警告不硬阻断(遵创始人「质量优先、允许临时破价、记账对账」)。
  ¥折算 blocked on F3(SaaGraphDispatcher cost 整段省略,§6.3)→ 不造假¥。
- 纯逻辑抽 8 静态方法 + 新增模型无关单测 SaaFullGraphE2eGateLogicTest(覆盖 happy+边界)。

验证:mvn test-compile 全 reactor BUILD SUCCESS;SaaFullGraphE2eGateLogicTest 12/12 过;
e2e 无 -Dsaa.e2e=1 仍 Skipped(门控完好)。质量收敛到≥80% 须 mini-desktop 权威量测(blocked,非本单元)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 16:30:43 -07:00
lili
5f2d0021fd fix(telemetry): P-OPN-08 评审P2整改——公开统计下游异常软降级零汇总(契约永不报错·对齐list非脆失败)+测试
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:56:42 -07:00
lili
c7a58b8c45 feat(project,telemetry): P-OPN-08 创作者公开聚合API@PermitAll(仅status==4·聚合统计无PII)
新增创作者公开主页两只读端点(契约+实现+单测,全 additive):
1) GET /app-api/project/public/creator/{creatorId} @PermitAll
   → PageResult<PublicCreatorProjectRespVO>{id,title,summary,coverUrl,ageRating,
     playCount,likeCount,publishTime,creatorId,creatorName};仅 status==4 已发布作品。
2) GET /app-api/telemetry/public/creator/{creatorId}/summary @PermitAll
   → {creatorId,publishedCount,totalPlayCount,totalLikeCount};对该创作者 status==4 作品聚合。

跨创作者公开读(#1 正确性风险)处理:本仓 DataPermission 仅注册 system DeptDataPermissionRule
(仅作用 AdminUserDO/DeptDO 表),game_project 无任何 DataPermission 规则 → MP 拦截器不追加过滤;
project 的"创作者只见自己数据"一向由 Service/Mapper 手动 eq(creatorUserId) 强制而非拦截器。
故公开读只需按"目标 creatorId(路径参数,非登录人)"+status==4 等值即天然跨创作者,无需 @DataPermission(enable=false)。

口径:publishTime 取 update_time 近似(项目表无 publish_time 列,同 count-published 口径);
公开统计经 project-api getCreatorPublishedSummary 取(发布态权威+play/like 计数列均在 project);
creatorName 经既有 AdminUserApi.getUser().nickname 尽力解析(查不到为 null,无 PII)。

单测(Mockito,test goal GREEN):
- ProjectMapperTest(新):SQL 形态守卫——公开查询恒 status==PUBLISHED(4)+按 creator_user_id 过滤,不放行下架(5)/封禁(6);
- ProjectServiceImplTest(+5):跨创作者读(走 selectPublishedPageByCreator 非 selectMyPage)/creatorName 兜底/空/聚合/零;
- GameStatServiceImplTest(+2):跨创作者经 project-api 聚合(不走"我的作品"归属链)/null DTO 兜零。
mvn -pl game-module-project/...-server,game-module-telemetry/...-server -am test → project 32/32 + telemetry 46/46 绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 13:43:08 -07:00
lili
3e04456097 refactor(studio): U6 上传归属对齐创始人裁定——撤 studio /asset/upload(字节走共享 infra),studio 改 ref 登记;浏览/选用/assetContext + 评审整改不变
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 12:12:04 -07:00
lili
046c061d60 feat(aigc): U7 R-TPL 品类玩法模板注册(经营模拟/剧情互动/解谜闯关/TRPG/非遗科普·constants-only·克隆generic代码生成契约)
注册 5 品类玩法模板(business-sim/narrative/puzzle/trpg/heritage),替代单一 generic 状态:
- 3 处代码同源点:AigcTemplateConstants.SUPPORTED_TEMPLATE_IDS 加 5 ID(保留 generic);
  PromptResourceLoader.TEMPLATE_RESOURCES 加 5 行(pom 通配自动复制资源,零 pom 改动);
  AigcTaskServiceImpl.getTemplateList() 回填 5 TemplateRespVO(中文品类名/说明/示例 Prompt/封面占位)。
- 10 契约文件:每品类 1 prompt(克隆 generic-coder.md frontmatter 形态 + 品类引导正文,范式=agent 写
  GameHostFactory 源码而非填 GameConfig)+ 1 schema(克隆 generic.schema.json 的 bundle 校验结构,
  校验 bundleText/hasGlobalName/bundleRawBytes,draft 2020-12,非旧 config-fill)。
- GameConfigSchemaValidator 无需改(经 getAllTemplateSchemaTexts 自动消费 5 新 schema)。
- 不触 SAA/executor/dispatcher/graph 代码(plan001 领域),仅动模板注册面。
- 测试:PromptResourceLoaderTest 9 / GameConfigSchemaValidatorTest 11 / AigcTaskServiceImplTest 11 全绿;
  启动自检 PromptResourceLoader ready + 校验器编译就绪含 5 新模板。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:45:39 -07:00
lili
bdf452d704 merge(tier1): U3 R-SOC 社区社交(评论/关注/排行ZSET/弹幕WS + 评审整改) 2026-06-18 11:31:32 -07:00
lili
03d59b1672 merge(tier1): U5 R-ADMIN admin运营(限曝光/导出/经营看板 + 跨模块只读-api) 2026-06-18 11:31:32 -07:00
lili
edc3436f7e fix(community): U3 评审整改——P0 ZSET 移出事务(afterCommit) + P1 弹幕长度门/弹幕广播出事务/举报接缝去重 + P2 注释与公开读
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:30:07 -07:00
lili
a6f8f58d23 fix(studio): U6 codex 整改——P0 FileApi 移出事务 + P1 magic-byte类型校验/选用悲观锁/草稿态守卫
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:17:16 -07:00
lili
ac7ffe4a92 feat(telemetry): U5 经营看板聚合+导出 + 营收报表导出
经营看板(跨模块只读聚合,缺数据兜底不 500):
- 新端点 GET /admin-api/telemetry/dashboard(telemetry:dashboard:query)→ DashboardRespVO,聚合四指标:
  DAU(本模块 game_telemetry_event 去重活跃身份:登录 user_id + 匿名 anon_id,取 statDateEnd 当日,
  新增 TelemetryEventMapper.countActiveIdentities)+ GMV(trade-api)+ 生成量(aigc-api)+ 发布量(project-api)。
- DashboardServiceImpl 容错:每个数据源独立 try-catch + CommonResult 解包兜底——任一源不可用→该指标兜底 0
  + degraded/degradedSources 标记,整体不 500(看板可用性优先);正常空数据(data=null)不算降级。
- 导出 GET /admin-api/telemetry/dashboard/export-excel(EXPORT 审计)单行导出看板快照。
- telemetry-server 加 trade-api/aigc-api 依赖 + starter-excel。

营收报表导出:TradeAdminController 加 GET /admin-api/trade/report/revenue/export-excel
(trade:report:export + EXPORT 审计),抽 buildRevenueReport() 与 /report/revenue 共用口径避免漂移。

测试:DashboardServiceImplTest 6(全可用聚合/单源抛异常兜底/CommonResult非0兜底/data=null不降级/
全跨模块故障DAU仍可取/跨模块只读 never 写方法)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:06:57 -07:00
lili
f85ae6c434 feat(feed): U5 限曝光降权 + 精选池导出
限曝光(boost 的反向运营操作):
- Flyway V25.0.0 加 game_feed_rank.exposure_limit DECIMAL(10,4) NOT NULL DEFAULT 0(additive,
  镜像 contracts/db-schemas);FeedRankDO 加 exposureLimit 字段。
- 排序口径升级为 sort_score = quality + boost - exposure_limit,统一收敛在 deriveSortScore()——
  setFeatured/setExposureLimit/发布基线重发布/算分回灌四写入点共用,保证 boost/exposure_limit 两个
  运营维度在任意写入路径都被保留(限曝光穿越 telemetry 算分回灌存活,已单测验证)。
- 两层效果:① 普通降权(0<x<9999)持久化进 sort_score 使游戏下沉(cursor 分页仍正确);
  ② 硬限曝光哨兵(>=9999)在 buildStream 出流处剔除(复用既有二次过滤续取机制,不动 status、可随时改回)。
- 新端点 POST /admin-api/feed/exposure-limit(复用 feed:featured:update 权限 + @ApiAccessLog UPDATE 审计),
  门禁=仅已发布且已有排序行(不新建孤儿降权行);错误码段 1-103-005-***。

导出:GET /admin-api/feed/featured/export-excel(feed:featured:export + EXPORT 审计)经 ExcelUtils
导出精选/限曝光排序覆盖层运营字段;空数据写表头。feed-server 加 starter-excel 依赖。

测试:FeedServiceImplTest 25→35(限曝光门禁/降权扣减/硬限曝光出流剔除/普通降权不剔/回灌保留限曝光/导出列表空与非空)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:06:35 -07:00
lili
240a18fc33 feat(trade-api/aigc-api/project-api): U5 看板只读count方法(additive)
为 U5 经营看板补三个跨模块只读数据源 seam(均 additive,删除后各模块既有单测仍绿):
- trade-api:新增 TradeApi Feign 接口 + TradeRevenueReportDTO + trade-server TradeApiImpl
  (@RestController @Primary 委托既有 IncomeService.sumGross/sumNet + WithdrawService.sumPaidAmount,
   口径同 /admin-api/trade/report/revenue)→ 看板 GMV。
- aigc-api:AigcApi 加 countSucceededTasks(start,end)(impl 委托新增 AigcTaskMapper.countSucceededBetween:
  status=succeeded 且 finish_time 落区间,零 DDL)→ 看板生成量。仅 additive:不动 SAA/executor/生成代码。
- project-api:ProjectApi 加 countPublished(start,end)(→ ProjectService.countPublished → 新增
  ProjectMapper.countPublishedBetween:status=PUBLISHED 且 update_time 落区间,零 DDL)→ 看板发布量。
  时间维度为 update_time 近似(项目表无独立 publish_time 列,已注释说明)。

跨模块只读,无任何写;自然日端点在各 impl 展开为全天 LocalDateTime 区间。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:05:56 -07:00
lili
3f35acb4d3 feat(community): U3 R-SOC 评论/关注/排行ZSET/弹幕WS
社区社交后端四子能力(game-module-community),克隆通知底座/feed互动幂等范式:

- 评论 Comments:CRUD + 举报转 compliance。删除按 userId 归属强校验(防越权删他人评论),
  举报落本端举报态幂等 + 事务提交后 afterCommit 接缝(compliance 无受理 -api,留桩 OPEN ITEM)。
- 关注 Follow:active 软开关幂等切换(不删行,范本=feed FeedInteractLog),不能关注自己,
  并发双插由 DB 唯一键 DuplicateKeyException CAS 收敛;粉丝数/关注数 countActive。
- 排行 Ranking:Redis ZSET + ZSET↔DB 一致性窗口。DB=真相、ZSET=缓存索引:
  写穿透双写(DB 原子累加 + ZSET incrementScore)、ZSET 缺失/启动从 DB 回填重建、最终一致;
  维度白名单 RankDimensionEnum(game_hot/creator_hot)。
- 弹幕 Danmaku:WebSocket 单机最小实(LocalWebSocketMessageSender),自维护房间 gameId→sessionId
  注册表做房间维度广播(框架仅按用户维度推送),断连懒清理;多实例需切 sender-type=redis(MQ future-state 未部署)。

契约/库表:
- Flyway V23.0.0(U3 独占 V23.x):game_community_comment/follow/rank/danmaku 四表 +
  幂等唯一键(follow uk(user_id,target_user_id,deleted,tenant_id)、rank uk(dimension,target_id,...)),
  同步 huijing-server/db/migration + contracts/db-schemas。
- community.yaml additive 加 8 个 app 端点 + 5 个 schema(既有冻结)。
- 错误码段 1-107-004 评论 / 005 关注 / 006 排行 / 007 弹幕。

验证:mvn -pl game-module-community/game-module-community-server -am test -o 全绿
(57 tests:新增 U3 35 + 既有 22;CommentService 9 / FollowService 8 / RankService 8 / Danmaku 10)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 11:01:24 -07:00
lili
09ced58930 feat(studio): U6 R-MAT 素材实体/浏览/选用/上传(compose infra FileApi)
R-MAT 创作者私有素材库(六类 sprite/character/effect/scene/ui/music,冻结同枚举):
- StudioMaterialDO + game_material 表(V24.0.0,归属 creator_user_id,idx_owner_cat)
- 3 端点 /app-api/studio/asset/{upload,browse,select}(studio 领域端点,需登录用户)
- upload:六类校验 + 大小≤10MB + 每类目 MIME 白名单 → composes huijing-module-infra
  FileApi.createFile 存字节 → provider 包装 ref → 落库 → 返回冻结 StudioAssetContextItem
- browse:owner-isolated 分页(强制 eq creator_user_id),可选 category 过滤
- select-into-draft:把本人素材 ref 写入草稿会话 assetContext(JsonUtils 序列化,按 ref 去重合并)
- MaterialProvider SPI + 工厂 + mmx-cli mock(graceful degrade,仿 AdProviderFactory)
- 错误码段 1-112-005-***(七个);studio.yaml 加 3 端点 + schemas(additive)

验证:mvn -pl game-module-studio-server,-api -am test 全绿
(StudioMaterialServiceImplTest 17/17,studio 模块 61/61)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 10:54:56 -07:00
lili
6a9bd4d349 fix(saa): 6c6g 评审整改——P1 K_STATUS 清零 + P2 stage2 fallback 注释
P1(真修):renderNode 起手 out.put(K_STATUS,"") 清 stale 状态——checkpoint/saver 跨 run 复用 state 时,
  上轮 giveup 写的 K_STATUS="failed" 会残留,下次 modify 进来 modifyRouter 首检 K_STATUS 误判失败、
  把 gamedef 确定性点改错误路由到 END。
P2(语义·仅注释):generateNode fallback 处加注,说明 stage2 升档后回退档仍取廉价档(MiniMax-M3)是
  「可用性优先于本次升档边际质量」的有意取舍(强档超时也要出包),非疏漏。

验证:mvn -Dtest=SaaStudioGraphTopologyTest,SaaStudioNodesRegressionTest → Topology 30/30 + Regression 8/8 全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 09:20:49 -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
c24b7fb4d2 fix(saa): GAMEDEF_SYSTEM 加 tap-targets few-shot(harness 探针证 9/9 正确)+ 快走查 repair 可配
plan 2026-06-18-001 U3 迭代2轮:据 cutover 早读「tap-targets 类系统性 5/9(E_live/F_wiring)」根因诊断+整改。

根因决断(harness 受控探针,无 LLM):把**手写 known-correct tap-targets gameDefinition**直接过全 harness
  → **9/9 真过**(E_live distinct=8/8、F_wiring 12 引擎调用)。**故运行时+装配器+tap-targets driver+约定全正确**;
  whack/tictactoe 失败 = **便宜模型生成质量**(tap-handling 写错:点击未判中→无 spawn/fx/计分→画面恒定),非基建/集成 bug。

GAMEDEF_SYSTEM 加 tap-targets few-shot(SaaPrompts.java):tile 网格每格 tags:["target"]+idx+occupied,
  justTapped→pointer overlap 判中→occupied 翻+spawn 标记(可见)+addScore+fx;win=score>=N。
  few-shot 本身经探针证 9/9 正确(教对 idiom);实测使模型确给 target 打标(gd-whack 9/10 tagged)。
  残留 tap-handling 精度=R3 便宜模型质量,靠 **repair 回环(真图 5+3 轮,本机只跑 3)+ stage2 升档(强档)** 解。

快走查:MAX_RETRIES 改 QC_MAX_RETRIES 环境可配(真图 maxRepairs=5,本机早读取 3 平衡时延)。

结论:**gamedef 路两大品类(realtime/physics + tap-targets)路径均证正确**;首攻便宜模型质量随品类波动,
  cutover 率 = repair 预算 + 模型档 的函数(二者在 mini-desktop 全图满配)。≥60% authoritative=mini-desktop。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 02:42:41 -07:00
lili
da4801828d fix(saa): GAMEDEF_SYSTEM driver 对齐加固 + 快走查升级全图镜像(design+gamedef)——据 U3 早读根因
plan 2026-06-18-001 U3 迭代1轮:据 lili-mac gamedef 快走查根因诊断,加固 GAMEDEF_SYSTEM 与九门 driver 的对齐。

快走查根因(design+gamedef 全图镜像, deepseek-v4-flash 单发无 repair):
- 路径端到端真成立:声明式 gameDefinition→装配→构建→真九门;pong 9/9(无 design 简版)、breakout 8/9。
- 单发首攻失败模式根因:① I_control——挡板命名变体(paddlePlayer≠gatespec 的 paddle)/ 只接键盘不接指针(driver 靠点指针位驱动)
  / 控制体 clamp 范围窄于 driver 边缘 tapX(340);② H_progress——设计稿 assertAfterPlay 引用取证读不到的自定义字段(totalRound)。

GAMEDEF_SYSTEM 加固(SaaPrompts.java,gamedef 路专属,不动现 SYSTEM):
- 命名逐字对齐 gatespec(挡板=paddle、球=ball,别用变体——读到 undefined=挂)。
- 可控体必须响应指针(`if(rt.input.pointer.down) paddle.x=rt.input.pointer.x`——driver 靠点指针位驱动,只接键盘=I_control 挂)。
- 进展落在可取证字段(score/remaining/实体位置;assertAfterPlay 别用读不到的自定义字段)。
验证:再跑 breakout 模型确按指令接指针控制(`if(pointer.down) paddle.x 追 pointer`)+ I_control tapX:50 已过;
  残留 tapX:340 未过=首攻 clamp 范围精度,属**repair 回环**(已建:验收失败→verdict 回喂→重生成)territory。

快走查工具升级(gamedef_quickcheck.py):加 design 步(抽 DESIGN_SYSTEM+复刻 extractGatespec)→ 全图镜像
  (classify 略/design→gamedef→装配→九门),getter truer 早读;prompt 抽自 SaaPrompts.java drift-free。

定位:单发快走查=首攻质量早读(非 cutover 门)。**≥60% cutover 门=全图含 repair 回环, authoritative=mini-desktop
  SaaFullGraphE2eTest -Dsaa.e2e=1**(单发 0/6≠失败:repair 回环抬升率,本机不跑 repap 多轮)。密钥经 _client 读 .env 不入码。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 00:58:01 -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
zizi
0db1d0da6d fix(trade): AccountServiceImplTest grant 测试补 insert 回填 id(test-only)
原 impl agent 未跑测试漏:mock insert 只 thenReturn(1) 未回填自增主键,
grant() 返回 grant.getId()=null → assertNotNull 失败。改 thenAnswer 模拟 MyBatis 回填。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 04:02:46 +00:00
zizi
ec23ff61bc feat(compliance): U4 R-ACC 政策正文页+申诉回路
codex 评审 MERGE-WITH-FIXES→修 P0(申诉重复提交守卫:STORED生成列pending_flag+uk_user_ban_pending局部唯一+@Transactional+DuplicateKey友好返回)+P1(@Transactional/@Size/@Min)。V22。plan 2026-06-18-002 U4。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 03:56:58 +00:00
zizi
ca53a0db0c feat(trade): U2 R-ECON admin赋余额+会员订阅(独立流水表+幂等)
codex 评审 NO-MERGE→修 P0(订阅幂等漏洞:独立幂等账本表 game_trade_subscription_grant+uk_biz_no,延期前先写、同事务)+P1(VO @Size/totalIncome注释对齐/权限种子SQL)。V21。plan 2026-06-18-002 U2。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 03:56:58 +00:00
zizi
9f2b9f9feb feat(feed): U1 R-FEED feed 游标分页真化((sort_score,id)复合游标+二次过滤续取)
codex 评审 MERGE-WITH-FIXES→修 P0(MAX_FETCH_ROUNDS 高过滤率提前到底丢数据:dbExhausted 区分库尾vs轮次中断,hasMore=overflow||!dbExhausted)。plan 2026-06-18-002 U1。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 03:56:57 +00:00
zizi
bf99662c3f test(aigc): SaaFullGraphE2eTest — SAA 真全图 e2e 首证门控测试(U7)
U7 集成顶石的门控集成测试(-Dsaa.e2e=1 + NEWAPI_KEY)。构造真 5 参
SaaGraphDispatcher(stub callback 捕获 reqVO+latch,DataSource=null 内存
checkpoint,零 DB),顺序跑 N 条一句话 create job,真 LLM(new-api 五角色)+
真九门 harness(node/esbuild/Chrome,4320/9222 串行)+真 16 节点全图
(render→classify→design→generate→validate→scaffold→asset→build→play→player→nreview→emit/giveup)+真出口回调,测成功率。

首证(2026-06-18,mini-desktop):SAA 真全图 e2e 机制完整跑通、零 prod bug;
成功率 3/5=60%(贪吃蛇/接金币/躲障碍 succeeded,engineBundle≈211KB 含 __GameBundle;
打砖块败 I_control、点击消除败 F_wiring+H_progress,救场阶梯耗尽 giveup 真落盘)。
单款墙钟 3.5-16min(九门真玩循环+最多8救场轮固有,同 Python W-G1)。
→ 成功率 60% < 80% 转正门:cutover 未切(现 worker 主链保持默认,零回归)。
gap=难门生成质量(prompt 接地/gatespec/救场调优),W-G1 生成域调优单元。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 00:40:14 +00:00
zizi
679afa1c65 feat(aigc): U5 giveup 真落盘 + U6 modify regenerate 取base源真消费(B4/B7)
6c6g 后端 Tier0 计划 U5+U6(docs/plans/2026-06-17-001-...)。
- U5 giveupNode 真落盘:gameRuntimeRoot 句柄 + attempts/verdict/escalationEvents 整包写盘 giveup-dump.json + K_GIVEUP_DUMP_PATH 回填真路径;
  best-effort 落盘失败仍正确 failed 终态;多级升档 stage3+ follow-up
- U6 modify 不被卡部分:
  · base 源 dispatcher 据 baseVersionId(V19 持久化)反查 SourceProjectApi.fetchByVersionId→K_SOURCE_PROJECT(零新增列/不搬大 blob)
  · regenerate-module 缺 target fail-loud(防静默全量重生成)+ 真消费 base 源(buildRegenerateMessages 注 base 源 JSON+目标 behavior 聚焦,system 不变;create/repair 普通路零变)
  · deterministic guard-pending-E2 一字未动;严格 per-behavior splice-back 依赖结构化源=follow-up(诚实标注)
- -api:SourceProjectApi.fetchByVersionId + DTO
- 测试:aigc 46+studio 44=90 绿(+17 新);codex 评审 NO-MERGE→2 P0(缺target/伪收窄)全修后绿

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 23:02:10 +00:00
zizi
069ae73e97 feat(aigc/worker): U3 trace 扩展键 + U4 缓存命中落账(B5/B9)
6c6g 后端 Tier0 计划 U3+U4(docs/plans/2026-06-17-001-...)。execution §5.8 trace+cost 落值。
- U3 extractTraceQuietly(Java)+ _extract_trace(worker)additive 抽 modelTier/escalationEvents/giveupDumpPath;
  仅真升档态(stage2/escalationEvents 非空)落 modelTier + 形态校验(非空 str/非空 list)→ 字节兼容(无扩展键键集与扩前一致)、Java/Python 两路同口径
- U4 cost.py 缓存命中折¥:两套字段取 max(DeepSeek prompt_cache_hit_tokens / MiniMax prompt_tokens_details.cached_tokens)
  + cache_ratio 折真实 quota;worker usage 捕获(_safe_int 兜脏不抛);pricing 不可达 tokens-only+costFallback 标记;不阻断仅观测
- 诚实边界:SAA Java 路无 cache 字段源→省略不伪造(follow-up);AgentScope 丢 DeepSeek 顶层字段(待真跑对账);worker 生产路完整落账

验证:mini-desktop Java 12+(SaaGraphDispatcherTraceTest)+ Python 73(test_cost 56/wg1_groupb 17)全绿;
codex 评审 NO-MERGE→2 P0(字节兼容/usage 阻断)+2 P1(pricing 口径/两路一致)全修后绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 22:26:27 +00:00
zizi
d57032a6d3 feat(studio): U2 源项目落库事务(B8)+ V19/V20 数据完整性
6c6g 后端 Tier0 计划 U2(docs/plans/2026-06-17-001-...)。execution §5.2 源项目工件落库 + status 机器态串联。
- GameSourceProjectDO/Mapper/SourceProjectService(studio,§12-①)+ SourceProjectApi seam(land/markBuilt/markOrphanById)
- 落库挂回调外层 DifyCallbackServiceImpl(非内层 tx)——守 §5.2「源落库与建包非同一大事务」
  (land 建包前独立 commit/markBuilt 成功后/markOrphan 失败补偿)
- status 0 草稿→1 已构建(回填 version_id)/2 孤儿(不建包不动 currentVersion);
  DifyCallbackReqVO additive sourceProject;dispatcher 从图终态抽 K_SOURCE_PROJECT
- 数据完整性(codex 评审 2 P0+2 P1 全收口):
  · P0 终态任务重复回调跳过 land(防版本血缘污染)· P0 去重按 game_id+source_hash + markBuilt 校 gameId(防跨游戏复用)
  · P1 markBuilt 与 notify 解耦(notify 失败不停 status=0)· P1 markOrphanById 精确标 + V20 唯一键 uk_game_source_hash(并发兜底)
  · post-commit best-effort 包兜底 try(防挂点失败反触写链补偿误置 failed)
- 诚实边界:现图只产最小骨架源(gameDefinition 待生成 agent 真填,跨单元),终态有什么落什么不伪造

验证:mini-desktop 编译绿 + 33 单测全绿(DifyCallback 19/SourceProject 14,含跨游戏/gameId校验/终态重复/notify解耦/markOrphanById);
V19+V20 SQL 结构绿(Flyway-apply 留部署验);codex NO-MERGE→2 P0+2 P1 全修后绿。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 21:46:38 +00:00
zizi
d64dcc9080 feat(studio): U1 studio 生命周期编排 create/modify/extend(B6) + V19 modify 持久化
6c6g 后端 Tier0 计划 U1(docs/plans/2026-06-17-001-...)。生成主线 modify/extend 生产可达。
- /studio/{create,modify,extend} + 5 VO(对齐 studio.yaml)+ StudioServiceImpl 三方法
  (create=draft+generate 复用;modify/extend 经扩展 aigc seam 委托;mode×target 锁定映射校验;白名单+归属门)
- aigc seam:AigcGenerateReqDTO/VO/AigcTaskDO additive 扩 modify 四件套;AigcGenerateExecutor.putModifyFieldsIntoJob
  接进 §6.1 job(键名对齐 buildInputs);project seam getVersionOwnerUserId/getVersionGameId(归属边界)
- V19.0.0__aigc_task_add_modify.sql:game_aigc_task 加 modify_mode/base_version_id/modify_patch +
  AigcTaskDO @TableField 持久化映射 → modify 四件套跨异步 tick 真抵达 buildInputs(化解执行器从 DB 重建无内存续传)
- 错误码 1-112-003-*;additive(存量 modify_mode='' 即现行 create 分流,零破坏)

验证:mini-desktop 编译绿 + 54 单测全绿(Studio 27/Executor 22/Project 5);V19 SQL 结构绿(Flyway-apply 留部署验);
codex 评审 MERGE-WITH-FIXES(0 P0;P2 注释已修)。follow-up(codex P1,计划已 deferred):
  idempotency 去重(契约缺省=不去重,present-dedup 待幂等基建)、taskChain.baseVersionId 轮询回显(即时已回显,轮询待小补)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:39:05 +00:00
zizi
04f3bfeeb6 fix(aigc): B2 codex 评审整改——救场阶梯连贯/escalate真切档/modify guard/RFC6901
codex NO-MERGE→整改:
- P0-1 validate/build/play 硬失败统一 bumpFailCount(救场阶梯 5/8 对各门生效,非仅 play+recursionLimit 兜底)
- P0-2 nreviewRouter 补 escalate 分支(narrative 同 5+3 阶梯,§5.9)
- P1-5 stage2 强档 deepseek-v4-pro(对齐 models.yaml)+ generate 按 modelTier 二维选档(升档真生效)
- P1-6 applyDeterministicPatch 改 RFC6901 JsonPointer(支持数组下标/追加,越界不损坏源)
- P2-8 classify 失败错因记 trace(非 feedback,免污染 generate 修复上下文)
- P0-3 dispatcher 透传 modifyMode/modifyPatch/baseVersionId/sourceProject + 非法 modifyMode fail-loud(禁静默走 create;job 侧填充待 B6)
- P0-4 modify deterministic guard fail-loud(failureReason=源构建管线待 B7+引擎E2;router fail→END,不静默接忽略 sourceProject 的旧 build)
- P1-7 asset 产侧 merge 真(sp.set assets;消费侧 build→GamePackage 待引擎线 E2/E3)
+5 拓扑测试(共 19 @Test 非门控);create-metric 全链连贯;§1.4 硬约束未碰。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 18:08:08 +00:00
zizi
706d014869 feat(aigc): B2 SAA 固定架构图拓扑扩展——+5 节点(classify/asset/modify/escalate/nreview)+ 救场阶梯
execution §6 拓扑落地(opus 实现 + 框架 API 对真 1.1.2.2 jar javap 核验)。11→16 节点,布线唯一源 assemble,无孤儿。
- 5 新节点:classify(真LLM物理优先→archetype/profile三维+§6.4映射表)、asset(六类规格v0+产消打通)、
  modify(deterministic改源/regenerate-module路由)、escalate(stage1→stage2+escalationEvents)、nreview(真LLM叙事审查+needsRepair计failCount)
- 布线:render→classify/modify、classify→design、scaffold→asset→build、play→player/nreview/repair/escalate/giveup、nreview→emit/repair/giveup、modify→build/generate、escalate→generate
- recursionLimitFor(maxRepairs,stage2Extra)=(m+s+1)*10+30,默认(5,3)=120;救场 5失败escalate→8失败giveup
- ALL_KEYS 字面量提升为 K_* 常量(单一源);新 SaaArchetypes §6.4 映射表契约;classify/narrative system prompt;saaStage2ExtraRepairs=3 旋钮
- 新 SaaStudioGraphTopologyTest(非门控:哑API build全图证无孤儿+Mermaid 16节点+recursionLimit+路由单测)
- 初始逻辑标 TODO(B4 救场真切stage2模型/giveup真dump/validate-build计failCount)、TODO(B7 modify深层指针/按id定位)
- additive:create-metric全链不破;§1.4硬约束(GamePackage/宿主/回调/九门harness)全未碰

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 17:33:15 +00:00
zizi
0f380a516b feat(contracts): 冻结 SAA state key 全表(ALL_KEYS +14)+ trace 扩展键 schema(§5.4/§5.8)
契约冻结门收尾(§7.0 剩 2 项后端内部契约):
- SaaStudioNodes.ALL_KEYS +14 键(archetype/tickModel/inputModel/progressModel/sourceProject/
  assetSpec/modifyMode/modifyPatch/baseVersionId/failCount/modelTier/escalationEvents/
  giveupDumpPath/narrativeReviewVerdict),全 ReplaceStrategy;先冻命名空间,classify/asset/modify/
  救场 节点 B2 实现写入(additive,存量节点不读零影响)。
- DifyCallbackReqVO.trace(开放 Map)javadoc+@Schema 文档化固定架构扩展键:
  modelTier/escalationEvents/cacheHit/giveupDumpPath/cost;落值属 B5 impl,trace_json 字节兼容。

验证:本地结构校验绿(14键无重/无撞/引号成对/数组收尾);纯 additive(字符串数组追加+注释级)。
aigc 编译 + V18 Flyway-apply 的整合 mini-desktop 验证随后跑(清验证债)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 16:54:48 +00:00
zizi
ca72fce600 feat(contracts): V18 game_source_project Flyway 迁移(源项目工件表·改源不改产物源侧存储面)
契约冻结增量:execution §5.2 源项目 DB 存储——独立 game_source_project 表(勿塞 game_version)。
两副本(studio 模块 + huijing-server 聚合,字节一致,如 V8 模式)。

字段:game_id/version_id/source_json/source_url/source_hash/schema_version/build_profile/
status(0草稿1已构建2孤儿3已发布)/base_version_id(modify 血缘)+ Yudao 审计列;
3 索引(idx_game/idx_version/idx_source_hash);头注铁律(回滚写 V18.0.1 不改本文件)。

验证:本地结构校验绿(16列/1主键/3索引/括号平衡/InnoDB+utf8mb4/审计列全);镜像已验证的 V8 studio 表约定。
⚠️ Flyway-apply-green 留批量 mini-desktop 部署(与 ALL_KEYS/trace 一并 recompile+migrate)验,本次暂未声称迁移已验。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 16:42:50 +00:00
zizi
7534bdf9b7 feat(create): generic 桥接——一句话创作无需选模板即可生成(入口归一缺省 templateId=generic)
背景:W-CLEAN 废玩法模板层后 template/list 返空,创作页「开始生成」因 canSubmit 依赖
「必须选中模板」而恒禁用;后端 @NotBlank/同源白名单/派发分支/落包一致性四道硬约束又要求
templateId 必填非空。核心思想=在入口把缺省 templateId 归一为 "generic"(恰好命中
SUPPORTED_TEMPLATE_IDS=[generic] 单一通用口径,品类区分留 prompt 层),四道约束以「恰好
generic」全部一致通过,DB 零改(template_id NOT NULL DEFAULT '' 归一后落 generic)、后端业务零改。

契约层(2):aigc.yaml AigcGenerateReqVO required 去 templateId、project.yaml
  ProjectCreateReqVO required 去 templateId,templateId 描述标注「可选,缺省 generic」。
后端层(归一 generic):
  - AigcGenerateReqVO/ProjectCreateReqVO/StudioDraftCreateReqVO 去 templateId @NotBlank +
    requiredMode REQUIRED→NOT_REQUIRED;
  - AigcTaskServiceImpl.submitGenerate 在 validateTemplateExists 前归一(validateTemplateExists 不改);
  - ProjectServiceImpl.createProject(BeanUtils.toBean 后)归一;
  - StudioServiceImpl.createDraft 原「空 templateId 抛 STUDIO_TEMPLATE_REQUIRED」改为归一 generic;
  - ProjectApi.createProject 的 templateId @Parameter required 放开(契约面一致避免 drift)。
前端 game-studio(去模板门):types.ts 两请求体 templateId 改可选;store/create.ts、api/aigc.ts
  generate 入参改可选;Create.vue canSubmit 去「必须选中模板」条件(prompt 非空即可提交)、
  onSubmit 缺省传 'generic'(空态下也能提交)。
测试校正:StudioServiceImplTest「空模板抛错」→「空模板归一 generic 透传 project」(行为变更)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 04:05:39 +00:00