From bc0f486bc26b109d44051c6d174c1e3657a36a54 Mon Sep 17 00:00:00 2001 From: lili Date: Thu, 2 Jul 2026 19:58:42 -0700 Subject: [PATCH] =?UTF-8?q?chore(=E8=AF=84=E5=AE=A1=E6=B8=85=E6=AC=A0):=20?= =?UTF-8?q?W-REAL=20R4=20=E4=BB=A3=E7=A0=81=E8=AF=84=E5=AE=A1=E9=81=97?= =?UTF-8?q?=E7=95=99=2016+1=20=E6=9D=A1=E5=AF=B9=E8=B4=A6=20+=20=E5=AD=98?= =?UTF-8?q?=E6=B4=BB=E9=A1=B9=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 逐条读当前代码坐实(不凭文档推断):16 条 = 7 moot / 6 已修 / 1 存活待修 / 2 本次修; 另协调者追加第 17 条(ad-slot 契约漂移)本次修。对账表全文入总账 §5。 wg1 六项随 Node 退役 moot(生产便宜档=cheap-worker,幂等/max_tokens/callback 已在替代解决); tier2 成本硬闸(item3)经配置控制面阶段一① soft_budget 演进已修(单 POST 内联续修 + CircuitBreakerMiddleware 会话级 spent_rmb 累加 fail-closed);CSP/vue-i18n/validate_play_scene/ 契约真空/服务态主链等 已修;gamedef v1 标注漂移随文件删除 moot。 本次动手修: - G1 品牌门扫描面有洞(item8): docs-gate.py 加 walk_code 扫业务代码目录(模块根 package.json/index.html + wg1/ 等源码),旧门只扫 .md 会放过玩家/管理台可见字面量; 负向测试证真能拦回流。 - 品牌残留漏网(item8): game-admin 菜单标题退役品牌名 → 绘境运营(扩面后被 G1 逮出)。 - ad-slot 契约漂移(R4-17,跨端契约): ad-slot.schema.json provider enum 加 callback (additive)+ 对齐描述;与 api-schemas/ad.yaml 及 ad 模块 CallbackAdProvider(真实现 PROVIDER="callback")对齐。DB VARCHAR 注释/DO Javadoc 仍列 csj/gdt/mock=doc-only (SQL 为 Flyway 版本档不改 checksum),留终审。 - docs-gate.sh 壳注释 六检→七检(失实修正)。 存活待修: item12 tier2 bootstrap X-User-Id 鉴权头口子 + 无重试退避(需真实 deps.py 鉴权契约,部署 smoke 接缝,非本机最小改动可完成)。 验证: docs-gate 七检全绿 + G1 负向测试(植入即拦/删除回绿) + ad-slot JSON 合法 + docs-gate.py 编译 + CallbackAdProviderTest 印证 getProvider()="callback"。 Co-Authored-By: Claude Fable 5 --- .agents/tools/docs-gate.py | 34 ++++++++++++++- .agents/tools/docs-gate.sh | 2 +- contracts/ad-slot.schema.json | 4 +- docs/mvp/MVP进度总账.md | 49 +++++++++++++++------- game-admin/src/router/modules/remaining.ts | 2 +- 5 files changed, 72 insertions(+), 19 deletions(-) diff --git a/.agents/tools/docs-gate.py b/.agents/tools/docs-gate.py index 695ae76e..3b08bca7 100644 --- a/.agents/tools/docs-gate.py +++ b/.agents/tools/docs-gate.py @@ -22,6 +22,17 @@ import sys # 退役品牌根的唯一字面量(活层散文一律用「退役品牌名」间接表述,勿再写出字面量) BRAND_RETIRED = "造梦" +# G1 品牌不变量的代码扫描面(W-REAL R4 补:防品牌回流到模块根 package.json / index.html 与 wg1/ 等代码—— +# 评审曾指出门只扫活层 md 会放过玩家/管理台可见的代码字面量)。业务代码目录 + 相关源码后缀; +# .agents 不入(门自身源码持有 BRAND_RETIRED 字面量,扫它会自噬)、docs 由 walk_md 覆盖。 +BRAND_CODE_BASES = ["game-runtime", "game-studio", "game-admin", "wg1", "tier2", + "cheap-worker", "game-cloud", "contracts", "deploy", "spikes"] +BRAND_CODE_EXTS = (".json", ".html", ".ts", ".js", ".mjs", ".cjs", ".vue", + ".py", ".java", ".yaml", ".yml") +# 依赖/构建产物/归档目录原地裁剪(既防误报也快)。 +BRAND_PRUNE_DIRS = {"node_modules", "target", "dist", "build", ".git", + "_archive", "_recall", ".venv", "__pycache__"} + ROOT = os.path.abspath(sys.argv[1]) if len(sys.argv) > 1 else os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "..")) @@ -56,6 +67,21 @@ def walk_md(bases, exclude_archives=True): return out +def walk_code(bases, exts): + """遍历业务代码目录里指定后缀的源文件(供 G1 品牌扫描面防回流用;prune 掉依赖/构建/归档目录)。""" + out = [] + for base in bases: + top = os.path.join(ROOT, base) + if not os.path.isdir(top): + continue + for dp, dns, fs in os.walk(top): + dns[:] = [d for d in dns if d not in BRAND_PRUNE_DIRS] # 原地裁剪不进依赖/构建目录 + for fn in fs: + if fn.endswith(exts): # str.endswith 接受后缀元组 + out.append(os.path.join(dp, fn)) + return out + + def read(fp): try: with open(fp, encoding="utf-8", errors="ignore") as f: @@ -92,13 +118,19 @@ def check(name, problems): # ---------- G1 品牌不变量 ---------- def g1(): problems = [] + # ① 活层策展 md(AGENTS.md / docs / .agents):日期留痕档豁免。 for fp in walk_md(["AGENTS.md", "docs", ".agents"]): if DATED.match(os.path.basename(fp)): continue for i, line in enumerate(read(fp).splitlines(), 1): if BRAND_RETIRED in line and "brand-ok" not in line: problems.append(f"{rel(fp)}:{i} {line.strip()[:60]}") - check("G1 品牌不变量(活层无退役品牌根)", problems) + # ② 业务代码目录源文件(W-REAL R4 补扫描面):模块根 package.json / index.html 与 wg1/ 等代码防品牌回流。 + for fp in walk_code(BRAND_CODE_BASES, BRAND_CODE_EXTS): + for i, line in enumerate(read(fp).splitlines(), 1): + if BRAND_RETIRED in line and "brand-ok" not in line: + problems.append(f"{rel(fp)}:{i} {line.strip()[:60]}") + check("G1 品牌不变量(活层 md + 业务代码无退役品牌根)", problems) # ---------- G2 canonical 唯一性 + 注册表对账 ---------- diff --git a/.agents/tools/docs-gate.sh b/.agents/tools/docs-gate.sh index f2b36165..8b8d8a5f 100755 --- a/.agents/tools/docs-gate.sh +++ b/.agents/tools/docs-gate.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -# 文档治理门薄壳:调用 docs-gate.py(六检)。用法:bash .agents/tools/docs-gate.sh +# 文档治理门薄壳:调用 docs-gate.py(七检 G1-G7)。用法:bash .agents/tools/docs-gate.sh # 退出码 0=全绿;非零=失败检数。pre-commit 与 wave-close 第 8 步必跑。 set -uo pipefail exec python3 "$(cd "$(dirname "$0")" && pwd)/docs-gate.py" "$(cd "$(dirname "$0")/../.." && pwd)" diff --git a/contracts/ad-slot.schema.json b/contracts/ad-slot.schema.json index 12fe7b4f..af63149e 100644 --- a/contracts/ad-slot.schema.json +++ b/contracts/ad-slot.schema.json @@ -18,9 +18,9 @@ "enum": ["rewarded", "interstitial", "banner"] }, "provider": { - "description": "广告联盟:csj=穿山甲 / gdt=优量汇 / mock=桩(MVP 默认)", + "description": "广告联盟:csj=穿山甲 / gdt=优量汇 / mock=桩(MVP 默认)/ callback=sandbox 自回调桩(M4 服务端回调验签演进,签名校验走桩直通;见 api-schemas/ad.yaml /app-api/ad/reward/callback 与 ad 模块 CallbackAdProvider)", "type": "string", - "enum": ["csj", "gdt", "mock"] + "enum": ["csj", "gdt", "mock", "callback"] }, "placement": { "description": "触发场景:game_end=本局结束 / pause=暂停 / feed=游戏流间隙", diff --git a/docs/mvp/MVP进度总账.md b/docs/mvp/MVP进度总账.md index 7b983fae..715b5297 100644 --- a/docs/mvp/MVP进度总账.md +++ b/docs/mvp/MVP进度总账.md @@ -120,24 +120,45 @@ canonical: true 四模块(game-runtime / game-studio / tier2 / wg1)并行评审得 25 条真发现、0 个 P0;下列 9 条 P1(品牌两条合并呈现)+ 7 条 P2 未闭。真正带真金白银风险的是 wg1、tier2 两条生成线的成本与幂等闸尚未焊死,应在 W-G1 切默认产线、tier2 批量开闸之前处理。 +> **W-REAL R4 清欠对账(2026-07-02,逐条读当前代码坐实、不凭文档推断)**:16 条 = 7 moot、6 已修、1 存活待修、2 本次修(品牌门扫描面);另协调者追加第 17 条(ad-slot 契约漂移)本次修。下方原始发现明细勾选态已按本表更新(存活项保留未勾)。 +> +> | 条目 | 判定 | 依据(读码坐实) | +> |---|---|---| +> | P1① wg1 `/generate` 幂等 | moot | wg1 是退役 spike(无生产 Java 接线,仅 game-cloud 测试/注释引用);生产便宜档 = cheap-worker,幂等走后端 WorkerDispatchClient + idempotencyKey | +> | P1② wg1 max_tokens 未透传 | moot | 同上退役;cheap-worker 已透传(`_bootstrap.build_cheap_model` / `cheap_service_driver` 的 `parameters.max_tokens`) | +> | P1③ tier2 ¥ 硬闸跨 resume 不累计 | 已修 | 架构改单 POST 内联续修,`CircuitBreakerMiddleware` 会话级实例 `on_model_call` 累加 `spent_rmb` 调用前 fail-closed;`soft_budget` 演进(配置控制面阶段一①);`test_budget_soft_stop` 覆盖 | +> | P1④ wg1 契约真空 | 已修 | `contracts/agent-loop/{verdict,tier2-source-project,tier2-verdict}.schema.json` + `trace/tier2-trace-event.schema.json` 已建;v1 clicker 世代已换 | +> | P1⑤ tier2 服务态主链未真跑 | 已修(核心) | 扁平探测零产出孤儿已由 `tool_groups[*].tools` 抽取修复(app.py:120「2026-06-24 实证修复」)+ B1 真驱暴露;端到端批量清单在 `tier2/.agent`(仍待 mini-desktop,属正常 spike→prod) | +> | P1⑥ game-studio CSP 注释失真 | 已修 | `inject.ts` CSP 已移除 `unsafe-eval`(注释据实述「不含 eval/new Function 故不需」),无 `scanLogic`/`gamedef` 失实表述 | +> | P1⑦ game-studio vue-i18n 卡类型门 | 已修 | `package-lock.json` 已含 `vue-i18n@10.0.8`;`vue-tsc@3.3.4`(合 ^3.2.8)/ `typescript@6.0.3`(合 ~6.0.2)对齐,评审「实装 6.0.3」错配已消(本机未 install 不影响权威机 `npm ci`) | +> | P1⑧ 品牌残留 + 机器门扫描面(合并 GR-01+WG1-04 两条 P1) | **本次修** | 三处品牌早修(b31cc37a);G1 仅扫 .md 有洞 → 本次扩 `walk_code` 覆盖业务代码目录(负向测试证拦回流)+ 清漏网 `game-admin` 一处退役品牌菜单标题 → `绘境运营` | +> | P2① game-runtime v1→v2 标注漂移 | moot | `build-from-source.mjs` / `gd-runtime.js` 已删(gamedef v1 世界全删),src/host 只剩 3 层架构 `boot-game-host` / `generic-host-config` | +> | P2② tier2 `validate_play_scene` 子串校验 | 已修 | 切片二 U4 加 `_strip_js_comments_strings`,剥注释+字符串后判(评审短期诉求);AST 结构判定记为中期 followup | +> | P2③ tier2 screenshot docstring 冲突 | moot | tier2 代码已无 canvas 像素回读(`getImageData`/`readback`/`toDataURL` 全空),screenshot 只读落盘 PNG;docstring「零截图参与」现属实 | +> | P2④ tier2 bootstrap 鉴权头口子 | **存活待修** | `_post` 的 `X-User-Id` 口子 + 无重试退避仍在(bootstrap.py:99);卡点 = 需真实 `deps.py` 鉴权契约(部署 smoke 接缝),非本机最小改动可完成,列部署窗口 followup | +> | P2⑤ wg1 callback 孤儿 | moot | wg1 退役;`cheap-worker/worker_service.py` 用 job 携带的 per-job callback URL(HMAC 回调) | +> | P2⑥ wg1 `_judge_vision` 绕过重试 | moot | wg1 退役 spike,不在生产路径 | +> | P2⑦ wg1 基建 subprocess 无 check | moot | wg1 退役 spike,不在生产路径 | +> | R4-17 ad-slot provider 枚举漂移(协调者追加) | **本次修(跨端契约)** | `ad-slot.schema.json` enum 缺 `callback`,而 `ad.yaml` 与 `CallbackAdProvider`(真实现 `PROVIDER="callback"`)已支持;additive 加 `callback` + 对齐描述;DB VARCHAR 注释 / DO Javadoc 仍列 csj/gdt/mock(doc-only、SQL 为 Flyway 版本档不改)——留终审 | + **P1(9 条)** -- [ ] **wg1 `/generate` 无幂等去重**(`wg1/gen-worker/worker/service.py:378`):仅 `threading.Lock` 串行化,同一 traceId 重投会重复真烧便宜模型 + 重复 HMAC 回调,后端可能重复建版本/组包。切默认产线前必修(内存 set 起步,崩溃恢复用 results/ jsonl)。 -- [ ] **wg1 `run_studio` 的 `max_tokens` 未透传**(`wg1/gen-worker/worker/agent_loop/studio.py:231`):形参声明了却没接到底层调用,复杂局便宜模型输出被默认上限截断→取不到完整代码块→parse 失败重试,把 token 白烧在无谓重试上,直接拖累「成功率冲 80%」。 -- [ ] **tier2 ¥ 成本硬闸跨 resume 不累计**(`tier2/gen-worker/service/app.py:192`):熔断中间件每个 chat 回合重建、计数从 0 起,`rmb_hard_limit=3.0` 在默认 6 回合 resume 下形同虚设,单款实际可烧约 7 倍单回合上限而硬闸永不触发。批量开闸前必修(把 spent_rmb 提到 session 维度跨回合累计)。 -- [ ] **wg1 契约真空**(`wg1/gen-worker/worker/service.py:91`):worker 产的 engineBundle / 九门 verdict / 9 维 trace 无任何 `contracts/` schema 背书,评审锚点的 verdict/game-design schema 还停在 v1 clicker 世代,字段世代不符;worker↔后端 trace 子集口径只散在注释里,键名漂移无门可拦。补新 schema,或在设计文档显式声明 engine 路不消费 v1 契约并指向新 schema。 -- [ ] **tier2 服务态主链未端到端真跑**(`tier2/gen-worker/service/app.py:105`):BackendStore 落库 / MCP / L2·L3 / 富游戏三门只有 schema 形状、缺真跑证据,代码里留着「扁平探测全空→服务态生成零产出」的实证注释,属孤儿风险。0 号 spike 真驱后把端到端验证列成显式验收清单挂进 `tier2/.agent`,每兑现一项去掉「待 spike」表述并附证据路径。 -- [ ] **game-studio host CSP 注释失真**(`game-studio/src/host/inject.ts:69`):iframe CSP 授了 `unsafe-eval`,注释援引本模块根本不存在的 `gamedef` / `scanLogic` 运行时当作既成安全保障(违反「不得把未验证声明当事实」),且多授了当前代码不需要的 eval 能力。删掉不存在的 `scanLogic` 表述据实改述真实边界;若引擎 bundle 不需 eval 则从 CSP 移除 `unsafe-eval`。 -- [ ] **game-studio `vue-i18n` 缺失卡类型门**(`game-studio/package.json`):声明 `^10.0.0` 却没装,26 条 TS2307 卡死 `vue-tsc` 与 CI;且 `vue-tsc` 声明 `^3.2.8` 与实装 `6.0.3`、`typescript ~6.0.2` 不在同一兼容线,`npm ci` 不可预期。在权威构建机装包 + 对齐版本声明 + 提交 lockfile,合入前清掉。 -- [ ] **品牌红线残留 + 机器门扫描面有洞**(合并 GR-01 + WG1-04 两条 P1 + §四 index.html 补正):活层三处退役旧名「造梦AI」——`game-runtime/package.json:6`、`game-studio/index.html:7`(玩家浏览器标签页可见,最显眼)、`wg1/gen-worker/worker/service.py:34`;更要紧的是品牌不变量门只扫 `src/` 会放过模块根 `package.json` / `index.html` 与 `wg1/` 目录。改三处字符串之外,须把门的扫描面扩到各模块根与 wg1/ 防回流。 +- [x] **wg1 `/generate` 无幂等去重**(`wg1/gen-worker/worker/service.py:378`):仅 `threading.Lock` 串行化,同一 traceId 重投会重复真烧便宜模型 + 重复 HMAC 回调,后端可能重复建版本/组包。切默认产线前必修(内存 set 起步,崩溃恢复用 results/ jsonl)。 +- [x] **wg1 `run_studio` 的 `max_tokens` 未透传**(`wg1/gen-worker/worker/agent_loop/studio.py:231`):形参声明了却没接到底层调用,复杂局便宜模型输出被默认上限截断→取不到完整代码块→parse 失败重试,把 token 白烧在无谓重试上,直接拖累「成功率冲 80%」。 +- [x] **tier2 ¥ 成本硬闸跨 resume 不累计**(`tier2/gen-worker/service/app.py:192`):熔断中间件每个 chat 回合重建、计数从 0 起,`rmb_hard_limit=3.0` 在默认 6 回合 resume 下形同虚设,单款实际可烧约 7 倍单回合上限而硬闸永不触发。批量开闸前必修(把 spent_rmb 提到 session 维度跨回合累计)。 +- [x] **wg1 契约真空**(`wg1/gen-worker/worker/service.py:91`):worker 产的 engineBundle / 九门 verdict / 9 维 trace 无任何 `contracts/` schema 背书,评审锚点的 verdict/game-design schema 还停在 v1 clicker 世代,字段世代不符;worker↔后端 trace 子集口径只散在注释里,键名漂移无门可拦。补新 schema,或在设计文档显式声明 engine 路不消费 v1 契约并指向新 schema。 +- [x] **tier2 服务态主链未端到端真跑**(`tier2/gen-worker/service/app.py:105`):BackendStore 落库 / MCP / L2·L3 / 富游戏三门只有 schema 形状、缺真跑证据,代码里留着「扁平探测全空→服务态生成零产出」的实证注释,属孤儿风险。0 号 spike 真驱后把端到端验证列成显式验收清单挂进 `tier2/.agent`,每兑现一项去掉「待 spike」表述并附证据路径。 +- [x] **game-studio host CSP 注释失真**(`game-studio/src/host/inject.ts:69`):iframe CSP 授了 `unsafe-eval`,注释援引本模块根本不存在的 `gamedef` / `scanLogic` 运行时当作既成安全保障(违反「不得把未验证声明当事实」),且多授了当前代码不需要的 eval 能力。删掉不存在的 `scanLogic` 表述据实改述真实边界;若引擎 bundle 不需 eval 则从 CSP 移除 `unsafe-eval`。 +- [x] **game-studio `vue-i18n` 缺失卡类型门**(`game-studio/package.json`):声明 `^10.0.0` 却没装,26 条 TS2307 卡死 `vue-tsc` 与 CI;且 `vue-tsc` 声明 `^3.2.8` 与实装 `6.0.3`、`typescript ~6.0.2` 不在同一兼容线,`npm ci` 不可预期。在权威构建机装包 + 对齐版本声明 + 提交 lockfile,合入前清掉。 +- [x] **品牌红线残留 + 机器门扫描面有洞**(合并 GR-01 + WG1-04 两条 P1 + §四 index.html 补正):活层三处退役旧名「造梦AI」——`game-runtime/package.json:6`、`game-studio/index.html:7`(玩家浏览器标签页可见,最显眼)、`wg1/gen-worker/worker/service.py:34`;更要紧的是品牌不变量门只扫 `src/` 会放过模块根 `package.json` / `index.html` 与 `wg1/` 目录。改三处字符串之外,须把门的扫描面扩到各模块根与 wg1/ 防回流。 **P2(7 条)** -- [ ] **game-runtime v1→v2 契约标注漂移**(`game-runtime/src/host/build-from-source.mjs` 及 `gd-runtime.js` 文件头,评审 GR-02):source-project 契约已升级为 `oneOf(v1|v2)`、v1 标注冻结只读、v2 多文件 `src/` 定为终态,但活实现仍整建在 v1 上且无标注指向该判别式,维护者易把冻结的 v1 当终态继续加码。文件头各补一行演进状态注释、链到 schema 判别式(只加注释不改逻辑)。 -- [ ] **tier2 `validate_play_scene` 文本子串校验平台命脉接线**(`tier2/gen-worker/worker/run.py:401`):裸子串/正则启发式决定是否拦 build 并回喂自纠指引,agent 把 `bindInput`/`tick` 写进注释即假绿、用别名/换行即假红误导自纠。中期改 AST 结构判定,短期至少剥注释/字符串后再扫。 -- [ ] **tier2 screenshot docstring 与像素回读数据流冲突**(`tier2/gen-worker/worker/toolkit.py:262`):docstring 写「L1/L2 判定零截图参与」,实际 harness 在回读 canvas 像素产 advisory 观测(严格不进 decision)。纪律没破、纯措辞误导契约消费方,据实校准(零成本)。 +- [x] **game-runtime v1→v2 契约标注漂移**(`game-runtime/src/host/build-from-source.mjs` 及 `gd-runtime.js` 文件头,评审 GR-02):source-project 契约已升级为 `oneOf(v1|v2)`、v1 标注冻结只读、v2 多文件 `src/` 定为终态,但活实现仍整建在 v1 上且无标注指向该判别式,维护者易把冻结的 v1 当终态继续加码。文件头各补一行演进状态注释、链到 schema 判别式(只加注释不改逻辑)。 +- [x] **tier2 `validate_play_scene` 文本子串校验平台命脉接线**(`tier2/gen-worker/worker/run.py:401`):裸子串/正则启发式决定是否拦 build 并回喂自纠指引,agent 把 `bindInput`/`tick` 写进注释即假绿、用别名/换行即假红误导自纠。中期改 AST 结构判定,短期至少剥注释/字符串后再扫。 +- [x] **tier2 screenshot docstring 与像素回读数据流冲突**(`tier2/gen-worker/worker/toolkit.py:262`):docstring 写「L1/L2 判定零截图参与」,实际 harness 在回读 canvas 像素产 advisory 观测(严格不进 decision)。纪律没破、纯措辞误导契约消费方,据实校准(零成本)。 - [ ] **tier2 bootstrap 鉴权头占位口子**(`tier2/gen-worker/service/bootstrap.py:99`):REST 客户端 `X-User-Id` 留口子待对齐,四步串行启动无重试/幂等,new-api 偶发 502 会让启动失败或重复注册凭据。smoke 时按真实 `deps.py` 定死鉴权头 + 加幂等与有限重试退避。 -- [ ] **wg1 回调 `callback` 孤儿字段**(`wg1/gen-worker/worker/service.py:8`):文件头文档声明 job 携带 `callback`,但全程只用进程级 `state.callback_url`,`job.get("callback")` 从不读取;执行器若按文档传 per-job 回调会被无声丢弃。删文档声明,或真接线 + 地址白名单防 SSRF。 -- [ ] **wg1 `_judge_vision` 绕过重试封装**(`wg1/gen-worker/worker/agent_loop/studio.py:190`):视觉位直接调 `client.chat.completions.create`,绕过 `_client.chat` 的 tries=3 突发重试(仍有 SDK 级 max_retries=2),遇网关瞬时 502 更易被吞成 panel error、顾问位无声失效。给 `_client` 加多模态 chat 变体复用重试。 -- [ ] **wg1 基建类 subprocess 无 check**(`wg1/gen-worker/worker/validate.py:86`、`run.py:48/62`):build/play 子进程因环境问题(node 缺失、脚本路径错)非零退出被当普通失败回喂模型重试,掩盖基建故障、白烧重试 token 才暴露。对基建类区分 returncode(如 127)快速失败标 infra_fail、不进回喂循环。 +- [x] **wg1 回调 `callback` 孤儿字段**(`wg1/gen-worker/worker/service.py:8`):文件头文档声明 job 携带 `callback`,但全程只用进程级 `state.callback_url`,`job.get("callback")` 从不读取;执行器若按文档传 per-job 回调会被无声丢弃。删文档声明,或真接线 + 地址白名单防 SSRF。 +- [x] **wg1 `_judge_vision` 绕过重试封装**(`wg1/gen-worker/worker/agent_loop/studio.py:190`):视觉位直接调 `client.chat.completions.create`,绕过 `_client.chat` 的 tries=3 突发重试(仍有 SDK 级 max_retries=2),遇网关瞬时 502 更易被吞成 panel error、顾问位无声失效。给 `_client` 加多模态 chat 变体复用重试。 +- [x] **wg1 基建类 subprocess 无 check**(`wg1/gen-worker/worker/validate.py:86`、`run.py:48/62`):build/play 子进程因环境问题(node 缺失、脚本路径错)非零退出被当普通失败回喂模型重试,掩盖基建故障、白烧重试 token 才暴露。对基建类区分 returncode(如 127)快速失败标 infra_fail、不进回喂循环。 ### 联调(把"模块编译通过"转成"可演示闭环"= Doc A P0 可验证的硬通货) - [x] **`deploy/smoke-test.sh` 五链路冒烟门(2026-06-11)** — API 级就绪门:只读 12/12 + `--deep` 13/13 全过(health/鉴权 + 链路①四模板就绪+draft + 链路②feed非空+zones+project/my + 链路③runtime/package取包 + 链路④ad/钱包/收益 + 链路⑤feed携qualityScore回灌 + deep:generate入队)。**5 条链路后端 API 全绿**,CORS/鉴权(test1 token)从前端 origin 验证通过。**实测 gotcha**:feed item 的 `packageUrl` 恒 null,真实取包走 `GET /app-api/runtime/package/{versionId}`(已写入脚本注释)。 diff --git a/game-admin/src/router/modules/remaining.ts b/game-admin/src/router/modules/remaining.ts index a98b6114..a00c12a5 100644 --- a/game-admin/src/router/modules/remaining.ts +++ b/game-admin/src/router/modules/remaining.ts @@ -248,7 +248,7 @@ const remainingRouter: AppRouteRecordRaw[] = [ name: 'Wanxiang', redirect: '/wanxiang/review', meta: { - title: '造梦运营', + title: '绘境运营', icon: 'ep:management', alwaysShow: true },