live :48080 端口精确从 6-21 旧 gamedef jar 换成 6-28 M3 jar(dev/2.0.0)+ dispatcher=http→worker:9501 + trace.enabled;boot 日志「生成派发通道选定 dispatcher=http=WorkerDispatchClient」坐实 Node/gamedef 旧路在 live 退役。拆 iso :48090 避 live+iso 双 executor 同 DB split-brain。最终拓扑=live :48080(M3 路)+ worker :9501,同 DB。control-plane 6门放量创始人定后单独开。 M3 剩(非 cutover 工程缺口):≥80% 生产真实分布达标复验(质量轨 WU-B/C/F)+ 对外开闸放量(放行决策)+ publish→feed→玩家真玩(产品轨移交边界)。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
35 KiB
date, topic, status, 关联, 图清单
| date | topic | status | 关联 | 图清单 | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2026-06-28 | cheap-worker-M3b-create-feed-e2e-and-6gates | 已实现 + ✅ 生产 cutover 完成(Node/gamedef 退役 go-live、live :48080 跑 Python M3 路 dispatcher=http);M3 剩 ≥80% 生产达标(质量轨 WU-B/C/F)+ 对外开闸放量(放行决策) |
|
|
便宜档 M3b · create→feed 端到端 + 对外开闸 6 门(切片一第三里程碑第二片)
Summary
M3a 已把便宜档默认生成路由从 Node/SAA 旧路整体切到 Python cheap-worker(dispatcher=http→worker:9501),并在隔离的 iso :48090 上验过两条回调路、live :48080 全程未动。M3b 承接 plan① 切片一 M3 的剩余部分:把"创作页一句话 → 生成 → 九门 → 发布门 → feed → 种子用户真玩"这条生成线在 cheap-worker 新路上端到端跑通,并把对外开闸 6 门在新路逐门复验。
M3b 的真实形状和直觉不同:6 门不是要从零建,而是建在旧路、需要在 cheap-worker 新路复验与补齐。 6 门里,D12 控制平面与 GP9 合规先行都焊在生成任务的提交入口、与 worker 实现无关,首局体验门焊在引擎无关的九门 harness 里——这三门 cheap-worker 新路天然继承,无需重兑现。真正在新路有缺口的只有三件,而且它们是连环的:worker 侧产出的 9d trace 七项当前没产(result_out.py 只产了成本一项),后端 D11 就绪评分因此读不到可玩性/首局/稳定性信号、退化成一个近恒定分(实测落 45 或 55 双峰、不随质量浮动),D9 反同质则因为 cheap-worker 没有查重逻辑而完全失效。
M3b 的生成线工作因此是:把 cheap-worker 的回调产出补齐到旧路 worker 的 9d-trace 同等口径,救活 D11,再把整条 create→feed→真玩 在 iso 上真验一遍。 create→feed→真玩 的代码链本身已经通了(engineBundle 从 worker 一路落到玩家页的真引擎启动),唯一的人工闸口是发布前的审核门。M3b 不动 live,在 M3a 已就绪的 iso 上把端到端跑通并复验 6 门;生产 cutover 与几项待拍数值是显式延后的创始人决策,不在本里程碑。
Problem Frame
M3a 完成后,便宜档生成跑在 cheap-worker 上,但它的回调产出和旧路不对等,这个不对等沿着回调链逐级放大成三门失效。
第一级在 worker 出口。cheap-worker 的 result_out.build_result_out 组回调入参时,trace 段只塞了一个 trace.cost.totalRmb(result_out.py:148-150)。而旧路两个 worker——原始 HTTP worker 的 _extract_trace(wg1/gen-worker/worker/service.py:91-218)和 SAA 路的 extractTraceQuietly(SaaGraphDispatcher.java:704-720)——都产出一个 9d trace 子集,其中有一个"必填七项"{pass, repairs, wallS, models, attempts, gameId, stage} 作为轨迹完整率的分母,外加 gatespec、sevenGateVerdict、cost、similarity 等可选项。cheap-worker 当前七项里只对得上 pass(从 verdict)、wallS(summary 的 wallSec)、gameId 三项,其余四项缺失或形态不同(attempts 是整数计数而非逐 attempt 的逐门 guards 列表,verdict 被 _verdict_brief 削成了 {pass, failedGates}、丢了逐门 guards,完全没有 repairs/models/stage)。
第二级在后端就绪评分。ReadinessScorer.score(ReadinessScorer.java:52-165)按四维加权算 0–100 分:可玩性 0.50 读 trace.pass、首局 0.25 读 trace.gatespec.driver 且 trace.sevenGateVerdict.guards.H_progress.pass(嵌套对象取 .pass)、稳定性 0.15 读 trace.repairs、效率 0.10 读 trace.cost.totalRmb;任一维字段缺失取中性值 0.5。于是当 trace 只有 cost 一项时,前三维全部落到中性 0.5,算出来恒为 100×(0.45 + 0.10×效率)。而便宜档真实成本是 ¥0.4–1.2(实测 27 份 run-summary 全 ≥0.30,= 2×效率维预算阈值 BUDGET_RMB=0.15),效率维因此恒为 0、对便宜档零区分力——退化分落在 45(active 定价)或 55(定价降级 spent_rmb=0、cost=0≤0.15→效率满分)双峰,不随质量浮动。这个看起来在工作的分,其实丢掉了可玩性、首局、稳定性的全部信号——一款九门全过的好游戏和一款勉强启动的游戏会拿到几乎一样的就绪分,审核台据此排序等于没排(BUDGET_RMB=0.15 与便宜档成本量级错配、效率维零区分,需校准,见 §待拍数值)。
第三级在反同质。后端完全没有查重逻辑,签名与查重按设计就全在 worker 侧(验收门.md:209);cheap-worker 没有 dedup.py、result_out 不产 similarity,所以新路上 D9 直接失效。D9 当初只落在了原始 HTTP worker 上,SAA 路本就没接(SaaGraphDispatcherTraceTest.java:183 注明"similarity 永远省略,D9 未接 SAA")——也就是说,即便在 M3a 之前,默认跑的 SAA 路也没有 D9。这把"D9 要不要补"变成一个真实的范围取舍,而不是一个单纯的回归修复(见 §决策点)。
还有一个会让验证假绿的开关:aigc.trace.enabled 默认 false(DifyCallbackTxService.java:101),关着时整段 trace 落库旁路、trace_json/readiness_score 恒为 NULL。M3b 在 iso 上验 trace 落库前必须先把它打开,否则会误以为"trace 没落是 worker 没产",其实是开关没开。
create→feed→真玩 这条链本身在代码层已经接通:回调七步事务产出 game_version + game_runtime_package(status=0 预览就绪)+ 任务置 SUCCEEDED,但不写 feed;一条游戏进 feed 需要有人调 reviewProject(APPROVE),经 PublishOrchestrationServiceImpl.publish(L57-100)把包翻成 status=1、版本翻 3、项目翻 PUBLISHED、feedApi.upsertRank 入流;之后玩家端 getFeedStream 拉流、inject.ts 的 boot()(L240-271)按 pkg.engineBundle 分流到 __GameBundle.bootGameHost 真引擎掌帧。engineBundle 这条主动脉全程贯通,所以代码层"→feed→真玩"已通,唯一断点是发布前那道人工审核门。
图1 · create→feed→play 现状链与 M3b 缺口
flowchart TD
subgraph SUBMIT["提交入口(Node/Python 共享 · 新路天然继承)"]
D12["D12 控制平面<br/>降级/配额并发/背压"]
GP9["GP9 合规先行<br/>prompt 审查 fail-closed"]
end
subgraph WORKER["cheap-worker 新路(M3a 已切 · M3b 补齐)"]
GEN["cheap_studio.run_studio<br/>ReAct 生成 + 九门 play"]
HARNESS["九门 harness + 首局体验门<br/>(引擎无关 · 新路天然继承)"]
RO["result_out.build_result_out<br/>⚠️ trace 只产 cost 一项"]
end
subgraph BACKEND["后端回调七步 + 落库"]
CB["DifyCallbackTxService<br/>校验→建版本→组包→落包→置 SUCCEEDED"]
TRACE["persistTraceQuietly<br/>⚠️ aigc.trace.enabled 默认 false"]
D11["D11 ReadinessScorer<br/>⚠️ 缺七项→退化 45/55 双峰"]
D9X["D9 反同质<br/>⚠️ 后端零逻辑 + worker 无 dedup → 失效"]
end
subgraph PUBLISH["发布入 feed → 真玩"]
REVIEW["reviewProject(APPROVE)<br/>🔶 唯一人工断点"]
PUB["publish: 包 0→1 / 版本 3 / 项目 PUBLISHED / upsertRank"]
FEED["getFeedStream 拉流"]
PLAY["inject.ts boot → __GameBundle.bootGameHost 真引擎"]
end
D12 --> GP9 --> GEN --> HARNESS --> RO --> CB --> TRACE --> D11
CB -.-> D9X
CB --> REVIEW --> PUB --> FEED --> PLAY
style RO fill:#f5b7b1
style D11 fill:#f5b7b1
style D9X fill:#f5b7b1
style TRACE fill:#f9e79f
style REVIEW fill:#f9e79f
style PLAY fill:#a9dfbf
Requirements
- R1 · 9d trace 七项在 cheap-worker 新路产出。 cheap-worker 回调入参的
trace段补齐必填七项{pass, repairs, wallS, models, attempts, gameId, stage}加 D11 首局维所需的gatespec.driver与sevenGateVerdict.guards.H_progress(嵌套.pass),键名一律 camelCase、镜像旧路_extract_trace/extractTraceQuietly口径。验收 = iso 上trace_json落齐七项、轨迹完整率 7/7。 - R2 · D11 就绪评分在新路从真实信号算分。 随 R1 自动兑现(后端算分器是共享码)。验收 = 修后 trace 喂 ReadinessScorer 时 playability/firstPlay/stability 三维各自脱离中性 0.5(playability→1.0 或 0、firstPlay→1.0、stability→1.0/0.7/0.4),且九门全过与勉强启动两款算出显著拉开的就绪分。不以「合成分脱离某区间」为判据——便宜档真实成本下效率维恒 0、未修态合成分本就在 45(区间外),看区间会假绿。
- R3 · D9 反同质的新路处置(决策点)。 见 §决策点:补到 cheap-worker(全 parity)或显式暂缓(对齐 SAA 先例 + observe-only 性质)。
- R4 · create→发布→feed→真玩 端到端在 iso 真验。 从一句话 brief 提交,经生成→回调七步→
reviewProject(APPROVE)→publish→getFeedStream→manifest→inject.tsboot,到__GameBundle.bootGameHost在真浏览器里真起来可玩。验收 = 真浏览器里点开 feed 里这款游戏能真玩(非兜底壳)。 - R5 · 6 门在 cheap-worker 新路逐门复验。 D12/GP9/首局体验验"继承不破",9d trace/D11 验"新路兑现",D9 按 R3。验收 = 逐门给出新路通过证据。
- R6 · 非阻断硬约束不破。 trace/dedup 落库或算分失败一律 try-catch 吞 + log,主回调链照常走到发布(沿用后端 best-effort 范式 + 验收门.md 组B 铁律);cheap-worker 侧富化 trace 同样不得让 trace 组装失败拖垮回调。
- R7 · 不动 live。 全部验证在 M3a 的 iso :48090 + worker :9501 上做;live :48080 与生产 cutover 不在 M3b。
Key Technical Decisions
- KTD1 · 9d trace 在 cheap_studio 侧捕获、result_out 侧组装,且是纯 additive。 cheap_studio.run_studio 在收口段其实已经算出了 full verdict(含逐门 guards,cheap_studio.py:157)和 gatespec(ensure_play_spec 产的 driverType,:154),只是没存进 summary——summary 只留了
_verdict_brief的{pass, failedGates}(:175)。所以富化是把这些已算出的维度 additively 存进 summary(再加repairs/models/stage三个轻量字段),不改任何生成逻辑、不影响现有产物。result_out 再据富化后的 summary 组payload["trace"],镜像_extract_trace的 camelCase 语义。 - KTD2 · 复用旧路经验证的 trace/dedup 口径,而非另写一套语义。 import 边界要看清:
_bootstrap把 tier2/gen-worker 加进 sys.path(cheap_studio 据此 importworker.config/worker.middleware),而 9d-trace 的_extract_trace与 D9 的dedup.py在 wg1/gen-worker、不在 cheap-worker 的 import 路径上(tier2/gen-worker 里没有这两者)。故两者都按「复用口径、非跨树 import」处理:trace 组装在 result_out 内手写、镜像_extract_trace的输出口径(七项 camelCase + sevenGateVerdict 只取{pass, guards}去噪;cheap summary 的输入形态与 wg1result不同,不能直接套 _extract_trace);D9 则把 wg1 的dedup.py(纯模块、无外部依赖、约 130 行)vendored 复制进 cheap-worker,DEDUP_REGISTRY直接设为 cheap-worker 自己的results/_dedup_registry.jsonl——比跨树 import + monkey-patch 全局常量更干净、天然路径隔离。 - KTD3 · D11 不动后端码,只喂对输入。 退化的根因不在 ReadinessScorer(它的四维读取与中性兜底都是对的),而在喂给它的 trace 缺字段。所以 M3b 不碰算分器,只让 cheap-worker 产出它要读的字段。这把 D11 的修复收敛成 R1 的副产品、零后端改动。
- KTD4 · 端到端验证复用 M3a iso,新增的只是开 trace 开关 + 走通发布门。 iso :48090 已是
dispatcher=http→worker:9501,正是 M3b 要验的新路。M3b 在它上面把aigc.trace.enabled打开、把reviewProject(APPROVE)→feed→真玩 这段走通,不新搭环境。 - KTD5 · 发布入 feed 走现有人工审核门,M3b 只是 exercise 它。 SUCCEEDED→feed 的发布编排(publishOrchestrationService)是现成的;M3b 调
reviewProject(APPROVE)把种子游戏推进 feed 以验真玩,审核台 UI、α 自动发布策略归产品/后端线,不在 M3b 自建。
决策点 · D9 反同质的新路处置(待创始人拍)
这是 M3b 唯一的范围分叉,单独拎出来给创始人定,不替他默认。
事实:D9 是 observe-only 的非阻断门(撞重只告警、绝不拦截,九门才是挡坏游戏的硬地板);它当初只落在原始 HTTP worker 上,默认跑的 SAA 路本就没接;后端零逻辑、补 D9 全是 worker 侧的事;移植成本较低(把 wg1 的纯模块 dedup.py vendored 复制进 cheap-worker、registry 指自己的 results/,见 KTD2)。
- 选项 A(暂缓 · 对齐先例 + 最小): M3b 不补 D9,在残留里显式记一笔"D9 未接新路(与 SAA 先例一致)"。理由:D9 非阻断、SAA 路也没有,M3b 先把承重的 trace/D11 与端到端打通;D9 作为 observe-only 增强随后单独补。代价:6 门里 D9 这一门在新路仍是缺的,"6 门全验过"打个折扣。
- 选项 B(补齐 · 完成单一路 parity): M3b 把 D9 移植进 cheap-worker(U3),让 reframe 钦定的 cheap-worker 单一路在 6 门上比当年任何旧路都全。代价:多一个小单元的工作量 + 验证面。
倾向:两者都正当。考虑到 D9 移植成本确实低、且 reframe 已把 cheap-worker 定为唯一便宜档路(留一门缺口未来还要回填),A 偏最小、B 偏干净完整。
创始人裁定(2026-06-28):选 B 补齐 —— D9 移植进 cheap-worker,完成单一路 6 门 parity。U3 转为本里程碑必做单元(不再条件化);6 门在新路全验。
High-Level Technical Design
图2 · 6 门在 cheap-worker 新路的依赖性分级
flowchart LR
subgraph INHERIT["天然继承(新路无需重兑现)"]
G_D12["D12 控制平面<br/>提交入口共享"]
G_GP9["GP9 合规先行<br/>提交入口共享"]
G_FIRST["首局体验门<br/>引擎无关 harness 共享"]
end
subgraph REDO["worker 侧产出依赖(新路必须兑现)"]
G_TRACE["9d trace 七项<br/>= M3b U1+U2"]
G_D11["D11 就绪评分<br/>= 随 trace 自动救活"]
G_D9["D9 反同质<br/>= U3 决策点"]
end
G_TRACE --> G_D11
style INHERIT fill:#eafaf1
style REDO fill:#fef9e7
设计的主轴只有一条:把缺口收敛到 worker 出口的 trace 产出这一个点,其余全是它的下游或与它无关。 D11 退化是 trace 缺字段的下游,补 trace 即救活 D11、零后端改动;D9 是 trace 里另一个可选段(similarity),按决策点处理;D12/GP9/首局与 worker 实现正交,只需复验"切路没切坏"。create→feed→真玩 这条产品链不在生成线缺口里,M3b 对它做的是端到端真验、不是改造。
Implementation Units
U1 · cheap_studio 富化 9d trace 维度(cheap-worker 侧 · 本机可执行)
交付物: cheap_studio.run_studio 的 summary additively 携带 D11/trace 所需的全部维度。
改动点: cheap-worker/cheap_studio.py(summary 构造段 L164-184 附近)。
Approach: 把收口段已算出但没存的维度存进 summary——full verdict 的逐门 guards(:157 的 verdict,不只 brief)、gatespec 的 driver(:154 的 ps);再补三个轻量字段:repairs(自修复轮数 = max(0, attempts-1),首轮 0、对齐 wg1 len(attempts)-1 与 SAA SaaGraphDispatcher 注释口径;注:cheap_studio.py:114-118「门绿但未 finish→踹 finish」分支可能多记 1,attempts-1 是可接受近似、实现处注明此口径偏差)、models(便宜档单模型,组成 {code: SPIKE_MODEL} 形态的 map)、stage(本 run 走到的最远阶段,scaffold/code/stage/smoke/play 之一)。全部 additive,不改生成循环、不改现有 summary 既有字段。**对照路容错:**worker_service.py:120 真路默认 run_gates=True 故收口段产 verdict/gatespec;run_gates=False 的对照路不产,U1 捕获须对 None 容错(缺则 trace 相应键省略、不抛)。
TDD:
- RED:写测断言 run_studio 的 summary(或新增的 trace-source 字段)含
repairs(int)、models(map)、stage(str)、full guards(H_progress 为含pass的嵌套对象)、gatespec.driver;先跑、看它因字段缺失而失败。 - GREEN:在 summary 构造段补这些字段。
- 回归:cheap-worker 既有全套测试(U-A/M1 累计)零回归;一次真生成跑通、现有产物形态不变。
U2 · result_out 组 payload["trace"] 七项(cheap-worker 侧 · 本机可执行)
交付物: result_out.build_result_out 产出的 trace 段含必填七项 + D11 首局维所需 gatespec/sevenGateVerdict,camelCase 镜像 _extract_trace。
改动点: cheap-worker/result_out.py(build_result_out 的 trace 组装段 L145-153 附近)。
Approach: 从 U1 富化后的 summary 抽出七项组 payload["trace"]:pass/repairs/wallS(summary.wallSec)/models/attempts/gameId/stage;sevenGateVerdict 只取 {pass, guards}(去 url/ts 噪声,对齐 _extract_trace:148-154);gatespec 带 driver(键名须落 driver、值 = ensure_play_spec 的 driverType;落成 driverType 则 ReadinessScorer hasDriver=false、firstPlay 永中性);cost.totalRmb 维持现状。键名严格 camelCase 且逐字镜像 ReadinessScorer 读取的确切键——注:trace 是后端开放 Map(DifyCallbackReqVO.trace),Jackson 只校验 10 个顶层字段、不拒 trace 内层未知键,键名拼错(如 seven_gate_verdict)会被静默接收、ReadinessScorer 读不到 → 悄悄落中性(假绿);真护栏只有 U2 跨语言切片喂真 ReadinessScorer,别寄望「后端拒未知」。失败路同样抽 trace(repairs/attempts/stage 对排障有价值,对齐旧路成功/失败都抽)。
TDD:
- RED:扩 test_result_out.py,断言成功路 trace 含七项 +
sevenGateVerdict.guards.H_progress.pass+gatespec.driver;断言失败路 trace 仍含七项(排障);先跑、看缺字段失败。 - GREEN:实现 trace 组装。
- 跨语言切片:扩 game-cloud 的 CheapWorkerResultOutContractTest(M3a 建),用真 fixture 喂 ReadinessScorer.score,逐维断言 playability/firstPlay/stability 各自脱离中性 0.5(证明信号真进算分、非看合成分落点),且九门全过 fixture 与勉强启动 fixture 算出显著拉开的分数。不用「脱离 50–55」作判据——便宜档真实成本下效率维恒 0、未修态合成分即 45 本在区间外,看区间会假绿(M3a 教训:单测桩绕真消费)。
U3 · D9 反同质移植到 cheap-worker(cheap-worker 侧 · 本机可执行 · 创始人定 B、必做)
交付物: cheap-worker 回调产 trace.similarity,撞重只告警不拦截。
改动点: 新增 cheap-worker/dedup.py(vendored 自 wg1 纯模块)+ 回调路接线调 check_similarity + result_out trace 段带 similarity。
Approach: 把 wg1 worker/agent_loop/dedup.py(纯模块:norm_text/compute_sig/check_similarity,无外部依赖)vendored 复制进 cheap-worker/dedup.py,DEDUP_REGISTRY 设为 cheap-worker/results/_dedup_registry.jsonl(天然路径隔离,无需跨树 import 或 monkey-patch——tier2/gen-worker 在 path 上但无 dedup、wg1 不在 path 上,见 KTD2)。在回调组装前以 title=_derive_title(brief)、theme="generic"、trace_id 调 check_similarity,把返回的 {dupHit,titleNorm,sig,dupWith} 塞进 trace.similarity。容错降级(登记表读写失败 → dupHit=None、不阻断)沿用现成逻辑。
TDD: RED 断言 trace 含 similarity 且第二次同 brief 撞重 dupHit=true;GREEN vendor + 接线;断言撞重不阻断回调(status 仍按九门判)+ registry 落 cheap-worker/results/(路径隔离、不与 wg1 串台)。
(决策点已定 B:本单元必做;A 的暂缓分支不适用。)
U4 · iso 开 trace 落库 + D11 真验(mini-desktop · 真 e2e)
交付物: iso :48090 上 trace_json 落齐七项、readiness_score 逐维信号真进算分(三维非全中性)。
Approach: 在 iso 后端配置同时开两道 feature-flag:aigc.trace.enabled=true(trace 落库前置)与 aigc.control-plane.enabled=true(D12/GP9 前置,默认 false 时整段旁路、U5 的拒绝证据无从产生)+ 占位配额/背压阈值;重启 iso :48090(端口精确清理、不碰 live :48080)。经 worker:9501 真生成一款,查 DB game_aigc_task 该任务 trace_json 七项齐全、readiness_score 非 NULL 且逐维信号真进算分(playability/firstPlay/stability 非全中性)。绕代理直连(root@100.64.0.7,Python ProxyHandler({}))沿用 M3a 范式。
验证: DB 实证 trace_json 七项 + readiness 可区分;non-blocking 复验(故意喂坏 trace 看主链仍 SUCCEEDED)。
U5 · create→发布→feed→真玩 端到端 + 6 门逐门复验(mini-desktop · 真 e2e + 真浏览器)
交付物: 一款 cheap-worker 新路生成的游戏,经发布门进 feed,在真浏览器里真玩;6 门逐门给出新路证据。
Approach: 提交一句话 brief → 生成 → 回调七步 → reviewProject(APPROVE) → publish → getFeedStream 含该款 → manifest 取 engineBundle → 经 /gstack 在真浏览器打开玩家页,确认走 __GameBundle.bootGameHost 真引擎(非"模板体系重构中"兜底壳)、可真玩。6 门复验(D12/GP9 的实证前置 = U4 已开 aigc.control-plane.enabled,否则两门旁路、只能记「架构继承推断、非新路实证」、不计入「6 门全验过」):D12(配额/背压拒绝走业务码 HTTP200)、GP9(违规 brief 被 AIGC_UNSAFE_PROMPT 挡、0 入队)、9d trace(U4 证据)、D11(U4 逐维信号证据)、首局体验(harness verdict 含首局门)、D9(按 R3)。
验证: 真浏览器真玩截图/日志为准(非 stub 通道);6 门逐门 PASS 证据表。
U6 · 蒸馏 + 残留收口
交付物: 把 trace parity 范式蒸馏回 .agents/,更新 memory,plan close-out。
Approach: 更新 .agents/skills/gen-path-parity-harness.md(补 9d trace 七项 parity 段 + D11 退化判别法);更新 memory m3a→m3b 进度;plan 文末补"执行发现";残留显式列:生产 cutover(创始人)、待拍数值(配额/D11 权重/D9 阈值)、D9(若决策点 A)、审核台 UI(产品轨)。
迁移对账(承接 plan① 切片一 · M3b 兑现的移交项)
| plan① 切片一 M3 项 | M3b 归属 | 兑现单元 |
|---|---|---|
| create→feed 生成线端到端打通 | ✅ 本里程碑 | U4 + U5 |
| 对外开闸 6 门验过 | ✅ 本里程碑(新路复验) | U1/U2(9d trace+D11)、U3(D9 决策点)、U5(D12/GP9/首局复验) |
| 后端路由 flag / D12 接缝 | 已在 M3a 交付 | — |
| 生产真实分布达标门复验 ≥80% | 🔶 延后(需生产 cutover 后) | 创始人决策后 |
| Node 旧路退役(生产 cutover) | 🔶 延后创始人决策 | 不在 M3b |
| studio 创作会话/资产/进度流/重生成 | ❌ 后端线(移交边界) | 不在 M3b |
Scope Boundaries
做(in scope): cheap-worker 9d trace 七项产出(U1/U2)、随之救活 D11(零后端改动)、D9 决策点(U3)、iso 上 trace 落库 + D11 + 端到端 create→feed→真玩 真验、6 门新路逐门复验。
不做(out of scope): 生产 cutover(切 live :48080 dispatcher saa→http,= 真 Node 退役 go-live,创始人决策);待拍数值(会员档配额/并发、D11 权重校准、D11 效率维预算阈值 BUDGET_RMB、D9 模糊相似阈值);studio 模块的创作会话/资产模块化/进度流/重生成编排(后端线);审核台 aigc 列表页与就绪分展示 UI(产品轨);多 worker 横向扩容(远期)。
Risks & Dependencies
- R-A · trace 富化破坏现有生成(回归风险)。 缓解:U1 纯 additive、不改生成循环;cheap-worker 既有全套测试零回归 + 一次真生成形态不变作门。
- R-B · trace 七项口径与后端 ReadinessScorer 读取不对齐(假兑现)。 缓解:U2 跨语言切片测用真 fixture 喂真 ReadinessScorer,逐维断言三维脱离中性 + 两 fixture 分数拉开——不靠本机自证、不靠「合成分落点」(便宜档效率维恒 0,合成分判据会假绿)。这正是 M3a 三个真 bug 的教训(单测桩会绕过真消费)。
- R-C · aigc.trace.enabled 默认 false 致验证假绿(误判 worker 没产)。 缓解:U4 第一步显式开开关 + DB 实证。
- R-D · 真玩验证走了 stub 通道而非 real 引擎(假绿)。 缓解:U5 在真浏览器确认
boot-game-host.js走 real 通道(L467-496)、非 stub(L436-448)、非兜底壳。 - R-E · iso 操作误伤 live :48080。 缓解:端口精确清理、绝不全局 pkill huijing-server.jar(M3a 铁律);trace 开关只改 iso 配置。
- 依赖: mini-desktop 可达(ssh 绕代理)、M3a iso :48090 + worker :9501 仍在(验证态)、真浏览器经 /gstack。
Verification(里程碑收口)
- cheap-worker 本机:U1/U2/U3 测全绿 + 既有全套零回归 + 跨语言切片测逐维断言三维脱离中性 + 两 fixture 分数拉开。
- iso :48090 真 e2e:trace_json 七项齐 + readiness 逐维信号真进算分(两款分数拉开)+ non-blocking 复验 + create→发布→feed→真浏览器真玩 + 6 门逐门 PASS 证据(D12/GP9 已开 control-plane)。
- 收口判据 = create→feed→真玩 在 cheap-worker 新路端到端真通 + 6 门(D9 按决策点)在新路验过;不含生产 cutover。
Sources & Research
代码侦察(2026-06-28,HEAD a327c991):result_out.py:148-150、cheap_studio.py:154/157/164-184、wg1 service.py:91-218、dedup.py、ReadinessScorer.java:52-165、DifyCallbackTxService.java:101/252-282、PublishOrchestrationServiceImpl.java:57-100、inject.ts:240-271、FeedServiceImpl.java:237-239(读侧 PUBLISHED 过滤;515/525-532 是写侧 upsertPublishBaseline 可见态校验)。6 门 SoT:验收门.md(canonical)。plan① 切片一 M3:2026-06-25 统一执行计划。
待创始人决策(M3b)
- D9 范围(本计划决策点): 选项 A 暂缓(对齐 SAA 先例 + 最小)/ 选项 B 补齐(完成单一路 parity)。
- 生产 cutover(延后): 何时切 live :48080 dispatcher saa→http(= 真 Node 退役 go-live)。
- 待拍数值(延后): 会员档配额/并发、D11 权重校准、D11 效率维预算阈值
BUDGET_RMB(当前 0.15 与便宜档真实成本 ¥0.4–1.2 错配、效率维恒 0 零区分力)、D9 模糊相似阈值。
双评审发现与处置(2026-06-28 · Opus 权威 + Codex 部分轨迹佐证)
Opus 对抗评审判 needs-rework(窄域),3 MAJOR + 5 MINOR,均 code-grounded、精确小改、不动架构;承重断言(D11 退化机制、trace 开关、create→feed→play 链、parity 参考)逐条核验属实。Codex 路(codex-rescue)走后台不可取回、末段 reconnect 错误未产出最终分级评审,但其调查轨迹(读 studio.py:330-386 的 repairs 源、reviewProject→publish、D12/GP9 共享入队门)佐证 Opus 发现、无新增项;按 §6.8 Codex 不可用回落 Opus 单评为权威。全部发现已在本文修复。
| 级别 | 发现 | 处置 |
|---|---|---|
| MAJOR | M1 「脱离 50–55 死区」是假绿判据:便宜档真实成本 ¥0.4–1.2 ≥ 2×BUDGET_RMB(0.15)→ 效率维恒 0,退化分实为 45/55 双峰(主峰 45、低于 50),未修态也「脱离 50–55」→ 测试假证修好 |
删此判据,改逐维断言(playability/firstPlay/stability 各自脱离中性 0.5)+ 两 fixture 分数拉开;BUDGET_RMB 入待拍数值。改动:Summary / Problem Frame / R2 / U2 切片 / R-B / Verification / 图1 节点 |
| MAJOR | M2 repairs=attempts off-by-one:cheap_studio attempts=attempt+1、干净一次过=1,但 repairs 语义首轮 0(wg1 len(attempts)-1、SAA 注释证)→ 好游戏 stability=0.7 永不满分、破 parity |
改 repairs=max(0, attempts-1),注明踹-finish 分支口径偏差(KTD1 / U1) |
| MAJOR | M3 「6 门复验」漏开 aigc.control-plane.enabled(默认 false → D12/GP9 旁路)→ 两门复验真空通过 |
U4 同时开 control-plane flag + 占位阈值;U5 注明否则两门记「继承推断、非实证」不计入 6 门 |
| MINOR | m1 「后端拒未知字段」对 trace 内层不成立(开放 Map,Jackson 只校验 10 个顶层字段)→ 键名拼错静默落中性 | U2 改述:trace 键名正确性的真护栏只有跨语言切片喂真 ReadinessScorer |
| MINOR | m2 gatespec.driver 键名陷阱(源是 driverType,须落键名 driver) |
U2 显式钉死键名映射 |
| MINOR | m3 D9「重接」实为 monkey-patch 模块级全局常量 DEDUP_REGISTRY、非传参 |
KTD2 / 决策点改述 + U3 加路径隔离测试 |
| MINOR | m4 §Sources feed 读侧行号引错(515/525-532 是写侧,读侧 PUBLISHED 过滤在 237-239) | Sources 改正 |
| MINOR | m5 散文 4 处元叙述踩 §12 铁律 | 删「钉死了 / 收敛成一句话 / 要诚实记下 / 结论是乐观的」 |
| 补注 | run_gates=False 对照路不产 verdict/gatespec | U1 注明捕获须对 None 容错 |
执行发现(2026-06-28 · 本机 U1-U3 完成 + 验证 · mini-desktop 前 checkpoint)
本机阶段 U1-U3 已交付并验证(opus 子代理执行 + 主会话亲验)。
-
U1/U2/U3 全绿:cheap_studio 富化(
build_trace_source+_furthest_stage)/ result_out_build_trace(七项 + sevenGateVerdict{pass,guards}+ gatespec{driver}+ cost + similarity,camelCase 镜像_extract_trace、对 verdictFull/driverType None 容错)/ D9dedup.pyvendored 进 cheap-worker(DEDUP_REGISTRY指自己 results/)。cheap-worker 全 16 测文件绿(test_result_out 18/18、test_trace_source 5/5、test_dedup 6/6、test_worker_service 15/15)。 -
跨语言反假绿门坐实(Opus M1 真护栏):Java
CheapWorkerResultOutContractTest新增readiness_perDimension_escapes_neutral_and_diverges——反射调真 ReadinessScorer 私有逐维 scorer:成功 fixture 三维 playability/firstPlay/stability 各=1.0(脱离中性 0.5)、合成分 100 vs 仅-cost 退化态 ≤55、拉开 ≥35。mvn 实跑 5/5 绿、BUILD SUCCESS。坐实 9d trace parity 真救活 D11(非区间-落点假绿)。 -
顺带修一处预存 M3a 缺陷:
test_worker_loop_run_failure_sends_fallback_failed在 HEADa327c991即红——worker 异常兜底_send_failed传非枚举值generation_failed(经 build_result_out 映射成llm_error,回调行为正确但测断言陈旧)。对代码核实 M3b 未碰相关行、确属预存 → 改_send_failed传真枚举值llm_error(错误路用真枚举、可追溯)+ 测断言对齐。 -
执行中纠正的设计假设(红线兑现):计划初稿假设「_bootstrap 已把 gen-worker 入 sys.path、可 import wg1 dedup」——核验证伪(_bootstrap 入的是
tier2/gen-worker、其无 dedup/_extract_trace;wg1 是另一棵树、不在 cheap-worker 的 import 路径)。U3 据此改为 vendor 复制dedup.py(更干净、并消除 Opus m3 的 monkey-patch 脆点)。 -
范围:改动仅 cheap-worker/(cheap_studio / result_out / worker_service / 新 dedup.py + 4 个测文件)+ 2 个 Java fixture + 1 个 Java 测方法;零跨档、零 live 触碰。 U4/U5 mini-desktop 真 e2e(iso :48090 worker M3b :9501,live :48080 全程未动):
-
U4 真 gen(task 189,便宜档失败九门=便宜档质量、非 M3b) → 回调七步 → trace_json 落齐七项 + D9 similarity 产出 + readiness_score=28(playability=0/firstPlay=0.5/stability=1.0/efficiency=0,真读信号)。开
aigc.trace.enabled=true后落库生效。 -
U5 注入真 bundle(succeeded):含真 multiball bundle(214KB · __GameBundle)的合法 succeeded 回调 → version 93144 + runtime_package(engineBundle 落 package_json)+ readiness_score=100。D11 三值判别坐实:失败 28 / 退化(仅 cost · Java 切片)45 / 成功 100,分数真随质量动。
-
6 门新路状态:9d trace / D11 / D9 三道 worker 侧门新路已验(U4/U5);D12 / GP9(提交侧、dispatch 上游、与 worker 实现正交,GP9 经 G1 已验)+ 首局(引擎无关 harness)三道新路天然继承。
-
边界发现(收口判据修正):玩家 manifest 端点要求 runtime_package published(status=1),preview(0)返「运行包未发布」。故
publish→feed→玩家真玩必须过reviewProject(APPROVE)——按本 plan 移交边界属产品/审核台轨(auth + 项目 REVIEWING 生命周期)、非生成线 M3b;M3b 生成线交付 = 落到可发布的预览包(version + status=0 包 + 真 engineBundle 进 package_json + D11 分),已具。 -
创始人裁定(2026-06-28):收口 M3b 生成线 + U6 蒸馏;publish→feed→玩家真玩 作产品轨后续。测试数据已清(task 189/190、version 93144、runtime_package、amgen 工作区)。
-
✅ 生产 cutover 完成(2026-06-28,创始人「同意切,完成M3」):侦察揭 live :48080 原跑 6-21 旧 gamedef jar(非 M3 代码),故 cutover 实质=jar 重部署。端口精确把 live :48080 换成 6-28 M3 jar(dev/2.0.0)+ dispatcher=http→worker:9501 + trace.enabled,boot 日志「生成派发通道选定 dispatcher=http=WorkerDispatchClient」坐实 Node/gamedef 旧路在 live 退役、Python M3 路上 live;
fuser -k 48080/tcp端口精确(绝不 global pkill)、revert 备=换回 6-21 jar+saa;拆 iso :48090 避 live+iso 双 executor 同 DB split-brain;最终拓扑=live :48080(M3 路)+ worker :9501,同 DB 13306。control-plane 6门放量创始人定后单独开。 -
遗留(M3 完整达标的非 cutover 工程缺口):① ≥80% 生产真实分布达标复验(依赖便宜档生成质量=WU-B/C/F;U4 真 gen 没过九门、质量未到 ≥80%)② 对外开闸 6门放量(control-plane,§6 放行决策 + 待拍配额值,创始人定后单独开)③ 产品轨 publish→feed→玩家真玩(移交边界 auth+REVIEWING)④ 待拍数值(配额/D11 权重/
BUDGET_RMB/D9 阈值)。即 Node 退役 go-live 已成;M3 的 ≥80% 质量达标 + 开闸放量 = 后续(质量轨/放行决策)。
状态: M3b 生成线收口(创始人 2026-06-28 裁定)。 承重命题(9d trace 七项 parity 救活 D11 + D9 dedup parity)经 §6.8 双评审 → 本机 U1-U3(全 16 Python 测绿 + Java 跨语言切片 5/5 绿)→ mini-desktop U4/U5 真后端 e2e 跨成败两路证实(D11 三值判别 28/45/100;trace+similarity 真落库;engineBundle 落可发布预览包),全程 live :48080 未动。6 门:worker 侧三门(trace/D11/D9)新路已验,提交侧/harness 三门(D12/GP9/首局)新路天然继承。✅ 生产 cutover 已切(2026-06-28,创始人「同意切」):live :48080 退 Node/gamedef、上 Python M3 路(dispatcher=http→worker:9501 + trace),拆 iso 避 split-brain。 M3 剩:≥80% 生产真实分布达标复验(质量轨 WU-B/C/F)+ 对外开闸 6门放量(control-plane §6 放行决策)+ publish→feed→玩家真玩(产品/审核台轨,移交边界)。