From 6d2f8789d79f06503cf670708894c811efa982c7 Mon Sep 17 00:00:00 2001 From: zizi Date: Wed, 1 Jul 2026 11:18:20 +0800 Subject: [PATCH] remove archive doc --- .agents/knowledge/agentscope-2.0-facts.md | 75 - .agents/knowledge/glossary.md | 61 - .agents/knowledge/tech-decisions.md | 164 -- .agents/rules/build-vs-buy.md | 37 - .agents/skills/cheap-model-game-generation.md | 97 - .agents/skills/contract-first-development.md | 104 -- .agents/skills/game-e2e-cdp-harness.md | 120 -- .gitignore | 12 + SAA-INTEGRATION-TODO.md | 13 - .../ideas/batch-001.txt | 25 - .../ideas/batch-002.txt | 30 - .../ideas/batch-002b.txt | 10 - .../ideas/idle-cal-10.txt | 17 - .../ideas/merge-cal-10.txt | 18 - .../ideas/merge-prod-20.txt | 27 - .../ideas/tycoon-cal-10.txt | 17 - .../orchestrator/.agent | 26 - .../orchestrator/README.md | 151 -- .../orchestrator/admin_walk.py | 165 -- .../orchestrator/backend_gw.py | 233 --- .../orchestrator/dash_walk.py | 276 --- .../orchestrator/evalflow.py | 251 --- .../orchestrator/feed_polish_walk.py | 71 - .../orchestrator/judge.py | 510 ----- .../orchestrator/ledger.py | 375 ---- .../orchestrator/llm_client.py | 272 --- .../orchestrator/newapi_cost.py | 187 -- .../orchestrator/player_cdp.py | 1637 ----------------- .../orchestrator/probe_bridge_channel.py | 285 --- .../orchestrator/prompts.py | 189 -- .../orchestrator/report.py | 352 ---- .../orchestrator/run_batch.py | 1269 ------------- .../orchestrator/run_dash_walk.sh | 17 - .../orchestrator/run_feed_polish_walk.sh | 16 - .../orchestrator/run_studio_walk.sh | 16 - .../orchestrator/run_walk.sh | 15 - .../orchestrator/sql/permission-fixture.sql | 43 - .../orchestrator/studio_walk.py | 295 --- .../orchestrator/tests/__init__.py | 2 - .../orchestrator/tests/test_judge.py | 363 ---- .../tests/test_judge_merge_schema.py | 175 -- .../orchestrator/tests/test_ledger.py | 268 --- .../tests/test_llm_client_strip.py | 156 -- .../2026-06-09-agent-loop-v1/runs/README.md | 12 - .../audit-fallback/prompt-variant.md | 33 - .../runs/batch-001/report.md | 139 -- .../runs/batch-002/report.md | 68 - .../runs/batch-002b/report.md | 66 - .../runs/golden-regression-v1.1.0/report.md | 113 -- .../runs/golden-regression-v1.1.1/report.md | 153 -- .../golden-regression-v1.1.2-b2/report.md | 44 - .../runs/golden-regression-v1.1.2/report.md | 41 - .../runs/idle-cal-10/report.md | 66 - .../runs/merge-cal-10/report.md | 66 - .../runs/merge-prod-20/report.md | 77 - .../runs/tycoon-cal-10/report.md | 67 - .../accepted-configs.json | 44 - .../assert_feed.py | 52 - .../2026-06-09-generation-spike/gen_spike.py | 187 -- .../pilot-results.md | 61 - .../seed-staging-report.md | 241 --- .../spike-eval.csv | 53 - .../spike-summary.md | 37 - .../2026-06-10-模型评估矩阵/designer-probe.md | 114 -- .../2026-06-10-模型评估矩阵/judge-duel.md | 143 -- .../m27hs/小结-主力升级门判定.md | 66 - .../2026-06-10-模型评估矩阵/report.md | 109 -- .../2026-06-10-模型评估矩阵/struct-m3-小结.md | 38 - .../struct-v4pro-小结.md | 38 - ...026-06-08-admin-wave2并行建设-execution.md | 8 - .../2026-06-08-admin-wave2并行建设-review.md | 79 - .../_archive/2026-06-08-mvp业务决策.md | 41 - ...-06-08-wave3-staging联调与P0补全-review.md | 240 --- ...26-06-08-wave3创作补全与发布闸门-review.md | 193 -- ...026-06-08-前端game-studio建设-execution.md | 9 - .../2026-06-08-前端game-studio建设-review.md | 343 ---- .../2026-06-08-后端模块并行建设-execution.md | 8 - .../2026-06-08-后端模块并行建设-review.md | 134 -- .../_archive/2026-06-09-B4四链路烟测报告.md | 158 -- .../2026-06-09-agent化生成QA闭环-execution.md | 8 - .../2026-06-09-agent化生成QA闭环-review.md | 311 ---- .../_archive/2026-06-09-wave3-execution.md | 8 - .../_archive/2026-06-09-下一阶段路线-plan.md | 121 -- ...09-核心功能技术实现方案-总体设计-review.md | 9 - .../2026-06-09-核心功能技术实现方案.md | 9 - ...26-06-09-王蓝莓小卖部黄金闭环-execution.md | 8 - .../_archive/2026-06-10-Mb渲染面-execution.md | 9 - .../2026-06-10-Mb生成下沉-execution.md | 8 - .../_archive/2026-06-10-Mc模板波-execution.md | 9 - .../_archive/2026-06-10-Mc模板波-review.md | 176 -- .../2026-06-10-Mc模板波-批①收口报告.md | 45 - ...06-10-Mc模板波-批②idle-tycoon-execution.md | 9 - .../2026-06-10-数据回路小波-execution.md | 9 - .../2026-06-10-架构文档三向审计-review.md | 179 -- .../2026-06-10-真实鉴权与匿名玩家-e2e报告.md | 63 - ...2026-06-10-真实鉴权与匿名玩家-execution.md | 8 - .../2026-06-10-真实鉴权与匿名玩家-review.md | 215 --- .../2026-06-11-T1引擎spike-execution.md | 131 -- .../_archive/2026-06-11-T1引擎终裁包.md | 80 - .../2026-06-11-Tier1运行时重设计-review.md | 224 --- .../2026-06-11-W4单位经济埋点-评审纪要.md | 84 - ...026-06-11-Wave4-community-biz-execution.md | 9 - ...-11-Wave4-community-biz-review-评审纪要.md | 100 - .../2026-06-11-Wave4-community-biz-review.md | 434 ----- .../2026-06-11-admin-cloud清理-codex执行单.md | 9 - ...2026-06-11-community-biz前端入口-review.md | 451 ----- ...26-06-11-community-biz前端入口-评审纪要.md | 125 -- .../2026-06-11-回包链路专项修-收口报告.md | 52 - ...026-06-12-T1b-α插件库与参考件-execution.md | 9 - .../_archive/2026-06-12-T1b-α收口报告.md | 42 - ...06-12-T1b-β引擎真接线与Runner-v2-review.md | 226 --- ...026-06-12-W-T1b-Runner与双层模板-review.md | 76 - .../2026-06-12-agentic基建框架选型-review.md | 73 - .../2026-06-12-自研偏误全链审计-报告.md | 168 -- .../2026-06-13-A0-引擎掌帧接管-edit-plan.md | 9 - .../_archive/2026-06-13-A1-A6-接线政策.md | 311 ---- .../_archive/2026-06-13-A1-edit-plan.md | 9 - .../_archive/2026-06-13-A2-edit-plan.md | 9 - .../_archive/2026-06-13-A3-edit-plan.md | 9 - .../_archive/2026-06-13-A4-edit-plan.md | 9 - .../2026-06-13-P1-王蓝莓上引擎-execution.md | 9 - .../2026-06-13-P1-王蓝莓上引擎-review.md | 171 -- ...26-06-13-P2-runner-v2泛化宿主-execution.md | 9 - .../2026-06-13-P2-runner-v2泛化宿主-review.md | 412 ----- ...13-T1b-β引擎真接线与Runner-v2-execution.md | 169 -- .../2026-06-13-WG1-20经典轻游戏基准-review.md | 186 -- .../2026-06-13-runner-v2-arc-review.md | 296 --- .../2026-06-14-OpenGame蓝图补缺-review.md | 280 --- .../2026-06-14-P3-W-G1生成主线-execution.md | 9 - .../2026-06-14-P3-W-G1生成主线-review.md | 404 ---- ...eoff天花板与Claude-free评估门-execution.md | 185 -- ...bakeoff天花板与Claude-free评估门-review.md | 177 -- .../2026-06-14-WG1-scale20-短板量化报告.md | 148 -- ...26-06-15-SAA-AgentScope-spike-execution.md | 85 - .../2026-06-15-SAA-能力API接入-dossier.md | 72 - .../_archive/2026-06-15-T1b-β收口报告.md | 212 --- ...-WG1-driver-coverage闭口与P2对照-L1报告.md | 86 - ...WG1-tap-targets-driver-自产缺口-L1brief.md | 160 -- ...26-06-15-python-to-SAA-migration-design.md | 309 ---- .../2026-06-15-python-vs-SAA-对比测试.md | 94 - .../2026-06-16-M4变现真实化-review.md | 148 -- .../2026-06-16-SAA-form①-e2e-runplan.md | 215 --- .../2026-06-16-agent-specs目录治理-review.md | 234 --- ...16-studio视觉体系-i18n-组件库-execution.md | 95 - .../2026-06-16-技术决策版重写-review.md | 65 - .../_archive/2026-06-16-生成引擎-并行编排.md | 20 - ...26-06-16-生成引擎主线-传承与演进-review.md | 100 - .../2026-06-16-视觉增强repair-review.md | 90 - .../2026-06-17-agent-specs深度重构-plan.md | 167 -- ...-17-demo与三文档套件缺口冲突审计-review.md | 256 --- ...7-产品功能与技术模块-完成度与优先级总账.md | 139 -- ...固定游戏架构与SAA-agentic-studio-review.md | 180 -- .../2026-06-17-开闸-一句话入口接线-review.md | 81 - .../_archive/2026-06-17-文档整理-plan.md | 161 -- ...17-生成主线-游戏生命周期项目管理-review.md | 136 -- ...2026-06-17-组B-SAA路trace接线-execution.md | 384 ---- .../2026-06-19-生成平台架构演进-review.md | 174 -- .../2026-06-20-OpenGame对照分析与复刻缺口.md | 153 -- .../2026-06-20-架构错误根因复盘-report.md | 73 - .../2026-06-20-生成设计合理性-对抗审查裁决.md | 88 - .../2026-06-21-planB-phase2-closeout.md | 45 - docs/agent-specs/_archive/agentic编排-SAA.md | 149 -- .../_archive/prompt治理体系-execution.md | 157 -- .../_archive/studio前端设计体系.md | 101 - docs/agent-specs/_archive/变现与单位经济.md | 113 -- docs/agent-specs/_archive/开闸验收门-W-G1.md | 104 -- docs/agent-specs/_archive/引擎与运行时.md | 103 -- docs/agent-specs/_archive/总账-波次史归档.md | 46 - docs/agent-specs/_archive/战略与合规.md | 78 - docs/agent-specs/_archive/渠道发行.md | 91 - game-admin/package-lock.json | 541 +++--- 171 files changed, 304 insertions(+), 23292 deletions(-) delete mode 100644 .agents/knowledge/agentscope-2.0-facts.md delete mode 100644 .agents/knowledge/glossary.md delete mode 100644 .agents/knowledge/tech-decisions.md delete mode 100644 .agents/rules/build-vs-buy.md delete mode 100644 .agents/skills/cheap-model-game-generation.md delete mode 100644 .agents/skills/contract-first-development.md delete mode 100644 .agents/skills/game-e2e-cdp-harness.md delete mode 100644 SAA-INTEGRATION-TODO.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-001.txt delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002.txt delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002b.txt delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/ideas/idle-cal-10.txt delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-cal-10.txt delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-prod-20.txt delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/ideas/tycoon-cal-10.txt delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/.agent delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/README.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/admin_walk.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/backend_gw.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/dash_walk.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/evalflow.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/feed_polish_walk.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/judge.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/ledger.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/llm_client.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/newapi_cost.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/player_cdp.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/probe_bridge_channel.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/prompts.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/report.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/run_batch.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/run_dash_walk.sh delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/run_feed_polish_walk.sh delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/run_studio_walk.sh delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/run_walk.sh delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/sql/permission-fixture.sql delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/studio_walk.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/tests/__init__.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/tests/test_judge.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/tests/test_judge_merge_schema.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/tests/test_ledger.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/tests/test_llm_client_strip.py delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/README.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/batch-001/audit-fallback/prompt-variant.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/batch-001/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/batch-002/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/batch-002b/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/golden-regression-v1.1.0/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/golden-regression-v1.1.1/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/golden-regression-v1.1.2-b2/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/golden-regression-v1.1.2/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/idle-cal-10/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/merge-cal-10/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/merge-prod-20/report.md delete mode 100644 docs/agent-specs/2026-06-09-agent-loop-v1/runs/tycoon-cal-10/report.md delete mode 100644 docs/agent-specs/2026-06-09-generation-spike/accepted-configs.json delete mode 100644 docs/agent-specs/2026-06-09-generation-spike/assert_feed.py delete mode 100644 docs/agent-specs/2026-06-09-generation-spike/gen_spike.py delete mode 100644 docs/agent-specs/2026-06-09-generation-spike/pilot-results.md delete mode 100644 docs/agent-specs/2026-06-09-generation-spike/seed-staging-report.md delete mode 100644 docs/agent-specs/2026-06-09-generation-spike/spike-eval.csv delete mode 100644 docs/agent-specs/2026-06-09-generation-spike/spike-summary.md delete mode 100644 docs/agent-specs/2026-06-10-模型评估矩阵/designer-probe.md delete mode 100644 docs/agent-specs/2026-06-10-模型评估矩阵/judge-duel.md delete mode 100644 docs/agent-specs/2026-06-10-模型评估矩阵/m27hs/小结-主力升级门判定.md delete mode 100644 docs/agent-specs/2026-06-10-模型评估矩阵/report.md delete mode 100644 docs/agent-specs/2026-06-10-模型评估矩阵/struct-m3-小结.md delete mode 100644 docs/agent-specs/2026-06-10-模型评估矩阵/struct-v4pro-小结.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-admin-wave2并行建设-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-admin-wave2并行建设-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-mvp业务决策.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-wave3-staging联调与P0补全-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-wave3创作补全与发布闸门-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-前端game-studio建设-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-前端game-studio建设-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-后端模块并行建设-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-08-后端模块并行建设-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-B4四链路烟测报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-agent化生成QA闭环-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-agent化生成QA闭环-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-wave3-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-下一阶段路线-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-核心功能技术实现方案-总体设计-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-核心功能技术实现方案.md delete mode 100644 docs/agent-specs/_archive/2026-06-09-王蓝莓小卖部黄金闭环-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-Mb渲染面-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-Mb生成下沉-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-Mc模板波-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-Mc模板波-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-Mc模板波-批①收口报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-Mc模板波-批②idle-tycoon-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-数据回路小波-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-架构文档三向审计-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-真实鉴权与匿名玩家-e2e报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-真实鉴权与匿名玩家-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-10-真实鉴权与匿名玩家-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-T1引擎spike-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-T1引擎终裁包.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-Tier1运行时重设计-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-W4单位经济埋点-评审纪要.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-Wave4-community-biz-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-Wave4-community-biz-review-评审纪要.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-Wave4-community-biz-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-admin-cloud清理-codex执行单.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-community-biz前端入口-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-community-biz前端入口-评审纪要.md delete mode 100644 docs/agent-specs/_archive/2026-06-11-回包链路专项修-收口报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-12-T1b-α插件库与参考件-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-12-T1b-α收口报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-12-T1b-β引擎真接线与Runner-v2-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-12-W-T1b-Runner与双层模板-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-12-agentic基建框架选型-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-12-自研偏误全链审计-报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-A0-引擎掌帧接管-edit-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-A1-A6-接线政策.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-A1-edit-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-A2-edit-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-A3-edit-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-A4-edit-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-P1-王蓝莓上引擎-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-P1-王蓝莓上引擎-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-P2-runner-v2泛化宿主-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-P2-runner-v2泛化宿主-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-T1b-β引擎真接线与Runner-v2-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-WG1-20经典轻游戏基准-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-13-runner-v2-arc-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-14-OpenGame蓝图补缺-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-14-P3-W-G1生成主线-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-14-P3-W-G1生成主线-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-14-WG1-bakeoff天花板与Claude-free评估门-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-14-WG1-bakeoff天花板与Claude-free评估门-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-14-WG1-scale20-短板量化报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-15-SAA-AgentScope-spike-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-15-SAA-能力API接入-dossier.md delete mode 100644 docs/agent-specs/_archive/2026-06-15-T1b-β收口报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-15-WG1-driver-coverage闭口与P2对照-L1报告.md delete mode 100644 docs/agent-specs/_archive/2026-06-15-WG1-tap-targets-driver-自产缺口-L1brief.md delete mode 100644 docs/agent-specs/_archive/2026-06-15-python-to-SAA-migration-design.md delete mode 100644 docs/agent-specs/_archive/2026-06-15-python-vs-SAA-对比测试.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-M4变现真实化-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-SAA-form①-e2e-runplan.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-agent-specs目录治理-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-studio视觉体系-i18n-组件库-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-技术决策版重写-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-生成引擎-并行编排.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-生成引擎主线-传承与演进-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-16-视觉增强repair-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-agent-specs深度重构-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-demo与三文档套件缺口冲突审计-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-产品功能与技术模块-完成度与优先级总账.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-固定游戏架构与SAA-agentic-studio-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-开闸-一句话入口接线-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-文档整理-plan.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-生成主线-游戏生命周期项目管理-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-17-组B-SAA路trace接线-execution.md delete mode 100644 docs/agent-specs/_archive/2026-06-19-生成平台架构演进-review.md delete mode 100644 docs/agent-specs/_archive/2026-06-20-OpenGame对照分析与复刻缺口.md delete mode 100644 docs/agent-specs/_archive/2026-06-20-架构错误根因复盘-report.md delete mode 100644 docs/agent-specs/_archive/2026-06-20-生成设计合理性-对抗审查裁决.md delete mode 100644 docs/agent-specs/_archive/2026-06-21-planB-phase2-closeout.md delete mode 100644 docs/agent-specs/_archive/agentic编排-SAA.md delete mode 100644 docs/agent-specs/_archive/prompt治理体系-execution.md delete mode 100644 docs/agent-specs/_archive/studio前端设计体系.md delete mode 100644 docs/agent-specs/_archive/变现与单位经济.md delete mode 100644 docs/agent-specs/_archive/开闸验收门-W-G1.md delete mode 100644 docs/agent-specs/_archive/引擎与运行时.md delete mode 100644 docs/agent-specs/_archive/总账-波次史归档.md delete mode 100644 docs/agent-specs/_archive/战略与合规.md delete mode 100644 docs/agent-specs/_archive/渠道发行.md diff --git a/.agents/knowledge/agentscope-2.0-facts.md b/.agents/knowledge/agentscope-2.0-facts.md deleted file mode 100644 index eeaf911f..00000000 --- a/.agents/knowledge/agentscope-2.0-facts.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -name: agentscope-2.0-facts -description: AgentScope 2.0 架构事实速查(源码实证 v2.0.2 + 官方文档)——编排/沙箱/服务化部署,给 tier2 富游戏线设计用 -node_type: knowledge ---- - -# AgentScope 2.0 架构事实(源码实证 + 官方文档) - -本文记录 AgentScope 2.0 的真实形态。来源是直接读 `/root/oss/agentscope`(checkout 在正式版 **v2.0.2**,即 PyPI 当前最新稳定版)的源码,并与官方文档 `docs.agentscope.io/v2` 交叉验证,每条关键结论都给了源码出处。 - -**版本号澄清**:PyPI 上没有 2.0.3 这个版本,早先文档里的「AgentScope 2.0.3」是笔误,正确是 2.0.2。AgentScope 的 1.0.x 到 2.0.x 是同一条线的连续大版本升级,不是两条并行的线;引用时以 `/root/oss/agentscope` 当前 checkout 的 tag 为准。 - -## 核心范式 - -2.0 是一次架构大重写。1.x 的静态编排原语(`pipeline` / `MsgHub` / `sequential_pipeline`)已经全部删除——在 `src/` 下搜这些类名零命中。取而代之的是「单个自带 ReAct 循环的 `Agent` 类 + 一个 FastAPI 服务层(`agentscope.app`)」。多 agent 协作、对外发布、沙箱执行这些能力,都上移到了服务层,而不再是库里的拼接式管道。 - -## 编排:单 Agent 自治 + 服务层 Team 工具 - -`agentscope.agent` 模块只导出一个统一的 `Agent` 类,它自带 reasoning→acting 的 ReAct 循环(`agent/_agent.py:594` 的迭代主体,`max_iters` 兜底退出)。1.x 那种声明式的 agent 子类(ReActAgent / DialogAgent)和消息管道都不存在了。 - -需要多个 agent 协作时,走的不是静态拓扑图,而是**把「建队、派 worker、对话」做成工具交给 leader agent 自己调用**:`AgentCreate` / `TeamCreate` / `TeamSay` / `TeamDelete` 四个工具配 `SubAgentTemplate`(worker 蓝图)。leader 调 `AgentCreate` 就 spawn 一个 worker agent + session,worker 的 `source="team"`、只拿得到 `TeamSay`(向 leader 汇报),leader 拿全套工具(`app/_service/_toolkit.py` 按 `source` 选工具可见性)。这是 agent-as-tool 的动态组队,对应官方哲学——靠模型自身的推理和工具调用,而不用刚性 prompt 和带倾向的编排去约束它。 - -**一个硬约束**:这套多 agent 能力**只在 app 服务层可用**,纯库里 import 一个 `Agent` 跑脚本是没有的。 - -## 沙箱:编排后工具调用直接落沙箱执行 - -Workspace 提供三种执行后端(`workspace/__init__.py`):`LocalWorkspace`(host 进程内,零隔离,开发用)、`DockerWorkspace`(容器)、`E2BWorkspace`(E2B 云沙箱)。agent 的工具来自 workspace(`get_toolkit(workspace=...)` 时 `tools = await workspace.list_tools()`),所以「换一个 workspace」就把执行环境从本地搬到了容器或云沙箱。 - -执行如何落进沙箱:Local 后端的 Bash/Read/Write 是 host 进程内的 Python 工具;Docker/E2B 后端的 `list_tools()` 返回空,工具改由容器内的 FastAPI MCP gateway 提供——agent 调工具时,host 侧 `GatewayClient` 发 `HTTP POST {gateway}/mcps/{mcp}/tools/{tool}`(`_gateway_client.py:136`)到容器内 gateway 真正执行。这就是「编排好之后工具调用直接在沙箱里跑」的机制。 - -**一个坑**:Docker/E2B 沙箱镜像默认不注册任何 filesystem/bash MCP,要在沙箱里有 Bash/Read/Write,得自带 MCP server 注册为 `default_mcps`;只有 Local 后端内置这些工具。 - -## 安装与部署:pip 装包即可,官方只主推一条生产路径 - -跑 AgentScope **不需要 clone 仓库**——`pip install agentscope[full]` 装包即可,`app` / `workspace` / `tool` 全在 wheel 内。框架**没有 CLI**(pyproject 无 `[project.scripts]`,不存在 `as serve` 之类命令),启动靠在 `main.py` 里自己调 uvicorn。两个例外要记:Docker 沙箱在 2.0.2 这个「尚未发布到 PyPI 的过渡期」目前需要本地有 agentscope 源码(构建镜像时 COPY 进去);E2B 沙箱需要 E2B 账号和 API key。`/root/oss/agentscope` 这份 clone 的主要价值是读源码核对,而非生产运行的必需品。 - -生产部署,官方主推且唯一给出端到端示例的形态是 **Agent Service**:用 `create_app(storage, message_bus, workspace_manager)` 造一个 FastAPI/ASGI app(`app/_app.py:33`),再用 uvicorn 起进程(`examples/agent_service/`)。它提供多租户、多会话、REST 触发 + SSE 事件流、HITL 审批、定时任务、凭据托管。两个要点决定了接入方式:一是 **chat 端点是 fire-and-forget**,`POST /chat` 立即返回 `started`,事件要另外从 `GET /sessions/{id}/stream` 的 SSE 流里收;二是**强依赖 Redis**——storage 和 message_bus 都只有 Redis 实现,没有 in-memory/SQLite 版本,生产必须配 Redis。要弹性扩展,就把这个 ASGI app 自己容器化后上 K8s 或 serverless,框架不提供 app 级的 Dockerfile/compose。 - -## 生态定位与一个架构信号 - -独立的 `agentscope-runtime` 项目**已归档**:官方声明其全部能力(工具沙箱、Agent-as-a-Service、可观测)已原生并入 AgentScope 2.0。所以 2.x 做沙箱和部署不要再装那个独立仓,`agentscope[full]` 一个包就齐。AgentScope Studio 是开发期的可视化追踪/调试台,不是生产承载层。 - -一个值得记的信号:官方称 **Spring AI Alibaba 底层将采用 agentscope-java 作为引擎**。这意味着项目里「SAA 廉价线」和「AgentScope 富游戏线」在引擎血统上正趋同。这条长期架构判断**已裁定(2026-06-25 reframe):框架收敛 AgentScope、SAA 降最低优先级(留作远期适配验证可插拔的目标)**——三档生成不再按引擎或产线分,而按 AI 参与深度切;详见运行时 SoT [`生成引擎/agentic运行时架构图说`](../../docs/architecture/架构/生成引擎/agentic运行时架构图说.md) §一 / §四。相关决策见 [[saa-agentic-infra-decision]]。 - -## 关键纠偏对照 - -| 凭名臆想 | 源码实证(v2.0.2) | -|---|---| -| 2.x = pipeline / MsgHub | 已删,改单 Agent ReAct + 服务层 Team 工具 | -| 多 agent 是静态编排图 | agent-as-tool 动态组队,且只在 app 服务层 | -| 用框架要 clone 源码 | `pip install agentscope[full]` 即可(Docker 沙箱过渡期暂需源码) | -| 有 CLI / `serve` 命令 | 无,生产 = `create_app()` FastAPI + uvicorn + Redis | -| 沙箱要装独立 agentscope-runtime | 已归档,能力并入 2.0 主框架 | - -## 便宜档 cheap-worker 实现 API 速查(2.0.2 源码实证 + WU-A spike 落地) - -上文偏架构(编排/沙箱/服务化)。本节是「怎么用库写一个跑通的 agent」的实现层速查——WU-A spike 把便宜档生成核心重写进 AgentScope(`cheap-worker/`,import 复用 tier2 框架层)时落地并核验,下一个 WU-A 全量重写 / n=5 直接照用,不必重新挖。 - -**import 路径(全部源码核验存在)**:`from agentscope.agent import Agent, ReActConfig, ContextConfig` · `from agentscope.tool import Toolkit, FunctionTool` · `from agentscope.middleware import MiddlewareBase` · `from agentscope.model import OpenAIChatModel, AnthropicChatModel` · `from agentscope.message import UserMsg, TextBlock` · `from agentscope.state import AgentState` · `from agentscope.permission import PermissionContext, PermissionMode`。 - -**三个「凭名臆想会用错」的不存在 API(源码全树零命中,别用)**: - -- `register_tool_function` **不存在** → 注册靠构造器 `Toolkit(tools=[FunctionTool(fn), ...])`。 -- `ReplyBudgetControlMiddleware` **不存在** → 预算/软刹得自挂 `MiddlewareBase` 的 `on_system_prompt`/`on_model_call` 钩子(tier2 的 `CircuitBreakerMiddleware` 即如此自实现)。 -- 内置 ReAct **不会「跑满 max_iters 才停」** → 在「模型产出无 tool_call 的纯文本回合」即退出(`agent/_agent.py`)。要多轮自修必须在 Agent 外**自建有界 resume 循环**:`for attempt in range(max_resumes): await agent.reply(...); 判收敛/门绿;否则带失败反馈再 reply`。这一圈正对应 Node 生成 harness 的 while 主循环。 - -**工具写法(schema 自动抽)**:每个工具是 `async def` + 参数类型注解 + Google docstring(`Args:`),`FunctionTool(fn)` 据此抽 schema;闭包捕获一个可变 session 对象做跨工具状态;返回 str(纯文本或 `json.dumps`)。 - -**Agent 构造(无人值守跑脚本)**:`Agent(name, system_prompt, model, toolkit, middlewares=[trace, breaker], state=AgentState(permission_context=PermissionContext(mode=PermissionMode.BYPASS)), react_config=ReActConfig(max_iters=...), context_config=ContextConfig(...))`。**BYPASS 必给**——否则 FunctionTool 默认 check_permissions 返回 ASK,无人值守跑会卡死。`reply` 是 async:`await agent.reply(UserMsg(name="user", content=text))`(UserMsg 必带 name)。**model 直调(验连通用)**:`await model([UserMsg(...)]) → ChatResponse(content=[TextBlock(text=...)], ...)`。 - -**便宜档复用 tier2 框架层(import 不重写、零改 tier2)**:`config.build_model_openai("MiniMax-M3", max_tokens=16000, record=True)`(OpenAI 协议、自动补 /v1、自动装代理旁路 + 取 key)· `config.build_context_config()`(历史压缩)· `CircuitBreakerMiddleware` + `Tier2TraceMiddleware`(四道熔断 + trace,与模型档无关,`enable_rmb_gate=False` 可关 ¥ 闸)· `client.install_proxy_bypass`(**必须在 import openai 之前**,否则本机 clash 把发往内网网关的请求转走得 502)· `client.get_api_key()`(**只读 env `NEWAPI_KEY`**;内网阶段 key 在 `docs/内网凭据与端点.md`,调用方先解析注入 env)。 - -**跨包 import 含连字符目录**:`gen-worker` 不能 `import`;把 `tier2/gen-worker/` 加进 `sys.path` 再 `from worker import ...`(`from observability import ...` 同理)。 - -落地实证 = 便宜档 Python 线 `cheap-worker/`(WU-A spike,端到端九门对照 Node 9/9 持平、过门率 1.0=1.0、对 tier2 零改动)。便宜档生成线现状见 [`cheap-model-game-generation`](../skills/cheap-model-game-generation.md)(注意其旧 W-G1 路已被 cheap-worker 取代)。 diff --git a/.agents/knowledge/glossary.md b/.agents/knowledge/glossary.md deleted file mode 100644 index b974fb10..00000000 --- a/.agents/knowledge/glossary.md +++ /dev/null @@ -1,61 +0,0 @@ -# 术语表 - -> 蒸馏来源:技术决策版 §11.1 附录术语表、§3.4 SDK 设计、§4 核心链路;执行 spec。 -> 目的:统一项目黑话,调试/评审/编码时快速对齐。每条一句话。 -> 相关:[`product-and-architecture.md`](./product-and-architecture.md) · [`tech-decisions.md`](./tech-decisions.md) · [`mvp-scope-and-milestones.md`](./mvp-scope-and-milestones.md)。 - -| 术语 | 一句话释义 | -|---|---| -| **GameConfig** | 游戏配置 JSON,描述玩法/关卡/角色/规则。**2026-06-12 起口径已变**:生成主线从"禁代码、填参数"迁到"让 agent 写码"(HJ-GEN-001),GameConfig 不再是驱动玩法的唯一入口;现行廉价线产 gameDefinition 中间表示(含逻辑 JS),终态走 `src/` 源工程(见 gameDefinition 词条)。安全合规可控改由"产物执行沙箱(iframe+CSP)+ build 段静态门"承接,而非"创作者只填参数"。 | -| **gameDefinition**(中间表示·脚手架) | 廉价线 generate 节点产出的结构化游戏定义 JSON:entities/components/scenes/rules 是声明式数据壳,逻辑核塞在 `behavior.code` 这个 JSON 字符串里、运行时用 `new Function` 解释执行。**它不是合格终态产物**——创始人 2026-06-20 定调终态必须是 `src/` 多文件源工程(结构化、可导航、agent 能定位);gameDefinition 只是"通往 src/ 的中间妥协态/脚手架",妥协只许在输入端(便宜模型先产极简声明式描述),产物端停在 JSON 内嵌 JS 串属**已知偏离终态的债**,缺的正是"gameDefinition → src/ 工程"那段展开。中间表示双证(92–100% 连贯、¥0.011/款、build-from-source 过九门)只证"便宜模型能可靠产连贯中间表示",不证"它即合格终态"。产线化迁移见 plan `2026-06-18-001`(U1–U4);范式与终态硬约束见 `docs/architecture/架构/生成引擎/README.md` §3。 | -| **GamePackage** | 可运行的游戏包 = 代码 + 资源 assets + manifest;由 aigc 产出、runtime 编译打包上传 OSS。 | -| **Manifest**(GameManifest) | 游戏包描述文件,含 runtimeVersion/configUrl/入口 entry/assetList/hash/checksum/preloadPolicy/bundleSize;宿主据它加载资源与决定加载哪些 SDK Plugin。 | -| **GenerationTask** | 一次 AI 生成任务实体,记录 prompt/template_id/~~dify_workflow_id~~(Dify 已降级远期未部署,该字段为 1.x 蓝图残留;现行生成经 new-api 网关,详见 tech-decisions §1)/retry_count/duration_ms/error_code;状态机:queued→running→succeeded/failed/timed_out/canceled。 | -| **quality_score** | 基于玩家行为信号(完成率/30s 留存/点赞率/收藏率/举报率/失败率)聚合的游戏质量评分;由 telemetry 算出,反哺 feed 推荐排序。 | -| **Feed** | 游戏流推荐列表("像刷短视频一样发现游戏");MVP 用规则+行为信号排序,候选集存 Redis Sorted Set、TTL 60s、cursor 分页。 | -| **DAG** | 有向无环图,描述 AI 生成工作流的节点编排(解析→匹配→LLM→校验→资源→打包)。~~由 Dify 可视化编排~~(**2026-06-12 纠偏**:Dify 已降级远期、从未部署;**2026-06-15 HJ-AGI-002** 曾定 ~~SAA 裸图编排(short-term SAA-only,AgentScope 降 long-term premium 独立轨)~~;**2026-06-25 框架 reframe**:agentic 编排框架统一收敛 **AgentScope**(三档共用一个 agent 框架),SAA / dify / coze 降最低优先级、留作「远期适配验证可插拔」目标;「自研编排/DAG 工作流引擎」表述作废)。 | -| ~~**Game Skill**~~(OpenGame 概念,已退役) | ~~OpenGame 的经验积累机制,类似模板级 few-shot 模板,提升生成质量。~~ **2026-06-12 纠偏**:OpenGame 降级远期、从未部署(C2/HJ-GEN-001),本术语仅留作历史,勿作现行依赖。 | -| **WanxiangGameSDK** | 注入到每个生成游戏中的平台 SDK,是平台能力注入 iframe 沙箱游戏的**唯一通道**(无 SDK 则平台仅为静态托管)。 | -| **SDK Core** | SDK 核心层,内联到游戏入口、压缩后 < 8KB,含 Lifecycle/EventBus/Telemetry/ErrorTrack,必选;失败即静默丢弃,游戏零感知。 | -| **SDK Plugin** | SDK 插件层,按需懒加载、不影响首屏,含 Ad/Pay/Social/Storage/Debug;失败即跳过并给兜底(如广告失败免费发奖励)。 | -| **三容器策略** | 游戏流预加载机制(参考抖音):只保留前一/当前/后一三个 iframe 容器,当前播放时预加载下一款 Manifest+关键资源,超时自动跳过下一款。 | -| **保底曝光**(bonus_new_creator) | 新创作者前 3 个作品给固定基础曝光量,避免冷启动无人可见,是创作者激励的关键。 | -| **降权**(低质降权) | 高跳出/加载失败/高举报的内容自动下调推荐权重(error_rate 为硬降权;report_rate 达阈值触发人工审核)。 | -| **idempotency_key** | 幂等键,防止"重复点击生成/重复提交/MQ 重复消费/支付回调重复"导致重复处理(Redis 5min 去重 + 状态机 + 乐观锁)。 | -| **DataPermission** | Huijing 数据权限机制,实现行级数据隔离(如创作者只看自己的项目/资产)。 | -| **单体启动** | 13 个业务模块编译为同一 JAR(game-server),用 Spring Profile 控制模块加载;需独立扩缩时改 Nacos 配置即拆为独立微服务(Huijing Cloud 原生支持)。 | -| **契约先行**(contract-first) | Day 0 先锁定契约文件写入 `contracts/` 提交 git,各工位据此 mock 并行开发,联调延后至 Day 11。共 **8 类契约**:7 个 Day-0 `contracts/` 文件(API/DB/SDK/GamePackage/事件/~~Dify IO~~〔Dify 已降级远期未部署,见 `contracts/DEPRECATED-dify-workflow-io.md`〕/广告位)+ Prompt Registry(`contracts/prompts/`)为第 8 类。 | -| **门禁(7 道)** | 创作全链路 7 道质量/合规阻断点:①Prompt 安全 ②AI 产出合规 ③资产入库版权+风格 ④组装 Schema 完整性 ⑤编译后性能(≤10MB/首屏≤2MB/无外网) ⑥预览可玩性自测 ⑦发布终审(合规+适龄)。 | -| **Fallback 生成器**(确定性 Fallback) | LLM 不可用/超时/熔断时退化为确定性兜底产出,保证生成链路不全断。(~~"模板填充"~~ 措辞按 2026-06-12 模板哲学更新:游戏模板/填参线已废(W-CLEAN),兜底走固定可玩产物,非旧"模板填参"线;生成主线=agent 写码于插件库 HJ-GEN-001。注:玩法模板(品类框架·引导生成·非 pre-built 代码)未废待建。) | -| **Game SDK 降级铁律** | Plugin 层代码全部 try-catch 包裹、异常不向游戏抛;游戏主循环(requestAnimationFrame)永不被 SDK 阻塞——"游戏稳定性 > 数据完整性"。 | -| **WS1-WS5** | MVP 5 个工位:WS1 平台基座、WS2 AI 生成、WS3 运行时与分发、WS4 产品前端、WS5 数据与变现(详见 mvp-scope-and-milestones.md)。 | -| **M0-M5** | MVP 6 个里程碑:M0 契约锁定 / M1 全栈可启动 / M2 创作链路 / M3 分发链路 / M4 变现链路 / M5 MVP 交付。 | -| **三仓库** | game-cloud(后端 Huijing fork)/ game-admin(Vue3+Element Plus 管理后台)/ game-studio(Vue3+Vant 产品端),三个独立 Git 仓库。 | -| **game-module-{name}** | 游戏领域自研业务模块统一命名;13 个:studio/project/aigc/runtime/feed/telemetry/pay/trade/community/ip/compliance/biz/ad,按 `-api`/`-biz` 分层。 | -| **锁风门 Gate**(style-lock gate) | 发布前风格/版权/性能聚合检查门,owner=compliance(T-CMP-12);MVP 做 pass/block 二态,承载 demo"发布前检查通过才可发布",强度策略(标准/严格/人工)为远期。 | -| **专区 Zone(双轨)** | 广场/游戏流的双轨分区(现象级授权IP区 / UGC孵化IP区):Zone 实体与归属 owner=project(T-PRJ-07)、分区推荐 owner=feed(T-FED-15)、发布去向 launchZone 选择。 | -| **创作会话**(studio 会话) | studio 的有状态创作上下文(会话状态机+持久化 T-STU-01),承载草稿装配/六资产调度/任务链/附件,是 aigc 收敛后"有状态编排域"核心(区别于 aigc 无状态生成原子)。 | -| **资产图**(Asset Graph) | studio 的多资产组合关系模型(T-STU-02):描述图元/角色/特效/场景/界面/音乐六类资产如何组装成一款游戏;区别于"资产空间"(创作者素材仓库)。 | -| **三种创作模式** | 覆盖小白到专业:模式 A 一句话生成(Prompt→成品,AI 主导)、模式 B 资产驱动创作(先攒资产再组装,AI 辅助单项)、模式 C 工作流编排(专业创作者自定义编排节点)。(**2026-06-12 纠偏**:模式 C 原述「在 Dify 可视化自定义节点」中的 ~~Dify~~ 已降级远期未部署;**2026-06-25 框架 reframe**:编排框架统一收敛 **AgentScope**(三档共用一个 agent 框架),~~SAA 裸图 (HJ-AGI-002;SAA-only,AgentScope 降 premium)~~ 已被推翻、SAA / dify / coze 降最低优先级留作远期适配验证可插拔目标。) | -| **资产空间**(Asset Workspace) | 每个创作者独立、归其所有的素材空间,含视觉/音频/设计/商业化四类资产;每类资产支持 AI 生成、手动上传、市场获取三种产出方式。 | -| **DataPermission 之外的隔离** | 匿名玩家=**免登读路径**(读端点 `@PermitAll` + 前端 anonId 透传),只能浏览试玩、不能发布/收藏/进后台。⚠️ 2026-06-10 显式变更(鉴权拍板 §9-7=B):**不再走 framework 层"匿名 Token"机制**——anonId 为纯客户端生成、身份不可信,防伪造/刷量由 telemetry 聚合侧按 anonId/IP 异常剔除兜底(见 `docs/agent-specs/_archive/2026-06-10-真实鉴权与匿名玩家-review.md` §5A/§9.1)。 | -| **eCPM** | 每千次广告展示收益,是广告变现核心指标;平台用游戏内容标签 + 玩家画像优化 eCPM。 | -| **T+1(结算周期)** | 自有渠道广告分成次日(T+1)自动入账创作者钱包,外部渠道按月结算;满 5 元即可提现。 | -| **分成比例** | 广告收益按创作者层级分成:小白 80% / 进阶 75% / 专业 70%(投资人叙事统一口径"创作者拿 80%";D3 拍板 MVP 统一 80%)。**R3 叠加规则(2026-06-10 拍板)**:基数=平台从渠道实收**净额**(微信 IAA 渠道先扣 40%);使用 IP 素材时 IP 授权分成 15-25% **从创作者份额内扣**(创作者实得 55-65%);平台恒留净额 20%。模型见 `docs/mvp/单位经济敏感性模型.md`。 | -| **SLO / Error Budget** | 服务可用性目标与可消耗的不可用预算:游戏流 API 99.5%(月 3.6h)、AI 生成 99%(月 7.2h)、支付 99.9%(月 43min)。 | -| **最终一致性 + 补偿** | 跨模块写操作尽量不用分布式事务,改"本地事务 + MQ 事件 + 失败补偿",定时任务扫描超 5 分钟"中间态"记录重试或告警。 | -| **Golden Config 回归** | 用模板标准配置样例做比对回归,确保模型/模板迭代后生成质量不退化。 | -| **trace_id** | Gateway 入口注入、全链路透传(含生成侧 new-api 网关调用与运行时 SDK;~~Dify/OpenGame~~ 已降级远期未部署)的追踪 ID,是调试与可观测的主线。 | -| **DAU** | 日活跃用户;MVP 目标 1,000 DAU,正式目标 100,000 DAU。 | -| **分层运行时(Tier1/2/3)** | 游戏产物三层:Tier1 极轻量H5/2D(MVP 唯一交付层;**引擎=LittleJS 增强发行版,2026-06-12 终裁**+Runner v2;~~模板双层架构〔核心代码模板/玩法模板〕~~ → **模板=LittleJS 能力插件/二次开发件**(2026-06-12 模板哲学重申:游戏模板/填参式双层架构已废,玩法/美术/关卡/UI=agent 生成域,好玩基线 v2 改挂评估门;玩法模板(品类框架)未废待建);15KB 红线已废除、改三层约束框架,见 `docs/brainstorms/2026-06-11-tier1-runtime-constraints-requirements.md`);Tier2 复杂2D+3D / Tier3 独立App=Cocos Creator 3.8.8+MCP。**⚠️ 2026-06-21 纠错**:cocos-mcp 是编辑器扩展、需编辑器在跑、非 headless,Cocos 退出 tier2 自治生成轨、只留 3D/渠道导出轴;自治轨改 Phaser/Pixi(另见 tier2 词条)。详见 tech-decisions §1.1。 | -| **Cocos-MCP** | 用 MCP 协议(158 工具)让 AI 驱动 Cocos Creator 3.8.8 编辑器做复杂2D/3D/原生游戏;属有状态 agentic 编排、归 studio(区别于 aigc 的无状态单次文生代码原子;~~原对照"OpenGame"~~ 已降级远期未部署)。**⚠️ 2026-06-21 纠错**:cocos-mcp 是编辑器扩展、需编辑器在跑、非 headless,Cocos 因此退出 tier2 自治生成轨、只留 3D/渠道导出轴(编辑器+人在环);自治轨改 Phaser/Pixi。 | -| **Prompt Registry(Prompt 即契约)** | git `contracts/prompts/` 为全生命周期 prompt 的单一事实源(第 8 类契约):版本化 + 输入输出 Schema 绑定 + 约束块 + Golden 集 + owner,运行时按 `id@version` 加载注入、不内嵌引擎内核。 | -| **Prompt 轻量门禁** | prompt 改动 PR 触发的效果验证:Schema 通过率 + 生成成功率≥80% + Golden 回归 + 成本/延迟不劣化 + 人工抽检;可玩性靠行为指标反哺、不做结构化自动评分。 | -| **T-AGC-09 测试脚本生成** | aigc 的无状态原子:GameConfig→可玩性测试脚本,由 runtime 编译流水线执行为入库门禁。 | -| **tier2 / 自治富游戏引擎** | 三档里 AI 参与最深的一档:用一个能自治工作的 AI agent,造便宜档(轻量 AI 深度)做不出的多系统富游戏(合成/经营/挂机这类,对标《肥鹅美食街》)。同样高度模板化(玩法模板 + 工程骨架,非从零写),引擎=Phaser(按复杂度选,非分档轴);面向价值更高、产量更低的高质场景,per-gen 预算硬闸 <¥50(图/音另算)。产物是真 Phaser 多文件 `src/` 工程。**现状=0 号 spike 已 accept、核心已落**(见 `tier2/HANDOFF.md`;待办=更多款收敛环验证 + 阶段 1 Agent Team + 控制面接入)。框架 2026-06-25 reframe 后统一 AgentScope(三档共用)。tier2 富游戏设计已并入运行时真相 SoT,见 `生成引擎/agentic运行时架构图说.md`(§4.2/§5)。 | -| **控制面 / 管理面** | 让三档生成被配置、观测、审计、管起来的共用治理层(2026-06-25 reframe 后三档统一收敛 AgentScope、共用同一套治理面,不再「SAA 廉价线、tier2」两条异构基建分治):四个组件=配置注册表(prompt/model/skill/tool/mcp 的唯一事实源)+ 观测/审计仓(运行轨迹 + 配置审计)+ D12 运行治理门(配额/并发/背压/降级)+ 管理面 UI(注册表与观测仓的视图与编辑器)。内核=配置即数据、全链可观测。配置按性质分流:**非关键配置**(运营开关、非关键 agent 装配)经 `/agent` CRUD 或热取即时生效、不重新部署服务代码;**重要配置**(关键 agent、关键玩法模板、质量与安全阈值如 prompt 正文与生成门阈值)走 **yudao 配置发布审批**,是受治理的「发版」(提交→审批→通过才发布;复用 game-cloud 现成 bpm + infra 配置管理)。设计见运行时真相 SoT [`生成引擎/agentic运行时架构图说.md`](../../docs/architecture/架构/生成引擎/agentic运行时架构图说.md) §5.2。 | -| **源项目契约** | tier2 立项要新写的第一套工程契约,钉住真 Phaser 引擎工程怎么存、怎么取、怎么复现构建:源项目类型标记 + 文件树 manifest + 入口文件 + 构建 profile + 依赖锁 + 内容哈希 + 落库寻址 API。它是 tier2 自己的,**绝不复用 Tier0/1 的 ECS-lite 数据壳装载路**,两条装载路解耦并存。呼应「游戏=长生命周期结构化源项目、改源不改包、重新构建」的产品基座。详见 `tier2实现详设.md`。 | -| **统一 trace 契约** | 把多个异构框架 adapter 的运行轨迹收成同一张表的契约(落 `contracts/trace/`、additive 演进):AgentScope(ReAct) 为现行主 adapter,SAA 是远期适配进来时的另一个 adapter。一个公共核心子集(traceId/step/cost/verdict/timestamp)对称,各 adapter 独有字段进一个 JSON 扩展列(ReAct 放推理/动作/观察,SAA 放阶段/修复轮次/门裁)。口径=「每个 adapter 诚实镜像它真有的字段、没有的绝不编造」,不强求异构 adapter 字段对齐。 | -| **约束自治(O2)** | tier2 的生成范式,是「纯填充」(O1)与「纯自治」(O3)之间的折中:把一款游戏拆三层框住 agent 自由度——数据表(LLM 填值,约 19%)+ 系统骨架(平台预建可复用品类骨架,约 25%)+ 表现层(LLM 现写,约 56%)。骨架与插件 API 接管便宜模型最易崩的「发明系统结构并正确接线」,把火力集中到必须现写的 56% 表现层;再用四道熔断 + 一圈确定性验收门把自治关在笼子里。 | -| **Phaser / Pixi** | 复杂档(tier2 富游戏,AI 参与最深)选定的引擎。选 Phaser(近 4 万星、官方支持无头模式、esbuild 构建、有挂机经营先例)是从 AI 作者视角——生态厚=训练数据密=模型写得出、不易在自治循环里漂;过硬筛=全无头(纯代码/CLI 可建、不依赖图形编辑器)。Pixi 是 Web 2D 渲染事实标准、纯渲染层、当能力包加载。LittleJS 留给轻量 AI 深度档的小包游戏(富游戏零先例、训练语料稀,模型不会写)。引擎是按复杂度的实现变体、不是分档轴;分档轴是 AI 参与深度。 | -| **0号 spike** | tier2 的生死门:在最便宜的时候验整轨最深的赌注——**便宜/中等模型的自治 agent,能否在经营骨架/玩法模板/资产池/RAG/九门兜底这套约束下,稳定写出那 56% 的表现层、过确定性门**。靶子=砍到最小但保住「多系统耦合+重 UI+数值经济闭环」三难点的 mini-肥鹅;最小 AgentScope + 硬编码配置先验。**结果=已 accept、tier2 核心已落**(feie-005 decision=accept;门后续走 n=5 收敛环验证,不滑成无限调参)。runbook(靶子规格/模型矩阵/阈值/退路树)见 `tier2实现详设.md`,落地真相见 `tier2/HANDOFF.md`。 | diff --git a/.agents/knowledge/tech-decisions.md b/.agents/knowledge/tech-decisions.md deleted file mode 100644 index f799e0b5..00000000 --- a/.agents/knowledge/tech-decisions.md +++ /dev/null @@ -1,164 +0,0 @@ -# 技术决策事实蒸馏(ADR 风格) - -> 蒸馏来源:`docs/architecture/架构/README.md`(§6 决策记录、§6.6/6.7/6.8 工具链,最权威)、`docs/architecture/架构/13模块.md`(各模块技术栈/边界)、`docs/architecture/架构/README.md`、`docs/superpowers/specs/mvp-execution-spec-design.md`(执行约束)。 -> 目的:让后续 Agent 一篇掌握"为什么这么选、放弃了什么、风险在哪、哪些还没拍板、哪些源档互相打架"。 -> 相关:架构与模块见 [`product-and-architecture.md`](./product-and-architecture.md);范围里程碑见 [`mvp-scope-and-milestones.md`](./mvp-scope-and-milestones.md);术语见 [`glossary.md`](./glossary.md);红线约束见 [`../rules/security-and-reliability.md`](../rules/security-and-reliability.md)、[`../rules/engineering-conventions.md`](../rules/engineering-conventions.md)。 - -总原则(一句话):**用开源生态组合替代烧钱自研,钱与人力集中在竞品做不了的"游戏流分发 + 创作者变现闭环 + 数据驱动优化"。** 所有核心组件均开源/可替换,无单点供应商锁定。 - ---- - -## 1. 关键决策表(ADR) - -> **⚠️ 回填(2026-06-10,HJ-AUDIT-001;再回填 2026-06-12;三回填 2026-06-15 HJ-AGI-002)**:下表「AI 生成引擎」行已被取代两轮——~~C2 裁定后 MVP 主线=模板驱动(LLM 直出 GameConfig+固定模板)~~ → **现行主线=agent 写码于插件库**(HJ-GEN-001 终审 2026-06-12:游戏模板/填参线随 W-CLEAN 清除退役;**「玩法模板」(品类框架·引导生成·非 pre-built 代码)未废=有效·待建但非最高优先级(最高=Tier 0 生成可靠,玩法模板排其后;HJ-DEMO-AUDIT-001 创始人 06-17,见完成度与优先级总账)**;生产生成=便宜模型经 new-api+harness 门。**~~agentic 基建=SAA(Spring AI Alibaba v1.1.2.2)裸图编排 (HJ-AGI-002;short-term SAA-only,AgentScope 降 long-term premium 独立轨)~~ — 此「SAA-only / AgentScope 降 premium」结论已被 2026-06-25 框架 reframe 推翻(superseded):框架统一收敛 AgentScope(三档共用一个 agent 框架),SAA / dify / coze 降最低优先级、留作「远期适配验证可插拔」目标。HJ-AGI-002 当时确实在产、是历史事实,但其分轨口径不再现行。**)。Dify/OpenGame 均未部署、降级远期。§1.1 Tier1 行的「OpenGame 文生代码」同此。 -> **⚠️ 回填(2026-06-11,Tier1 重设计·创始人专门会话)**:下表「游戏运行时」行的 **Tier1「自研 Canvas<15KB」被二次质疑裁定取代**——自研壳实为机制演示(资产载而不绘/零 juice/只胜不败),手搓引擎=critical risk;**15KB 红线废除**(系 srcdoc 内联架构的衍生约束,前提已失效),改为三层约束框架(SLO 地板@千元机+4G P75 / 预算入场券 B1 gz≤350KB·raw≤1.5MB / 工程增强层 E1-E6),引擎=契约下可换的实现,**终裁待 LittleJS vs Phaser eval-spike**。单一事实源:`docs/brainstorms/2026-06-11-tier1-runtime-constraints-requirements.md` + `docs/agent-specs/_archive/2026-06-11-Tier1运行时重设计-review.md`。 - -| 决策点 | 选择 | 理由 | 放弃的备选(why-not) | 风险 | -|---|---|---|---|---| -| **后端框架** | Huijing Cloud(Java 17 + Spring Cloud Alibaba),fork 二开 | 60%+ 后台能力开箱即用(RBAC/OAuth2/BPM/文件/通知/审计/代码生成/多租户);社区活跃(60k+ star);单体启动可平滑拆微服务 | **NestJS(Node)**:v1 验证可行但缺企业级基础设施,微服务生态弱,后台/工作流要从零建;**Go(Kratos/go-zero)**:性能好但 RBAC/BPM/代码生成无现成方案 | 绑定 Huijing 升级节奏;须守"不改 framework 层"才可升级 | -| **AI 生成引擎** | ~~Dify(自部署,DAG 编排/多模型)+ OpenGame(Python 微服务,代码生成)+ Java 壳(任务调度)~~ **(本行 1.x 蓝图态,已 supersede——现行=new-api 网关直连便宜模型 + SAA(Spring AI Alibaba v1.1.2.2)裸图编排 (HJ-AGI-002);Dify/OpenGame 降级远期、从未部署,C2/HJ-GEN-001。本行仅留 why-not 决策史)** | Dify 可视化编排/多模型热切换/可观测开箱即用;OpenGame 为 CUHK MMLab 2025 SOTA、6 阶段 pipeline 论文验证、含 benchmark;组合 4-6 周跑通 vs 自研 6-12 月 | **纯自研**:6-12 月,时间不允许;**LangGraph**:纯 Python 无可视化 UI,运营无法参与编排;**Coze**:字节闭源不可控;**n8n**:通用自动化非 LLM 原生 | LLM 不稳定/幻觉(→Fallback 兜底);OpenGame 社区停更(→fork 自维护,可退化为纯 Dify+模板);Dify 升级不兼容(→锁版本+壳层隔离) | -| **前端** | Vue3 + Element Plus(game-admin)/ Vue3 + Vant(game-studio,移动优先适配 360-430px) | Element Plus 版是 Huijing 官方主推、社区最活跃、文档最全、二开友好度最高;Vant 适配游戏流滑动体验 | **React + Next.js**:与 Huijing 前端生态不一致,二开成本高(v1 用的就是 Next.js,v2 切 Vue3) | 两端两套组件库;C 端游戏流须独立 H5,admin 风格不适用 | -| **数据库** | MySQL 8.0 | Huijing 默认,社区方案最多,迁移成本最低;需 JSONB/全文检索时再加 PostgreSQL/ES | **PostgreSQL**:JSONB/全文检索更强但 Huijing 适配成本高 | 复杂检索能力弱,靠后续叠加 ES/PG 补 | -| **消息队列** | RocketMQ 5 | Huijing 默认集成;延迟消息/事务消息/死信队列完整,适合生成任务调度、审核通知、事件摄取、结算触发 | **Kafka**:偏大数据流、运维重,MVP 过度;**Redis Stream**:可靠性不足,无死信/事务消息 | 运维复杂度高于 Redis Stream,但生产更可靠 | -| **游戏运行时**(分层,见 §1.1) | Tier1 ~~自研轻量 Canvas Runtime(<15KB)~~ **→ LittleJS 增强发行版 + Runner v2(2026-06-12 终裁,15KB 红线废除,详见 §1.1)**;**Tier2/3 复杂2D·3D·原生 用 Cocos Creator 3.8.8 + MCP**〔⚠️ 2026-06-21 纠正:Cocos 仅留 3D/渠道导出轴(编辑器+人在环);自治富 2D 生成轨改 Phaser/Pixi,见 §1.1〕 | Tier1 首屏极快(P75<3s)、AI 生成纯 JS 直接可运行、平台完全控制沙箱;~~Tier2/3 用 Cocos 因 MCP(158工具)可 AI 驱动~~(该理由已被推翻:MCP 是编辑器扩展、非 headless,AI 无法无人值守驱动)、出功能快、一栈覆盖复杂2D+3D+原生/小游戏导出 | **Three.js**:仅 web3D、与 Cocos 重复(不选);**Phaser 3 全栈**:纯 2D、导出弱(~~否决~~ 该否决仅在 Tier1 轻量档冷启动维度;Phaser 是 tier2 自治富 2D 轨选定引擎,见 §1.1);**LayaAir**:无 MCP 生态、清单无快手(否决);**Unity**:AI 适配差、启动重(否决) | Cocos web 包体较重(MB级)→Tier2/3 不进游戏流、走渠道/App 分发;~~Tier1 仍自研薄壳保首屏~~(2026-06-11 回填:Tier1 改成品轻引擎+Runner v2,见 §1.1) | -| **多渠道导出** | **以"微信小游戏格式包"为统一中转**;Tier2/3 用 Cocos 官方一键导出,Tier1(LittleJS)渠道 adapter 走 W-CH-α 竞标(~~原「自研 Canvas 自做 adapter」随自研壳退役~~,见 §1.1) | 快手无专用导出接口,标准路径=导出微信包→快手开发者工具"微信格式兼容转换";抖音有自有导出接口;导出可异步离线、不影响实时预览 | LayaAir 官方平台清单无快手,不走 LayaAir CLI 路线 | DevTool import 仍需真机验证;三平台各自真机 | -| **AI 素材工具链** | **图片/音乐现行=mmx-cli(MiniMax,2026-06-12 创始人亲验拍板默认;agent 造游戏直接 CLI 调用,免 GPU/免训练)**;~~图片/角色/场景/封面→ComfyUI(自部署)~~ **ComfyUI 退备选**;~~音乐/音效→Stability Audio API~~;语音/音色→Fish Audio / 阿里 CosyVoice | (以下为 ComfyUI 备选时的理由,留作历史)ComfyUI 节点化、可训 IP 风格 LoRA 出系列一致素材、自部署无审查/无限频、长期成本低于商用 API;Fish/CosyVoice 中文效果最佳、支持 few-shot 音色克隆 | 直接调 **Midjourney/DALL-E API**:无法训风格 LoRA、游戏场景(武器/战斗)易被拒、按次付费贵 | ComfyUI 需 GPU(无 GPU 走 CPU 慢 10x 或 mock/外部 API) | -| **内容安全** | 图片→safe-content-ai(自部署快检)+ 阿里云内容安全(高风险兜底确认);文本/音频→阿里云审核 API;AI 输出→~~Dify Guardrails 节点~~ **(Dify 未部署已 moot;现行 Prompt 注入检测+输出 schema 校验落在生成侧门禁/Prompt Registry 门,见 [`skills/prompt-governance.md`](../skills/prompt-governance.md))** | 自部署做首道快检(免费/低延迟),高风险样本二次送阿里云确认;阿里云违禁词库持续更新、语义强于规则 | 单一商用 API:成本高且首道检测延迟大 | 双层链路一致性需治理;阈值(block 0.7 / review 0.4)须在 Nacos 调优 | - -补充选型(同源 §7 治理章,非主决策但已定):Nacos(注册+配置中心,Huijing 原生)、Redis 7(候选集缓存/限流/排行/熔断/分布式锁/幂等去重)、MinIO 本地·阿里云 OSS 生产(对象存储+CDN)、Flowable/BPM(审核/发布/下架流程)、Prometheus+Grafana+Sentry+Jaeger(可观测)、Flyway(DB 迁移)、Sentinel(熔断降级)、穿山甲+优量汇(广告,覆盖 80%+ 国内移动广告市场)、ClickHouse(远期,事件量爆增后从 MySQL 迁移)。 - -存储分层口径(技术决策版 §5.2,"先简后扩"):业务实体→MySQL 8.0;游戏包/素材/封面→MinIO/OSS;推荐候选集/热数据→Redis Sorted Set;事件流→MySQL 分区表(MVP)→ClickHouse(增长期);搜索→MySQL FULLTEXT(MVP)→Elasticsearch(增长期)。 - -### 1.1 分层运行时设计 - -> **⚠️ 引擎口径已更新(2026-06-21 · tier2 触发)**:tier2 自治富游戏生成轨的引擎定为 **Phaser/Pixi(全无头·纯代码)**、agent 框架定为 **AgentScope(Python·独立 service·自治 ReAct)**,Cocos 仅留 **3D/渠道导出轴(编辑器+人在环)**——下表与本 §1.1 凡写「Tier2/3=Cocos+MCP 锁定」「MCP 158 工具可 AI 驱动」「Phaser 否决/落选」处,均按此口径理解,详见本节末 §1.1 supersession 横幅与 tier2 富游戏设计(已并入运行时 SoT `docs/architecture/架构/生成引擎/agentic运行时架构图说.md` §4.2/§5)。**这同时澄清了 §1/§2/§4 里"AgentScope 降 long-term premium 独立轨"的旧口径**:AgentScope 不再只是悬置的远期备选,而是 tier2 富游戏线现行选定的 agent 框架(tier2 核心已落、0 号 spike 已 accept,见 §4 与运行时 SoT `生成引擎/agentic运行时架构图说.md` §4.2/§5)。**进一步:2026-06-25 框架 reframe 已把这层澄清推到底——三档统一收敛 AgentScope(不再「廉价线 SAA-only、tier2 AgentScope」两套基建并存),SAA / dify / coze 整体降最低优先级、留作「远期适配验证可插拔」目标。** 下表保留决策史、只加纠正标注,不删。 - -游戏产物分三层,对应不同运行时:**Tier1 = LittleJS 增强发行版 + Runner v2(agent 写码于插件库生成,HJ-GEN-001;~~原「自研 Canvas + OpenGame 生成」已废除~~,见下表);Tier2/3 统一用 Cocos Creator 3.8.8 + MCP。**(术语澄清:废的是游戏模板/填参线(W-CLEAN),「玩法模板」(品类框架)未废、待建。) MVP 仅交付 Tier1;非目标保持收敛(Tier2/3 仅远期探针,见 §7)。 - -| 层 | 定位 | 选型 | 生成路径 | 状态 | -|---|---|---|---|---| -| **Tier1 极轻量H5/2D** | 游戏流即点即玩,首屏 P75<3s + 点卡→可玩 S2(常态≤2s) | ~~自研轻量 Canvas Runtime(<15KB)~~ → **LittleJS + Runner v2(2026-06-12 创始人终裁,spike 85/82:冷开 0.54s vs 2.86s=4.8~5.3×/引擎 15.9KB gz/敏感性分析裁量分拉平 S2 硬差仍定向,终裁包 `docs/agent-specs/_archive/2026-06-11-T1引擎终裁包.md`)**:引擎 URL 化交付享 HTTP+编译双缓存;~~模板双层架构~~ → **模板=LittleJS 能力插件/二次开发件**(2026-06-12 模板哲学重申:游戏模板/填参线废,玩法/美术/关卡/UI=agent 生成域(玩法模板=品类框架·未废·待建),好玩基线 v2 改挂评估门;**裁决①(2026-06-12):粒子/物理/后处理插件=引擎能力包装层,禁在受控面墙内平行重造引擎内建能力,β 设引擎真接线门;Q4 补裁(2026-06-13):「自研内容是引擎外的层,不是对引擎本体的替代」——「有意替代」豁免关闭,自研仅限包装层/引擎缺件补层,确定性取证诉求在 harness/门侧解决(手搓 Canvas2D 零实测证据优于引擎内建,且自揽平台渲染差异债)**);iframe 沙箱 + SDK 注入不变 | ~~LLM 填参~~ → **agent 写码于插件库**(HJ-GEN-001 终审;旧填参线随模板废除退役;美术/音乐=mmx 优先,2026-06-12 拍) | ✅ W-T1b 主门过(拔高样板「暖阳小卖部」2026-06-12 创始人亲玩判 passed),**MVP 唯一交付层**。真护城河=沙箱/SDK/契约/三容器(全保留);存量 1.x 双轨冻结;引擎复议权=拔高暴露引擎级阻塞(终裁包 §4.5-3) | -| **Tier2 复杂2D+3D** | 中重度含 3D,渠道分发 | **Cocos Creator 3.8.8 + MCP**(备选 PlayCanvas)〔⚠️ 2026-06-21 纠正:此「锁定」仅指 3D/渠道导出轴,Cocos 用编辑器+人在环;自治富 2D 生成轨改 Phaser/Pixi〕 | **Cocos-MCP** agentic 工具编排(studio 编排) | ✅ 锁定(限 3D/渠道导出轴)。~~MCP 158 工具可 AI 驱动~~ 系事实错——该 MCP 是 Cocos 编辑器扩展、需编辑器在跑、非 headless,故进不了无人值守自治生成 loop;MVP 至多 1 个探针 demo | -| **Tier3 独立App** | 打包为原生应用 | **Cocos 原生导出**(同 Tier2 引擎) | 同 Tier2 + 打包 | ✅ 锁定引擎。否决 Unity(AI 适配差、启动重);MVP 后投入 | - -**自研工期评估(为什么 Tier2/3 复用 Cocos 而非自研)**:Tier1 薄壳约 0.5–1.5 人月(可行,且必须自研以控沙箱/SDK/三容器预加载);自研 3D 引擎数十人月~数年、自研原生框架数十人月——3 周窗口下绝不可行,必须复用成熟引擎。选 Cocos 因其一栈覆盖复杂2D+3D+原生/小游戏导出,~~且 MCP(158工具)使 AI 驱动可行~~(**2026-06-21 纠正:该 MCP 是编辑器扩展、非 headless,无法无人值守驱动;Cocos 此处仅指 3D/渠道导出轴的人在环作者,自治富 2D 生成轨改 Phaser/Pixi**)(与"开源组合替代烧钱自研"总原则一致)。**(2026-06-11 回填:「必须自研以控沙箱/SDK」已被推翻——控制点在沙箱/SDK/契约层,与渲染引擎解耦;Tier1 渲染层亦改复用成品轻引擎,自研壳退役,见 §1.1 表)** - -**导出枢纽 = 微信小游戏格式包**:微信=引擎导出官方格式;抖音=自有导出接口;**快手=无专用接口,走"微信格式兼容转换"**(快手开发者工具)。**LayaAir 官方平台清单无快手**,不走 LayaAir CLI 路线。Tier2/3 用 Cocos 官方一键导出微信包;Tier1(LittleJS)渠道 adapter 走 W-CH-α 对比竞标(LittleJS+自研 adapter vs Cocos 导出,HJ-CH-001 §4;~~「Tier1 自研 Canvas 自做 adapter」随自研壳退役~~)。 - -> 选型依据:Cocos 3.8.8/MIT 一栈覆盖2D/3D/原生导出,故 **3D/原生/渠道导出轴** 选 Cocos;Three.js r184/MIT/113k★ 仅 web3D、与 Cocos 重复故不选;LayaAir 2.1k★、无 AI/MCP 生态、清单无快手(否决);Unity 启动 7-10s×2-3 与 P75<3s 冲突(否决)。 -> **⚠️ supersession + 纠错(2026-06-21 · tier2 触发)**:上句原作"headless MCP(158 工具) 使 AI 驱动可行"**是事实错**——Cocos 的 MCP 是**编辑器扩展、需 Cocos Creator 在跑、非 headless**(取证级核实),故 Cocos **进不了 tier2 全自治生成 loop**。引擎重定为正交两轴:**自治生成轨(全无头:富 2D=Phaser/Pixi、轻量档=LittleJS)** vs **3D/渠道导出轴(Cocos,编辑器+人在环)**;Phaser 的"spike 落选"只在 Tier1 轻量档冷启动维度、与 headless 自治维度正交。本表其余 Tier2/3=Cocos / Phaser 否决 行均按此口径理解。详见 tier2 富游戏设计(并入运行时 SoT `docs/architecture/架构/生成引擎/agentic运行时架构图说.md` §4.2/§5,引擎选型)。 - ---- - -### 1.2 A11 调整回路(试玩后纠错 · 切片三 2026-06-29) - -用户试玩生成的游戏后用自然语言提调整,这条回路在便宜档线落地。架构 = **A 两段式**:判意图(`/modify/plan` 收原话 → 便宜档 worker 取 base 源 + 一次轻 LLM 把自然语言分类成 `mode/target/payload` + 风险)与执行(用户确认后调已结构化的 `/modify`)分离成两次请求,HITL 走前端在两次调用之间的确认——绕开"自然语言进不了已结构化的执行入口"与"危险回问做成任务内暂停态却撞上内部状态机无暂停态"两道阻断(A2A 原生 input-required 暂停态留后期)。可改性的根基是生成侧**工程规范性**:资产统一在 `assets.js`、数值集中在 `core.js`,使一次修改落到"那一处",这是生成质量、不是给调整加静态门(判意图仍 LLM 驱动)。执行分两档:确定性类(换资产 / 调数值,改一处、零 LLM)+ 模块重生成(改玩法,有界单文件重写、复用续跑与三层校验)。验收 = 九门 + 三层校验 + **三断言**(改动真生效非 no-op / 非目标模块字节稳定[改前改后真比对、不信执行器自报] / 新版本血缘可查)。 - -**现状**:便宜档代码完成、本机逐段一手真验(真九门、真 LLM 重写、断言集成 smoke);受计费真后端 e2e 排部署窗口(创始人 2026-06-29 定不动 live);复杂档随 tier2 跟进。关键收敛:A11 后端骨架(契约 / `/modify` 编排 / `game_source_project` 血缘 / D12 配额)已大面积落地,真活在便宜档接入 + 判意图/执行/三断言。设计面 SoT = 运行时 SoT [`生成引擎/agentic运行时架构图说.md`](../../docs/architecture/架构/生成引擎/agentic运行时架构图说.md) **§六**;执行留痕 = [`docs/plans/2026-06-28-003-feat-studio-A11-对话式调整回路-plan.md`](../../docs/plans/2026-06-28-003-feat-studio-A11-对话式调整回路-plan.md)。 - ---- - -## 2. 这些选型如何服务护城河(为什么"够用即可") - -投资人版与技术决策版口径一致:**技术深度不追第一,生态完整度追第一。** 生成能力会被通用大模型 12-18 个月追平,故选型刻意"够用、可替换、低成本",把自研投入压在竞品的空白——游戏流分发与变现闭环。真正壁垒:① 游戏流推荐数据壁垒(真实流量积累,无法购买)② 生成质量反馈闭环(玩家数据→quality_score→优化建议→创作者迭代)③ 模板/素材/工作流资产沉淀(马太效应)④ 广告位 AI 优化(提升 eCPM)。对应的工程取舍:自研只做 feed/telemetry/SDK/变现链路/**发行版包装层与契约**(~~runtime~~ 出列:渲染循环=LittleJS,自研面只剩引擎能力包装与插件协议——2026-06-12 审计 R5 纠正「护城河预划过粗给自研免检光环」;agentic 编排自研只剩护城河件——checkpoint + 验收门;框架本身(2026-06-25 reframe 后三档统一收敛 AgentScope,SAA / dify / coze 降最低优先级、留作远期适配验证可插拔目标)采主流标准对接、不自研),其余(后台、工作流、生成、素材、安全)全用开源/商用组合。**Build-vs-Buy 硬门=[`.agents/rules/build-vs-buy.md`](../rules/build-vs-buy.md)。** - ---- - -## 3. 待确认项(源档明确标注未拍板,勿当既定事实) - -来源:架构选型审阅版 §11 + 技术决策版 §1.2 指标口径。后续若已敲定,应回填本表并注明决策时间。 - -| # | 待确认项 | 候选 | 出处 | -|---|---|---|---| -| 1 | ~~MVP 首选 LLM~~ → **已拍板**(D1,2026-06-08):主 DeepSeek + 备 Qwen,不接 OpenAI;**现行实际 = new-api 网关多模型可用**(2026-06-14 网关探活实测:`deepseek-v4-flash`/`deepseek-v4-pro` + `MiniMax-M2.7`/`M3` 渠道全活;W-G1 L1 冒烟用 `deepseek-v4-flash` 打底、`pro` 升难档——原「DeepSeek key 未激活」已过时) | — | `2026-06-08-mvp业务决策.md` D1 | -| 2 | v1 运行时资产移植方式 | Canvas2D 渲染 + 小游戏转换逻辑:移植为 Java 服务,还是保留 Node 微服务 | 选型审阅版 §11.2 | -| 3 | 产品端域名方案 | game-studio 与 game-admin 同域不同路径,还是不同子域名 | 选型审阅版 §11.3 | -| 4 | ~~MVP 登录方式~~ → **已拍板**(2026-06-10 七项全拍,见 `2026-06-10-真实鉴权与匿名玩家-review.md` §9.1):**C 验证码为主+邀请码旁路**、玩家开放注册(受限期凭邀请码)、创作/发布限 A2 白名单、互动即弹一键登录、实名提现前收、匿名=纯客户端 anonId+聚合侧剔除(glossary/contracts 已同步修订);待出 execution 版排建设(建议 M-b 后) | — | 鉴权评审版 §9.1 | -| 5 | Tier3 独立App 运行时引擎 | **Cocos Creator 3.8.8 + MCP 统一 Tier2/3(见 §1.1)** | 运行时选型研究 | -| 6 | ~~MVP 模板集不一致(R4)~~ → **已拍板**(2026-06-10 创始人复审):**维持 D2 集合,按 D2 改建**——M-c 建 idle/tycoon/merge runtime(clicker 保留,顺序建议 merge→idle→tycoon);dodge/runner/match schema 降 P1 保留契约不删。回填见 `2026-06-08-mvp业务决策.md` D2 复审注 | — | HJ-AUDIT-001 R4 + mvp业务决策 D2 | - ---- - -## 4. 关键口径(落地前以此为准) - -> 多份源档由不同子代理产出,下列口径已统一裁定,落地一律以本表权威单值为准。整体原则:**蓝图/选型以技术决策版(HJ-ARCH-001)为准,执行/排期以 mvp-execution-spec(HJ-MVP-SPEC-001)为准。** 投资人版(HJ-ARCH-002)仅作对外叙事,不作技术依据。 - -| 口径点 | 权威结论 | -|---|---| -| **运行时技术栈** | Tier1=**LittleJS(2026-06-12 终裁)**+Runner v2(原自研<15KB 壳退役、存量 1.x 冻结);Tier2/3=Cocos Creator 3.8.8+MCP〔⚠️ 2026-06-21 纠正:Cocos 仅留 3D/渠道导出轴,自治生成轨=Phaser/Pixi〕(见 §1.1)。Three.js/LayaAir/Unity 仍否决;Phaser 经 spike 竞标落选(该落选只在 Tier1 轻量档冷启动维度;Phaser 是 tier2 自治轨选定引擎——败于冷开/交付形态,工程质量合格,证据留 spike 目录) | -| **生成成功率指标** | MVP 验收按 **≥80%** 判定;**≥85%** 为远期蓝图目标,勿用 85% 卡 MVP | -| **时间线** | 双路线并存:投资人版 5 人/11 周、执行 spec 10 人/3 周;执行排期以 mvp-execution-spec 为准(含逐日计划与里程碑) | -| **MVP 范围/口径** | MVP 验收以 Doc A 的 **55 项 P0 产品功能**为准;技术实现范围经 Doc C 反查 Doc B(工作量 ≈137 技术项)。详见 [`mvp-scope-and-milestones.md`](./mvp-scope-and-milestones.md) §3 | -| **模块划分** | **13 模块**(含 game-module-studio 创作编排域,aigc 为无状态生成原子);能力清单拆为产品功能(Doc A)/技术功能(Doc B)/映射(Doc C) 三文档分离 | -| **生成主线(三档统一 AgentScope、SAA 最低优先级远期适配)** | ~~MVP=模板驱动(LLM 直出 GameConfig+固定模板)~~ → ~~现行是两条并存的生成线~~ → **2026-06-25 框架 reframe:框架统一收敛 AgentScope(三档共用一个 agent 框架),SAA / dify / coze 降最低优先级、留作「远期适配验证可插拔」目标**。三档按 **AI 参与深度**(Tier0/1/2)切分、全部高度模板化(玩法模板 + 工程骨架,不是从零写),引擎是按复杂度的实现变体(轻-中=LittleJS、最高=Phaser),**引擎不是分档轴**。**便宜档**:agent 写真 `src/`(HJ-GEN-001 终审 2026-06-12,旧游戏模板/填参线随 W-CLEAN 退役〔M-b 执行器写链语义保留复用〕),便宜模型经 new-api + harness 九门,引擎=LittleJS;gameDefinition 已废、A-model 写真 src/ 现行(无 factory/gamedef 双轨、无 cutover);per-gen 预算硬闸 <¥10(图/音另算)。已实证地板(W-G1 L1 worker + 九门真玩 + 3 款冒烟,¥0.01–0.03<¥0.15 闸;全 20 款 bake-off + 四模型横比 + Claude-free judge 门待跑,配方见 [`skills/cheap-model-game-generation.md`](../skills/cheap-model-game-generation.md))。**复杂档(tier2 富游戏)**:自治 ReAct agent 用 **AgentScope + Phaser** 造多系统富游戏(合成/经营/挂机这类,对标肥鹅美食街),产物=真 Phaser `src/` 源工程,三层校验兜底;per-gen 预算硬闸 <¥50(图/音另算)。**现状=0 号 spike 已 accept、核心已落**(见运行时 SoT `生成引擎/agentic运行时架构图说.md` §4.2/§5 与 `tier2/HANDOFF.md`)。运行时单一真相 SoT = [`生成引擎/agentic运行时架构图说.md`](../../docs/architecture/架构/生成引擎/agentic运行时架构图说.md)(§5.2 控制面 / §5.7 成本)。Dify/OpenGame=远期增强未部署 | - -### 4.1 生产质量三层 reframe(创始人亲玩校准锁定,2026-06-14·WG1 review §8) - -W-G1 实证后创始人亲玩校准拍定:**生产环无 Claude**,质量由**三层**兜底,各司其职、不可互相替代—— - -| 层 | 是什么 | 能判 / 判不出 | -|---|---|---| -| **① 确定性门**(地板/可玩性真值,Claude-free) | 九门(A–G 假绿守卫 + H 机制/latch + I 控制手感)+ 适配性真玩 driver(读 state 接球,解盲打假阴性)。手感**尽量拆成确定性门**(latch 终态驻留 / 控制跟手 / 碰撞穿透[门 J 规划]) | 能判:能跑/真接线/有进展/真结束/跟手。拆得掉的全自动判 | -| **② 便宜 player**(主观层,消费 gate-H) | M3 静态截图 + flash 运行数据,判**拆不掉的主观**好玩/美术/节奏;须人锚校准(`calibrate.py` vs 创始人 `labels.json`) | **判不出物理/碰撞/控制的交互手感**——实证把碰撞有问题的件高估为最佳(两 player 均 fun=4,text 漏控制 bug)。**有结构性天花板** | -| **③ 创始人抽检**(人锚,现阶段不可替代) | gate-H 盲打假阴性 + player 漂移的最终纠偏 | 没有它会把碰撞有问题的件当"最佳"发出去 | - -- **"上下文是杠杆"实证**:同 flash 仅改接地(grounding)→ 成本 **−50%**、修复轮次 **−80%**;player rubric 锚定(1-5 分级 + 空心→≤2)把 player MAE **1.25→0.75**。结论 = 工程沉淀在 **agent harness**(任务协议/状态模型/门禁/judge 校准),单次生成是消耗品(harness 复利)。 -- **Opus 定位**:builder / teacher / calibrator——**建好即退,不进生产环**(否则"生产无 Claude"前提破);SAA 框架藏在 job/callback 契约#6 后保持可替换。 - ---- - -## 5. 关键技术风险与降级(技术决策版 §8,决策落地必读) - -每条决策都自带风险与"降级方案"——这是"够用即可、可替换"原则在工程上的兜底。摘录高/极高影响项: - -> ⚠️ 下表「LLM 调用不稳定」行的"Dify 重试+熔断"与「OpenGame 社区停更」整行为 1.x 蓝图态:Dify/OpenGame 降级远期、从未部署(C2/HJ-GEN-001),其应对/降级机制已 moot;现行 LLM 不稳定应对=new-api 网关多模型切换 + harness 门兜底,"模板填充"措辞同 §4 已废(填参式游戏模板已废 W-CLEAN)。 - -| 风险 | 概率/影响 | 应对 | 降级方案 | -|---|---|---|---| -| LLM 调用不稳定(超时/限流/幻觉) | 高/高 | Dify 重试+熔断;多供应商切换 | 确定性 Fallback 生成器(退化为模板填充) | -| 生成游戏质量不可控 | 高/高 | JSON Schema 强校验 + 可玩性自动测试 + 模板约束 | 质量不达标不入库 | -| 游戏沙箱逃逸 | 低/极高 | CSP + iframe sandbox + 无网络 + postMessage 校验 | 检测异常立即销毁 iframe | -| OpenGame 社区停更 | 中/中 | fork 维护,核心 pipeline 简单可自维护 | 退化为纯 Dify + 模板生成 | -| 广告联盟审核不通过 | 中/高 | 提前申请资质 + 内容合规前置 | 延迟广告上线,先做订阅/B 端(或先用 mock 广告) | -| MQ 重复消费致数据不一致 | 中/高 | 消息幂等消费(message_id + Redis 去重) | 定时任务修复 + 告警 | -| 第三方 SDK 数据泄露 | 低/极高 | 广告/支付 SDK 宿主侧隔离 + 最小权限 | 紧急下线第三方 SDK | - -### 5.1 便宜档私有方言对模型有量化成本(2026-06-28 对照实验,evidence 见 agent-specs) - -便宜档让模型直接写一套私有运行时方言(L1/L2/L3 三层骨架 + `createGame` 五法 + `_forensicsView` 契约 + `ctx` 受控面 + 输入收归 L1 + 几十条红线)。母语 vs 方言对照实验(同 brief 点击得分、同模型 MiniMax-M3、各 n=5、用契约无关的 fair-verdict 五信号判据)实测:M3 在母语(标准 Canvas/rAF/addEventListener)下 **5/5 一次成型、3 步、约 14K 输入 token、约 55s**;在现状方言下产同一个能玩的游戏要 **约 26 倍 token、3–9 倍时间**,还出现母语从未有的失败模式(一局磨满 20 分钟未收敛、反复撞静态检查返工、按错路径读插件)。结论:之前记在"M3 弱"头上的低良率/高成本,**很大一部分是方言强加的税,不是模型天花板**(M3 不弱)。 - -⚠️ **方向修正(2026-06-29 创始人纠正,推翻"换母语"初判)**:便宜档按 SoT 定位是"AI 参与深度低的高质游戏"(轻量≠简单,见运行时 SoT §一/§4.1),**不是简单玩具**;L2 插件库是"降 AI 参与=便宜+高质"的核心载体、**不是"税"**。"换母语扔插件"会让 AI 从头写整个游戏 = **升** AI 参与,与便宜档"降 AI 参与"的核心策略正相反,故推翻。本实验测的点击得分恰是产品不做的简单玩具、对象本身无产品意义——它留下的真发现是:**当前 AI 在方言里写 game-logic.js 时,学插件 API 形状的摩擦极大(drawButton 当返按钮对象、define 想批量都是按母语直觉猜错;9 步 358K),"降 AI 参与"的设计意图没兑现**。修正方向(创始人方向 3,分阶段)= ① 保留插件库,让**插件 API 向模型母语直觉对齐**(drawButton 真返按钮对象、define 批量,消除"按直觉写就错"的坑)+ RAG/few-shot/skill 补 API 密度,把学习摩擦降到接近母语;② 扩玩法模板与工程脚手架覆盖,缩小 AI 自由写的面。地基(确定性受控面 + 九门)仍是护城河。详见 [`../../docs/agent-specs/2026-06-28-母语vs方言-生成对照实验-evidence.md`](../../docs/agent-specs/2026-06-28-母语vs方言-生成对照实验-evidence.md),它给 [`../../docs/agent-specs/2026-06-20-生成设计合理性-对抗审查裁决.md`](../../docs/agent-specs/2026-06-20-生成设计合理性-对抗审查裁决.md) 的"表现力硬编码"补量化证据。 - -✅ **落地(2026-06-29 阶段一B 改签名)**:方向①「插件 API 向母语直觉对齐」已全部完成——附 A 15 处可改签名 #1-#15 逐插件改逐插件验:drawButton 返命中矩形(#5,治"误把 void 当返回值"#1 翻车点根因)、sessionScore.add / juice.burst / gamefeel 工厂(免 new)、collision·physics 几何挂实例、Aabb 兼收 {x,y,w,h}(#12)、**ctx.random()·ctx.time() 可调用 + 保留方法双 API**(#1,单点 buildContext 包装、框架内部不破)、audioMusic 语义音名、timer·scene·juice.render doc 钉死。另修一个正交真 bug:check 的 API 静态门方法名正则漏认泛型声明 `get(`、把真实存在的 `save.get` 误判不存在、误杀一整类带存档游戏(`851b86fe`)。`2a20e5e7`→`2be7b718` 共 13 提交,每处单元+确定性验、各插件测试绿、双源 prompt 一致、形状门 11/11 不破。**减摩擦端到端见效**:改签名前栽在 save.get 泛型门 bug 的打地鼠+高分游戏(2 attempts/¥6.69/失败),改后**一次过九门、¥0.64/209s、不 thrash**。剩:方向①的补密度(阶段一C few-shot/RAG)+ 方向②扩模板(数据点门控)。详见 [`../../docs/agent-specs/2026-06-29-便宜档降AI参与-减摩擦与扩模板覆盖-设计.md`](../../docs/agent-specs/2026-06-29-便宜档降AI参与-减摩擦与扩模板覆盖-设计.md)。 - -✅ **方向②扩模板 数据点(2026-06-29,难品类经营,修正了假设)**:建经营黄金骨架 `game-runtime/games/_template-shop/`(蒸馏过门的 bake-shop-serve 实证 pattern + 母语化 API + 多样性参数空间 + fill-in 标记,独立过九门)+ 品类路由接入(`scaffold-saa [template]` / `cheap_run.scaffold(template)` / `run_studio(scaffold_template, scaffold_desc)`,缺省回落 _template)。同一咖啡馆 brief 三路对照(n=1):**软脚手架**(给骨架 + 软提示)892 行/¥0.85——AI 把预算填进增富化(自加 combo+VIP)、对 ~890 行基线三指标全平**没降**;**强制换皮**(write_whitelist 锁 game-logic.js、只许改 core 主题数值+render 观感)696 行(-22%)/¥0.34(-51%)/tokens-64%,game-logic **0-diff**、仍过门仍 distinct。**结论:"扩模板降工作面"成立但只在"强制换皮"模式**(脚手架+锁循环只换皮)——降本杠杆不是脚手架本身、是写边界强制;软脚手架买的是质量/过门鲁棒(增富化)、不买成本。取舍:强制换皮省成本但封顶增富化,软脚手架反之。**n=5 收敛环确认(经营,5 个不同店主题 奶茶/书店/花店/拉面/冰淇淋):5/5 全过九门 · 成本均 ¥0.252(-64% vs 基线)· game-logic 全 0-diff · 全 1 轮 · 5 店菜单互异——成本腰斩稳 / 过门 100% / 多款不雷同 三件全确认**。🔴 **创始人纠正(2026-06-29,推翻 reskin 策略框)**:上面 reskin 的成本数据作留痕(锁写省成本机制为真),但**「reskin 锁循环只换皮作阶段二成本主线」= 错、越线、已废**。① **便宜 = LLM 低参与度,不是游戏低质量**;底线 = 2D 丰富游戏(进货/解锁/成长/音乐/丰富玩法),reskin 砍复杂度违背底线;"低参与" = agent 不在引擎/plumbing 上耗(脚手架+插件包了)、精力放游戏设计。② **架构红线:项目代码只做机械确定性的事;玩法/美术/音乐的「丰富生成」= 生成 agent 设计创作职责(靠 [sim-business-game-design](../skills/sim-business-game-design.md) + 组合插件),「丰富校验」= 纯 LLM 验证 agent 非阻塞——绝不写成代码校验、不进九门、不进脚手架**。故"丰富脚手架/脚手架好玩门断言"也废。**修正后下一步**:接 sim-business 设计指导到生成 agent(现 prompt 漏)+ 建 LLM 丰富度验证 agent → 喂 M1 达标门(标=过九门+丰富);脚手架保持轻起点。 - -✅ **切片一收口落地(2026-06-30,上面"修正后下一步"全部交付并验证)**:生成 agent 接上 sim-business 设计指导(`cheap_roles.py` + `prompt.mjs` 双源,"先设计后写码"步 + MVP-first 铁律 + 8 条好玩自检);新建纯 LLM 丰富度验证 agent `cheap_verify.py`——读产物源码逐条裁 8 条好玩清单、写进 run-summary 的 richness 字段,**非阻塞(失败降级不阻断)、不进 verdict、不改达标判定、零 code-presence 断言**(命中与否 100% 由 LLM judge 裁,代码只搬运计数——红线落地;sim-business §10 那 4 条"可机检好玩门"刻意不实现)。富游戏重验 M1 达标门(全新 gameId、三品类各 n=5):**click/whack/shop 各 5/5 = 100% 过九门、整体达标 ✅**——richness 加固没压垮达标,plan 担心的"丰富后跌破"未发生;richness 均分 shop 4.2 / click 3.4 / whack 2.4(8 条 rubric 偏经营,最贴 shop,whack 低是品类不匹配非质量差)。退役授权据新富游戏 M1 报告重算 `authorized=True`。基建线同轮交付:统一 trace 落库(tier2 `JsonlFileSink` + cheap-worker 接线 + SAA 扩展段 schema)、配置注册表运行时热取(cheap_roles 三级回落加载器、Java `@Scheduled` TTL、`check_registry.py` 一致性 CI 门)、生成控制面只读管理面(后端 3 端点 + game-admin Vue 三 card)。**两个测试坑(留给后来人)**:① bake-off 复跑同一 gameId 会复用 `_wg1-gen//play-spec.json` 旧 spec(`ensure_play_spec` 是"已存在不覆盖"语义)——旧薄游戏 spec 驱新富游戏会假失败(自动驱动器卡菜单 `phaseNow=menu`、score 0→0、E_live/G_input/H_progress 齐挂),`auto_vs_golden.py` 有 staged-spec 残留断言守卫而 `bake_off.py` 没有,故达标门复验务必 `--offset` 取全新 gameId(或先清 `_wg1-gen` 实验 staging);② `cheap_run.game_dir("base4")=games/amgen-base4` 是 load_brief 的 brief 来源依赖,清理 `amgen-*` 实验产物时**必须排除 `amgen-base*`**,否则断掉所有品类的 bake-off brief。 - -## 6. 决策落地的关键工程参数(供选型校验,技术决策版 §4/§7) - -- **AI 生成**:生成任务状态机 queued→running→succeeded/failed/timed_out/canceled;超时 120s;失败重试 ≤2 次、超时重试 ≤1 次;队列最大积压 500(超则返回 429);P50<60s、P95<180s。 -- **运行时沙箱**(安全铁律):iframe `sandbox="allow-scripts allow-same-origin"` + CSP `script-src 'self'; connect-src 'none'`(游戏内零网络请求)+ postMessage 来源与 schema 双校验;资源总 ≤10MB、首屏 ≤2MB;加载超时 5s 自动跳过+降权。 -- **推荐打分**(规则非 ML):`Score = w1·quality_score + w2·freshness + w3·interaction_rate − w4·skip_rate − w5·error_rate − w6·report_rate + bonus_new_creator + bonus_featured`;候选集 Redis Sorted Set、TTL 60s、cursor 分页。 -- **幂等四场景**:重复点生成→idempotency_key(Redis 5min);MQ 重复→message_id 去重集合;支付回调重复→订单状态机+乐观锁(version);发布重复→version 唯一约束+状态前置校验。 - -## 7. 不做(明确非目标,技术决策版 §1.3) - -**MVP/近期非目标(保持收敛)**:MVP 不做 3D、不做专业级游戏引擎(Unity/Unreal 级)、不做海外市场;不做完全开放式代码生成(**harness 九门约束**——agent 写码于 LittleJS 插件库,非旧"配置填参"线);不自研大模型(接入通用 LLM + 开源 Agent 框架)。 - -**远期分层路线(仅探针,不进 MVP)**:Tier2 复杂2D+3D、Tier3 独立App(统一 Cocos+MCP,见 §1.1)为远期方向;MVP 至多做 1 个 Cocos-MCP 探针验证链路可行性,不投入工程。**Unity 始终否决。** - -## 8. 鉴权与匿名身份落点(2026-06-10 建设+e2e 收口,HJ-PASSPORT-EXEC-001) - -- **落点=system 内 passport 独立子包**(非新 game-module):零 RPC 直注 SmsCodeService/OAuth2TokenService;错误码取 system 远段 `1_002_090/091`;全部新文件收敛 `*/passport/` 子包(fork 合并冲突面≈0)。跨模块校验走 `PlayerApi`(@Primary 本地化,照 OAuth2TokenApiImpl 范式)。 -- **身份矩阵**:创作者=手机验证码(Debug 渠道,码落 `system_sms_code`)发 userType=MEMBER 真 OAuth2 token;陌生玩家=邀请码旁路注册(`wanxiang.passport.invite-register-enabled` 开关退役,核销=条件 UPDATE 原子恰一,并发实证);匿名玩家=纯客户端 anonId + 14 端点 @PermitAll + `game_runtime_session.player_user_id` 可空(V11);A2 创作白名单=`game_player.creator_flag` 5 个 Service 入层挂点。 -- **mock 并存机制(批跑零中断的根)**:`TokenAuthenticationFilter` 先查真 token、查不到才 mock——staging `mock-enable:true` 下 `Bearer test1` 与真 token 天然并存无开关;mock 白名单豁免=PlayerApiImpl「game_player 无行∧mockEnable→放行」(生产 mockEnable=false 自动收紧)。 -- **前端守卫真源=`isRealLogin()`**(仅 localStorage 真 token;既有 `isLogin()` 因 token 恒有 env/mock 兜底值**恒真不可用作守卫**);互动转正挂点=Feed.vue `onInteract` 单函数入口(share/report 是其内联分支,无独立函数)。 -- **匿名写链审计列**:见 rules/engineering-conventions §1.2 红线(系统身份注入范本 + V11 漏继承审计列之雷 + TelemetryEventEnum 真守门人)。 - -## 9. 多模板架构落点(2026-06-10 M-c 批① merge 收口,HJ-MC-TPL-EXEC-001) - -- **runtime=单 `startRuntime` 工厂内 switch(templateId) 分发**(拍板,弃「每模板独立工厂」):生命周期/`finish(score)`/loop/drawBase/cleanText 共享单份(红线代码不复制不漂移),玩法差异只在 `init()`(状态+交互+draw 玩法层+finish 触发);所有函数定义在 startRuntime 体内(toString() 注入约束);空串 templateId 兼容旧包并入 clicker case;未知模板走 `game_error` 防御分支不静默错渲染。体积实测:clicker+merge 双玩法 min 后 raw=4,828B(硬线 15,360B 的 31%,软门 8,192B)。 -- **后端=Loader/Validator「templateId→资源」Map 缓存**:PromptResourceLoader 逐模板装 (promptVersion, promptBody, schemaText),GameConfigSchemaValidator 逐模板编译 JsonSchema;**校验逻辑零新码**(仍 schema.validate(node)),同源铁律保持(注入 LLM 文本==校验文本,per templateId);isReady()=全模板就绪(任一缺失整体自禁用含模板名)。**模板白名单唯一同源=`AigcTemplateConstants.SUPPORTED_TEMPLATE_IDS` 编译期常量**(Properties 默认值与 validateTemplateExists 同读;不注入 executor Properties——`@ConditionalOnProperty` 关闭时 Bean 缺席)。pom maven-resources includes 已通配(新模板两资源自动进 classpath)。 -- **runtime↔player 承重接口纪律**:跨进程共享公式(merge 棋盘布局)必须钉死全部参数字面双侧一致(含 spec 散文易漏的 topPad 类参数),主 agent 收口逐字符比对;运行时实证=player 按公式推演 8 产料+7 拖拽全格命中、score=2^(targetLevel-1)-1 理论值吻合。 -- **新模板接入操作配方**:见 [`.agents/skills/add-game-template.md`](../skills/add-game-template.md)(批② idle/tycoon 直接套用)。 diff --git a/.agents/rules/build-vs-buy.md b/.agents/rules/build-vs-buy.md deleted file mode 100644 index 9245c503..00000000 --- a/.agents/rules/build-vs-buy.md +++ /dev/null @@ -1,37 +0,0 @@ -# Build-vs-Buy 硬规则(自研偏误防线) - -> **由来**:2026-06-12 全链审计(两起定罪案:自研 Canvas 引擎/自研 agentic 内核;一起现行案:LittleJS 发行版零接线)。根因不是经典 NIH,而是 **agent 写码边际成本≈0 把天平结构性压向自研**+口号无闸门。本文=闸门。 -> **定义**:**基建类组件** = 承担平台级横切职责(编排/运行时/引擎能力/协议实现/网关/存储/追踪/测试 harness/构建工具)的新组件,或预计 >300 行,或预计被 ≥2 个波次复用——命中其一即是。 - -## R1 现货尽调前置门(硬门) - -基建类组件开工前,评审版 spec 必含「Build-vs-Buy」一节:**≥3 个具名现货候选**(或附检索证据声明"生态位为空"),逐个给排除理由,理由必须落入枚举 {许可/体积预算/沙箱与 CSP 约束/维护健康度/集成成本/数据主权}。**「维护健康度」含生命周期状态硬查**:候选是否已归档 / deprecated / 停更、能力是否已并入上游(查官方仓 archive 标记 + release 频率)——**归档项不得作首选**。第二轮评审 checklist 必查此节;缺失=评审 fail,不得进执行版。 - -## R2 形态终点测试(spec 必答项) - -评审版「关键权衡」节必答:**"此自研件 12 个月后/v3 形态长什么样?届时需要哪些今天没有的能力?"** 若 v3 形态趋同于某现货品类(引擎/agent 框架/测试驱动器/schema 校验器/tracing),默认裁决=采购;坚持自研须创始人在 spec 内**具名签字行**("按默认拍"不可覆盖)。 - -## R3 约束血统登记(数字红线铸币税) - -任何进入 rules/spec/验收门的数字红线(体积/时延/行数/依赖数)必须带三件套:**来源**(由哪个架构前提推导)/**失效条件**(前提变即失效待复审)/**复审触发**(谁、何时)。无血统红线不得阻断任何设计决策。配套铁律:**架构终裁落锤后 48 小时内 AGENTS.md 与 `.agents/knowledge/` 全链回填**(wave-close 第三步显式子项,grep 验收;反面教材=「<15KB」在 AGENTS.md 滞留一日仍在向新会话传毒)。 -存量待回填血统:SDK<8KB / B1 350KB / 「本机零 npm 依赖」(适用面=lane 源码,不及工具链) / 「标准库优先」 / harness RSS≤2G。 - -## R4 prior-art 强制步(AI 放大器对冲) - -agent 动手写任何 **≥100 行**的新工具/harness/协议实现前,执行版 spec 或任务卡必含三行「prior-art」:①仓内已有同类 / 已有调研结论?(grep 代码**与 `.agents/knowledge/` 蒸馏事实**——同类选型常已被记过,直接用)②npm/PyPI/GitHub 现货?(检索词+前 3 结果,**并核候选生命周期:是否归档/停更**)③采纳或拒绝的一句话理由。缺三行,评审/收口打回。**spike 豁免 R1,但 spike 产物转正必须补过 R1**——"钱花两次用"只豁免重写,不豁免选型。(教材案例:llm_client 客户端 token 估算重造 new-api 权威计费,评审事后才抓回。教材案例 2(2026-06-25):`agentscope-runtime` 被外部研究当独立可采件、荐为扩容/沙箱首选,实则官方已归档、能力并入 `agentscope` 2.0.2,且本仓 `.agents/knowledge/agentscope-2.0-facts.md` 早记此结论——漏 R4① 仓内 grep + 漏 R1 归档状态查,双失,差点写进 SoT。) - -## R5 豁免面(防误杀) - -以下自研免尽调:(a) 契约/协议/schema **定义本体**(域特定,如 9 组契约、插件协议形状);(b) ≤100 行无状态胶水(static-serve 级);(c) 安全边界物理禁外部代码的场景(CSP 沙箱 iframe 内的 SDK/probe);(d) 已有在案尽调的延续性迭代;(e) 创始人书面豁免。**升格触发**:(b) 类被第 3 处复制或单文件破 300 行,自动补过 R1。 - -## R6 名义采用禁令(既买必用,不用即清) - -终裁采购的组件,首个消费波次必须出**真接线证据**:构建产物 grep 实证含该组件。声称"基于 X"的交付物产物里没有 X=验收 fail。(现行案:「LittleJS 增强发行版」产物 0 字节 LittleJS。)反向同理:已采购 ≥2 波未接线的组件,收口强制三选一:接线/挂 deprecated 横幅/删除——禁止无状态悬挂。(现行案:Dify/OpenGame 契约面。) - -## R7 抽象墙审计(对冲"可换性"过度工程) - -任何以"X 可换"为由建的隔离层,spec 必列**「被墙掉的 X 内建能力清单」**及替代成本;清单出现"将自研重造"项,该项单独过 R1+R2。**"可替换"≠"不依赖"——为可换性砌墙砌到宁可墙内重造也不用墙外买来的能力,就是自研偏误换壳。**(现行案:受控面禁直透引擎→粒子/物理/后处理三件在裸 Canvas2D 平行重造。) - ---- - -**决策链落点**:R1/R2/R4 → `ai-development-protocol.md` spec 模板与评审 checklist;R3 接线证据/转正重选型 → `wave-close-checklist.md`;R6/R7 → 波次验收门。审计全文与盘点表见 `docs/agent-specs/_archive/2026-06-12-自研偏误全链审计-报告.md`。 diff --git a/.agents/skills/cheap-model-game-generation.md b/.agents/skills/cheap-model-game-generation.md deleted file mode 100644 index c9737c62..00000000 --- a/.agents/skills/cheap-model-game-generation.md +++ /dev/null @@ -1,97 +0,0 @@ -# 便宜模型直出可玩轻游戏 · L1 生成 worker 配方(W-G1 实证) - -> **⚠️ 状态(2026-06-26):本篇是 reframe 前的旧 W-G1 / gamedef-factory 路。** reframe(2026-06-25)已废 gamedef + 统一 AgentScope;便宜档生成已迁到 **`cheap-worker/`**(Python/AgentScope + 直写 LittleJS `src/` 多文件 + import 复用 tier2 框架层 + shell-out 现有 node 工具),不再是本篇的「裸 openai client 不引 AgentScope + `generated-factory.js` + `buildGenericHostConfig` 套壳」。 -> - 便宜档 Python 线现状 → memory `amodel-generation-build-state`(WU-A spike)+ 执行 plan `docs/plans/2026-06-26-001-feat-cheap-worker-python-spike-plan.md`;AgentScope 2.0.2 实现 API 速查 → [`../knowledge/agentscope-2.0-facts.md`](../knowledge/agentscope-2.0-facts.md)「便宜档 cheap-worker 实现 API 速查」节。 -> - **仍有效(跨路通用,与 worker 实现无关)**:成本口径(§2)、代理旁路坑(§3)、driver-coverage / 模型能力画像(§9)、质量评估三层(§8)。 -> - **已失效(被 reframe 推翻)**:§1 链路(factory/gamedef)、§3「不引 AgentScope」VERDICT、§5–7 的 `generated-factory` / `buildGenericHostConfig` 套壳。 -> - **勿照本篇 §1/§5/§6 起新便宜档生成 —— 走 `cheap-worker`。** - -> 适用:用 new-api 便宜模型(DeepSeek/MiniMax)在**插件库 + 装载契约**上生成**可真玩**的 Tier1 轻游戏;**质量由 harness 门保证、非模型自觉**(HJ-GEN-001)。 -> 真玩取证门见 [`game-e2e-cdp-harness.md`](./game-e2e-cdp-harness.md) §7(九门:A–G 假绿守卫 + H 机制/latch + I 控制手感);本篇讲**生成侧**(谁生成 / 怎么校验 / 成本 / 坑 / 自产 gatespec)。 -> 活样板:worker = `wg1/gen-worker/`(lane 分支 `wg1/gen-worker`);生成产物 + harness = `game-runtime/games/_wg1-gen/`;交付报告 = `wg1/gen-worker/REPORT.md`。 - -## 1. 链路(能生成代码 ≠ 能玩) - -brief 题面 → 便宜模型写 `generated-factory.js`(一个 `GameHostFactory`)→ **静态校验门** → 套**官方 generic 壳**(`entry-generic.js` + `buildGenericHostConfig`,§6)→ esbuild `--global-name=__GameBundle` 打 iife(引擎内联 ~265KB)→ P1 宿主 `bootGameHost` 装载 → 本机 Chrome+CDP **九门真玩**(A–G 假绿守卫 + H 机制/latch + I 控制手感,harness §7)→ 失败回喂错因重试 ≤N。**必须过真玩门才算 pass**——能编译 / 能渲染 / 能动 ≠ 能玩。 - -## 2. 模型与成本(2026-06-14 网关实测) - -| 模型 | 定位 | 实测 | -|---|---|---| -| `deepseek-v4-flash` | **打底**(易档) | reasoning 模型;易档 0 重试 ¥0.01;三款冒烟过 A–G 核心门(H/I 逐游戏可选) | -| `deepseek-v4-pro` | 难档**升档** | Simon 0 重试 ¥0.06 | -| `MiniMax-M2.7` | 备选,**不优先** | completion_ratio=4 拉高成本 ¥0.117 贴 ¥0.15 闸 | -| `MiniMax-M3` | 备选 | 非 reasoning,响应干脆(1-token 回 ok) | - -> 网关 `100.64.0.8:3000` 共 11 模型,上四款 + `MiniMax-M2.7-highspeed` 渠道全活(各打 1 发 ping 实测);MiniMax 另有 M2/M2.1/M2.5 + highspeed 阶梯,横比可按需扩。原「DeepSeek key 未激活」(作战清单:32)**已过时**——经 new-api 网关四模型即时可用。 - -**成本口径**(¥上界,不计缓存折扣):`quota =(prompt + completion×completion_ratio)× model_ratio × group_ratio`;`¥ = quota / quota_per_unit(500000)× usd_rate(7.3)`。闸门 **¥0.15/款**。取价 `/api/pricing`、取率 `/api/status`;精确 `logs.quota` 需网关 access token(`sk-` key 无管理权,故只给上界)。 - -## 3. L1 纪律 + 坑红线 - -- **裸 openai client,不引 AgentScope**(spike VERDICT:框架 token 膨胀 + 本地开销吃便宜档单价);**统一出口 = new-api 网关**——baseUrl 指 new-api + key 走 `NEWAPI_KEY`(env / `.env`,gitignored,**绝不入库**)。**协议不锁**:同一 baseUrl 下 OpenAI `/v1/chat/completions` 与 Anthropic `/v1/messages` 并存、按模型选;不是「只 OpenAI 兼容 / 禁厂商 SDK」。 -- **reasoning 模型(flash/pro/M2.7)烧 max_tokens 于 reasoning_tokens** → `max_tokens` 必须给够,否则 `finish=length`、`content` 空。 -- **代理旁路坑**:本机 clash(`HTTP(S)_PROXY=127.0.0.1:7897`)会把发往 `100.64.0.8` 的请求经代理转发 → 502;**`NO_PROXY` 大小写两版都要含网关 host**,且须在 `import openai` **之前**设。 -- **输入坐标契约坑**(便宜模型与人皆易错):输入是**逻辑像素** `x∈[0,390] / y∈[0,844]`,**非归一 [0,1]**(`game-runtime/src/host/boot-game-host.js:295`)。写错 → 能编译能渲染能动但**点击全失灵**(详见 harness §7 G 门,正是这门逮住的)。 -- **静态门禁用 token**:`import` / `littlejsengine` / `Math.random` / `Date.now` / `addEventListener` / `requestAnimationFrame` / `new AudioContext` / `document.` / `window.`——生成代码只许调插件公开面 + 6 受控面(getContext2d/onFrame/getInput/getAudioContext/time/random),随机与时钟一律走受控 `random` / `time`(确定性可复现)。 -- **bundle 入库**:`dist/` 被 `.gitignore` 吞,故 bundle 输出文件名 `bundle.iife.js`(不落 `dist/`)——它是交付物须入库。 - -## 4. 静态校验门(node 侧,出厂前省 CDP 开销) - -抽码(` ```js ` 块)→ 契约扫描(default export + `init/update/render/destroy` 四方法齐 + `getEngine` 用法 + 禁用 token 扫描)→ `node --check` 语法。不过门不进打包,把"必失败件"挡在真玩门前。 - -## 5. 边界与未做 - -- 只消费冻结契约(`game-host.d.ts` / 6 受控面 / `__GameBundle` / `bootGameHost`)**零修改**;只在 lane 分支,不推 dev/2.0.0。 -- **✅ 生产接线已成(3b-B 派发面,`c99014c`)**:`AigcGenerateExecutor.dispatchGeneric`→真 worker `service.py`(包 `run_studio`)→HMAC 回调→落库入 feed 全链真证闭合(见 [`../rules/security-and-reliability.md`](../rules/security-and-reliability.md) §1.3)。3b-B 单款一句话「点击小怪物」真生成卡九门(Score 恒 0→**质量门正确拒发不可玩=系统履职非故障**),`run_studio` 自修 `max_repairs` 未救回。**⚠️ 但单点失败≠模型壁垒**:L1 scale-20 14 款实证(§9)便宜模型实际相当能干(主力 7/8 可玩、自写 CCD/文本HUD/网格/match 全对),多数失败是**宿主键盘桥 host bug(已修 `d754b71`)+ driver-coverage(harness 太朴素),非模型**;3b-B 那款真因(driver-coverage 或该款 hit-detection)续查并入 §9 画像。**真难点不是模型能力,是 harness driver 覆盖 + 宿主门面完备**(§9)。 -- **未做/续(创始人并行)**:20 款补全(scale-20 已 14 款,见 §9)、四模型横比(过门率/重试/¥每过门)、6 个 driver-coverage 失败款的 driver 增强(flappy/multiball/愤怒小鸟等)、键盘款修后批量重跑、calibration 人锚补全——规划见 [`2026-06-14-WG1-bakeoff天花板与Claude-free评估门-review.md`](../../docs/agent-specs/_archive/2026-06-14-WG1-bakeoff天花板与Claude-free评估门-review.md)。 - -## 6. 官方 latch 终态契约 + 套壳(P3 对齐,2026-06-14) - -P3 主线把 L1 产出靶定死为**官方通用装载壳**(`game-runtime/games/_generic/`,dev/2.0.0 `3108009`)。L1 **只产 `generated-factory.js`**(一个 `GameHostFactory`),套官方壳打包: - -- **套壳**:`entry-generic.js`(import `./generated-factory.js` + `src/host/generic-host-config.js` 的 `buildGenericHostConfig` 标准 7 插件装配)→ esbuild `--global-name=__GameBundle`。本 lane harness 入口(`_wg1-gen/_shared/entry-bundle.template.js`)= 同 `buildGenericHostConfig` 装配的**取证超集**(多透传 recHook/onReady 供 F 门;studio 调 `{canvas,seed}` 时 recHook no-op,一份 bundle 两用)。 -- **可测性红线**:工厂须导出 `_forensicsView() → { state: () => ({ phase, score, remaining, progress, gameoverReason, ...实体位置 }) }`(纯只读、闭包实时值);`host.state()`(`boot-game-host.js:283`)透传它。 -- **★ P0 latch 终态**:`phase ∈ 'booting'|'playing'|'gameover'`,进 `gameover` 后**恒驻留**(禁自动重开)。宿主 `inject.ts` 每 500ms 轮询 `phase` 代发 `game_end` 结算——**瞬时终态会被漏读→闭环静默断裂**,故必须驻留。实证:flash 能遵此契约(v4/v5 latch ✓)。 -- **位置态(技巧游戏)**:题面要求时额外导出 `ball/paddle` 等实体 `{x,y,vx,vy,w}`——供 harness **适配性真玩**(读球位接球)+ 确定性手感门(控制/碰撞)。 - -## 7. 确定性门推广:design agent 自产 gatespec(适任意游戏,405394d 实证) - -确定性手感门(H/I)原靠**手写 brief** 喂判据——每款游戏人工写 `assertAfterPlay`/`driver`/`controlCheck`,不可规模化。P1 把它升级为 **design agent 自产、studio 抽取合入**,确定性门遂适用**任意生成游戏**(实证:flash 的 design agent 对 breakout 产出结构合法 gatespec、studio 抽取合入成功): - -- **design agent 产 gatespec**(`worker/agent_loop/roles.py` 的 `DESIGN_SYSTEM` 末尾):在玩法设计末尾输出一段**机器可读 gatespec 块**,含 `exportState`(须导出哪些观测态,对齐 §6 可测性红线)/ `driver`(适配真玩出招式,如 `paddle-intercept`)/ `controlCheck`(控制体 + 目标 x)/ `assertAfterPlay`(进展断言)/ `expectLatch`。**坑**:模型易把 `ballPath` 写成竖直 `.y`——prompt 须明确「球水平运动 → `ballPath='ball.x'`」。 -- **studio 抽取合入**(`worker/studio.py` 的 `_extract_gatespec`):从 design 输出抽 gatespec 块(`json_repair` 兜模型 JSON 残缺)→ 合入 play-spec → **安全归一**(如 paddle-intercept 的 `ballPath` 误写 `.y` 自动兜回 `.x`);结果记 `gatespec` 供取证回溯。prompt 修 + 归一兜底**双保险**,实证唯一内容误差(ball.y)已被双修。 -- **★ tap/离散点击类自产 driver 缺口(3b-B 重跑实证·dispatch 面致命)**:design agent 对 tap-target 类游戏(打地鼠/井字棋/点击得分)反复给 `driver:{type:none}`——dispatch 面 `run_studio(play_spec={})` **全恃自产 driver**(无手供 play_spec),致 harness 盲打打不中目标 → `moves/score` 恒 0 → **H_progress 挂 + latch 不触发**,repairs=5 耗尽(3b-B 重跑 gen9306/9307 + 原 gen9303-9305 共 5 款同签名,**8/9 门过仅此门挂、游戏本体全对**:`targetX/Y/radius`、`board`、`moves` 导出正确,G_input/I_control/F_wiring 均过)。**根因=自产 driver 缺口,非模型/非游戏本体**(样板 tictactoe 过九门靠其 lane brief 手供 `play_spec.driver=tap-targets`)。**修向**:`DESIGN_SYSTEM` 对「离散点击目标」类强制产 `tap-targets` driver(+`exportState` 含 `targets[{x,y,occupied}]`),或 `_extract_gatespec` 对 brief 含离散格位/目标时兜底注入 tap-targets。~~当前 dispatch 面一句话现生成对 tap 类不可靠,须先补此缺口~~——这是 moat『一句话现生成』腿的真·临门一脚(纯 L1 生成域)。**【已修·2026-06-16·`a2cbabe6`】** `DESIGN_SYSTEM` 规则③改**家族二分**(离散点击目标类→必产 `tap-targets`+导出 `targets[{x,y,idx,occupied}]`、绝不 none;规避/推理族 +`safeOnly:true` +导出 `safe`〔仅 `_forensicsView` 测试可见、不渲染〕+断言 `result=="win"`;安全放置族断言 progress↑;技巧挡板类仍 `paddle-intercept`〔`ball.x` 绝不 `ball.y`〕;其余 none)——Python `roles.py` 与 SAA `SaaPrompts.java` **逐字同改**(规则段 1076 chars 公平性铁律)。**铁证**:tictactoe(放置族)一句话 `play_spec={}` 整链 **9/9 全绿一次过**(design 自产 tap-targets→factory 自产 targets→九门含 H_progress+latch 达终态),旧 `driver:none` 盲打卡死真因已闭;breakout 回归未误伤(恒 paddle-intercept)。**残留(正交)**:saolei 九门未翻绿=便宜模型写扫雷 factory 本身质量(`Math.random` 违禁/胜负不可达/A_boot 崩),九门**正确拦截坏游戏**=O1 factory 级生成质量(§9/scale-20 单列),非本修失败。**刻意未加 `_extract_gatespec` 关键词兜底**(易误判 paddle/flap,靠门 + 反馈自愈)。 -- **意义**:手感门判据从「手写一次性 brief」变成「随游戏生成的自产物」——同一条便宜模型生成链既出游戏码、又出验它的确定性门,确定性门覆盖面随生成规模自动扩张(harness 复利的一环)。 - -## 8. 质量评估:确定性门兜底 + 人锚天花板(W-G1 校准实证,2026-06-14) - -**确定性门(Claude-free,优先)** 已能把多数"坏"变可判:九门 + latch + 控制手感门 + 适配真玩。**"上下文是杠杆"实证**:同 flash 仅改接地,成本 −50%、修复轮次 −80%;player rubric 锚定(1-5 分级 + 空心→≤2)把 MAE 1.25→0.75。 - -**但便宜 player agent 做"好玩裁判"有结构性天花板**: -- **静态截图(M3 视觉)+ 运行数据(flash 文本)判不出交互动态质量**(物理/碰撞/控制手感)。实证:创始人亲玩把碰撞有问题的 pro 判 fix,两个 player 都给 fun=4(高估);text 还漏了 m27 的控制 bug。 -- **gate-H 盲打脚本会假阴性**:固定坐标 taps 打不动技巧游戏→"0 进展"≠空心(创始人把被判空心的 v2 排第 2)。解法 = **适配性真玩 driver**(读 state 接球,harness §7)。 -- **founder/人锚不可替代**(至少现阶段):没有它会把碰撞有问题的 pro 当"最佳"发出去。**校准 harness** = `wg1/gen-worker/worker/agent_loop/calibrate.py`(吃 `calibration/labels.json` 人锚,算 player vs 人锚 MAE/吻合/反样本否决)。 -- **路线**:确定性门做"地板"(能跑/真接线/有进展/latch/跟手),手感尽量拆成确定性检查(碰撞穿透门 J 规划中);拆不掉的主观手感留**创始人抽检**。 - -## 9. scale-20 放量实证:模型能力画像 + spec 预判推翻(W-G1 lane v3,2026-06-14) - -flash 打底放量 14 款(主力 8 + 压测 6),Opus 对抗审计核实(2 个 ultracode workflow): - -- **主力 7/8 真可玩**(0 假绿):井字棋/见缝插针/打砖块/跑酷/太空侵略者/Doodle/扫雷(扫雷=borderline——本体可玩,但门弱断言经"踩雷 lose"路径满足、证据薄)。flappy 唯一未过=**driver-coverage**(升 pro 仍挂,但源码物理合理、理想 AI 得分→是 flap-to-gap driver 太朴素,**非模型天花板**)。 -- **压测**:match3 ✅;**2048/Tetris/Asteroids 三款键盘游戏全挂于宿主缺键盘桥**(非模型,见 [`game-e2e-cdp-harness.md`](./game-e2e-cdp-harness.md) §8);multiball/愤怒小鸟=driver-coverage。 -- **★ 模型能力画像(flash)**:文本 HUD / 网格状态机(井字棋胜负+AI、扫雷洪泛)/ 子步 swept CCD(asteroids/multiball)**均自写正确**;计时/物理精度(Flappy)需**题面 pin 死数值 + 收紧观测契约**(Doodle 实证:收紧计分 + seek-x driver → regen 首发过)。栽点主要在**静态门可拦的纪律滑坡**(Date.now/Math.random/缺 render·destroy/没调 getEngine),零 CDP 成本拦下、回喂即修。 -- **★ spec 预判的门面缺口几乎全推翻**:CCD / 文本HUD / 网格 / match-finding / 手势均**非缺口**(便宜模型自带或自写;故"碰撞穿透门 J"已非急需)。**真·L0 门面缺口收敛为唯一一处=宿主键盘桥**(已 spawn_task 交 L0)。完整数据见 [`2026-06-14-WG1-scale20-短板量化报告.md`](../../docs/agent-specs/_archive/2026-06-14-WG1-scale20-短板量化报告.md)。 -- **M3 视觉 player 当生产过滤器**(`calibration/m3_test.json`):与门 8/9 一致、抓显性空心(flappy fun1)、漏截图不可见失败(键盘死/弱证据,恰被确定性门兜住)→ **三层互补**(门=地板 / M3=主观过滤 + 便宜 fun 信号 / 创始人=人锚)。MAE 压低待创始人对新款补锚(框架沿用 `calibrate.py`)。 -- **★ 规避/推理族:题面须自产「安全位」+ 断言用胜利终态(saolei borderline 修复,2026-06-15)**:tap-targets 盲点首个对扫雷会盲踩雷秒负、核心玩法零暴露(门弱断言被 lose 路径满足→ false-borderline)。修法 = 题面令 `_forensicsView` 自产 `safe`(测试专用 x-ray,=`!cell.mine`,**勿渲染/勿给玩家避雷提示**)→ harness driver `safeOnly:true` 只揭安全格到 win → 断言改 `result=="win"`。**flash 一次过且自产 safe 正确**(`generated-factory.js:337`)→ **坐实缺口在题面、非模型能力**。通则:凡「盲点首个会致负」的家族(扫雷类),题面给 oracle 安全位 + driver 避负 + 断言用胜利终态;门只证「机制点亮+可赢可达」,好不好玩归 M3+创始人。详见 [`2026-06-15-WG1-tap-targets-driver-自产缺口-L1brief.md`](../../docs/agent-specs/_archive/2026-06-15-WG1-tap-targets-driver-自产缺口-L1brief.md)。 -- **★ driver-coverage 6 款闭口 + 重生成归因(2026-06-15)**:scale-20 余 6 款 driver-coverage 失败全部归因(详 [`driver-coverage 闭口报告`](../../docs/agent-specs/_archive/2026-06-15-WG1-driver-coverage闭口与P2对照-L1报告.md) + [harness skill §8 四因铁律](./game-e2e-cdp-harness.md))——**0 个模型造不出 / 0 个 3D 硬界**:flappy/multiball **重生成即过**(原件『缝隙贴顶』/『底部丢球未实现』=**实例缺陷非模型短板**,收紧 brief + 增强 driver〔vy 前瞻 / 弃守排空〕后 flash 翻绿,multiball retries=0);t2048/asteroids 宿主键盘桥(L0 已修)重打包即活;asteroids/angrybirds 盲玩=可测性边界,**经 enrich exportState(asteroids 暴露陨石坐标 / angrybirds pin+导出 launch 物理常数)+ 适配 driver(aim-fire / drag-aiming 解析)转确定性闭口**(asteroids score 0→6、angrybirds 0→20 清场)。**生成侧铁律:单件失败禁直接归『模型造不出』,必重生成区分『实例 bug / 可测性缺口 / 模型短板』**——『模型造不出』是最大伪报源(原 flappy『升 pro 仍挂=模型天花板』被本轮证伪=driver+实例)。 - -## 10. gamedef 路 × 保真度谱系(Plan B Phase-2 实证,2026-06-21) - -SAA gameDefinition 路(M3-forced,staging gamedef-path)对一句话的**玩法保真度是谱系**,Plan B Phase-2 质量门(real-play CDP + rubric + 三契约)实证逆出(详 [`../../docs/agent-specs/2026-06-21-planB-phase2-closeout.md`](../../docs/agent-specs/_archive/2026-06-21-planB-phase2-closeout.md)): - -- **现象**:简单玩法(射击/躲避/打地鼠)稳定保真;**复杂机制(打砖块球物理 / 贪吃蛇变长身体)坍缩成通用骨架**(打砖块→"移动收集"、贪吃蛇→"接10个"),**GAMEDEF_SYSTEM 加 breakout/snake few-shot 两轮仍坍缩**(LLM 看到对应 few-shot 也不用)。 -- **★ 别归『模型造不出』(呼应 §9 末红线)**:同档 §9 实证 **flash / local nine-gate 路曾产可玩打砖块** → **非绝对天花板**,根因 = **M3 模型选择 + gamedef-path prompt 的当前局限**。只在一条配置测 2 轮就判天花板=伪报。 -- **★ 杠杆排序(复杂机制保真)**:few-shot **对复杂机制无效**(LLM 无视/复现不出)< **换更强模型**(flash 做到过)/ **skeleton-first 确定性骨架**(结构强制、LLM 只填参,绕过坍缩;`SaaSkeletons` 现默认关+映射坏需修)。简单玩法 few-shot+保真铁律有效(射击 collapse→faithful 实证)。 -- **★ Phase-2 门 ≫ gen 自评 accept**:gen 的「accept ≥80%」放过了 **assets=0 / 静止不可玩 / 不忠实 / 雷同 / 几何占位** 的游戏——**只有 real-play(帧变=真玩)+ rubric(设计保真)+ 三契约 逮得住**。core-done 质量门不可由 gen 自评代替。 -- **★ 裁责三招**:① 灌 Node `gd-runtime.createRuntime` 步帧——**动=wiring**(查 iframe CSP `'unsafe-eval'`/部署 `--mode staging`)/ **不动=gen-quality**;② manifest `assets` vs 源 `game_source_project.assets`——**0 vs 非0=产消断链**(打包丢);③ brief↔生成 gameDefinition 实体对比——**判保真度**(产对应实体 vs 坍缩通用骨架)。 diff --git a/.agents/skills/contract-first-development.md b/.agents/skills/contract-first-development.md deleted file mode 100644 index 362b03d6..00000000 --- a/.agents/skills/contract-first-development.md +++ /dev/null @@ -1,104 +0,0 @@ -# 契约先行与并行解耦联调手册(contract-first-development) - -> 蒸馏来源:`docs/superpowers/specs/mvp-execution-spec-design.md`(§3 契约先行 / §6 并行解耦与 Mock / §8.3 联调规则)、`docs/architecture/架构/README.md`(§6 联调协议)、`docs/architecture/架构/README.md`(§7.7 API 契约与版本)。 -> 适用:多工位(前端/后端/SDK/AI/数据)并行开发同一交付时,先锁契约、再各自 mock 解耦、最后集中联调。 -> 配套:工程规范(错误码/API 路径/`-api` 包)见 [`../rules/engineering-conventions.md`](../rules/engineering-conventions.md);新模块契约落地见 [`./add-business-module.md`](./add-business-module.md);生成链路见 [`./agentic-amodel-generation.md`](./agentic-amodel-generation.md) 与编排 [`./saa-graph-orchestration.md`](./saa-graph-orchestration.md);SDK 契约见 [`./runtime-and-multichannel.md`](./runtime-and-multichannel.md);任务协议见 [`../workflows/ai-development-protocol.md`](../workflows/ai-development-protocol.md)。 - ---- - -## 目标 - -**Day0(开发首日)半天全员锁定契约**,写入 `contracts/` 并提交 git;之后各工位基于契约 **mock 对方接口独立开发**,集中联调在 **Day11** 开始。把"等对方接口"的串行依赖,换成"对着契约并行"。 - -## 前置 - -- 已读 [`../knowledge/product-and-architecture.md`](../knowledge/product-and-architecture.md),对齐 13 模块边界与端(`/app` vs `/admin`)。 -- 工位划分明确(MVP spec:WS1 基座 / WS2 AI / WS3 运行时+SDK / WS4 前端 / WS5 数据变现)。 - ---- - -## 1. 理念 - -``` -Day0 上午(半天):全员对齐 → 锁定 7 个 Day-0 契约文件 → 提交 git(里程碑 M0) - ↓ -Day1~Day10:各工位基于契约 mock 对方接口,独立并行开发 - ↓ -Day11~Day12:集中联调(只联调、不加功能) -``` - -> 契约体系共 **8 类契约**:下列 7 个 Day-0 `contracts/` 文件 + Prompt Registry(`contracts/prompts/` 目录)为第 8 类(见 [`./prompt-governance.md`](./prompt-governance.md))。本手册聚焦 Day-0 锁定的 7 个文件。 - -契约一旦锁定即为各工位的"对接面"。变更契约必须同步 `contracts/` 并通知相关方(见第 4 节)。 - ---- - -## 2. 7 个 Day-0 契约文件清单(第 8 类 Prompt Registry 见 prompt-governance.md) - -| 契约文件 | 内容 | 负责人 | -|---|---|---| -| `contracts/api-schemas/*.yaml` | 所有模块 API 的 OpenAPI 3.0 定义(Request/Response) | WS1 lead 主笔,全员 review | -| `contracts/db-schemas/V1__*.sql` | 核心表结构(Flyway 迁移脚本) | WS1 | -| `contracts/sdk-interface.d.ts` | WanxiangGameSDK 全部 public API 类型 + postMessage 协议 | WS3 SDK 负责人 | -| `contracts/game-package.schema.json` | GamePackage manifest 格式 + 目录结构 | WS3 + WS2 | -| `contracts/events.schema.json` | telemetry 事件名 + 字段(v1) | WS5 | -| `contracts/dify-workflow-io.json`(⚠️ 降级远期未部署,见 `contracts/DEPRECATED-dify-workflow-io.md`;现行生成主线=new-api 网关) | Dify workflow 的输入/输出契约 | WS2 | -| `contracts/ad-slot.schema.json` | 广告位配置格式 | WS5 | - ---- - -## 3. Mock 策略表 - -| 工位 | 依赖谁 | Mock 方式 | 真实对接时间 | -|---|---|---|---| -| WS4 前端 | WS1/WS2/WS3/WS5 的 API | `vite-plugin-mock` 基于契约 yaml 自动生成 | Day6 起逐步替换 | -| WS3 SDK | WS4(宿主) | 独立测试页模拟 postMessage | Day6 集成 | -| WS2 aigc | WS1(project) | 内存态写入 + MQ mock | Day5 真实对接 | -| WS5 telemetry | WS3(SDK 上报) | curl 模拟 `/events/batch` | Day6 真实对接 | - ---- - -## 4. 真实对接切换 - -| 场景 | 做法 | -|---|---| -| 前端 mock → 真实 API | 改 `.env` 中 `VITE_API_BASE_URL` 即可(开发团队版 §6.1,MVP spec §8.3) | -| 后端新增/变更 API | **必须同步** `contracts/api-schemas/` 并通知前端(MVP spec §8.3) | -| 契约定义顺序 | 后端**先写 `-api` 包的 VO/DTO**,前端据此定义 TS 类型(开发团队版 §6.1) | - -> API 演进规则:新增字段不算 breaking;删除/重命名字段 = 升版本(技术决策版 §7.7)。 - ---- - -## 5. 联调规则 - -| 规则 | 说明 | 出处 | -|---|---|---| -| 时间窗 | Day11~Day12 预留 2 天,**只联调不加新功能** | MVP spec §6.3 | -| 主导与响应 | 前端主导提 bug,后端 **30 分钟内**响应 | MVP spec §6.3 | -| Bug 优先级 | **P0 当天必修**;P1 联调期内修复 | MVP spec §6.3 | -| 阻塞升级 | 阻塞 **> 30 分钟**立即升级到每日站会 | MVP spec §6.2 / §8.3 | -| 每日站会 | 每天 **10:00**,每人 2 分钟(昨天/今天/阻塞点) | MVP spec §6.2 | -| 问题跟踪 | 联调 bug 提 Issue,打标签 `联调` + 模块名 | 开发团队版 §6.1 | - ---- - -## 6. 联调速查 - -| 观察点 | 地址 / 工具 | -|---|---| -| 后端 API 文档 | Swagger / Knife4j `http://localhost:48080/doc.html` | -| 生成链路日志 | ~~Dify UI `http://localhost:3001`~~(已降级远期未部署)→ 现行=编排器批跑日志 `docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/` + new-api 网关 `http://100.64.0.8:3000` | -| SDK 事件流 | game-studio 开发模式 **DebugPanel**(实时 postMessage 事件流,开发团队版 §6.3) | - ---- - -## 7. 常见坑 - -| 坑 | 后果 | 应对 | -|---|---|---| -| 契约偏差到联调才暴露 | Day11 集中爆雷、返工 | WS1 在 Day10 预留时间专门修对接时发现的契约偏差(MVP spec §4 Week1 Day10);前端 Day6 起提前对接早暴露 | -| 契约变更未同步 | 前后端字段不一致、联调失败 | 任何 API 增改**先改 `contracts/` 再写代码**,并通知相关方(MVP spec §8.3) | -| 前端先于 `-api` 定 TS 类型 | 与后端 VO/DTO 错位 | 顺序固定:后端 `-api` VO/DTO 先行 → 前端据此定 TS(开发团队版 §6.1) | -| mock 与真实响应结构不一致 | 切真实 API 后页面崩 | mock 严格依据契约 yaml 生成,不手捏假数据 | -| 阻塞硬扛不升级 | 拖垮整条链路进度 | 阻塞 > 30 分钟必升级站会,会后 10 分钟两人对齐(MVP spec §6.2) | diff --git a/.agents/skills/game-e2e-cdp-harness.md b/.agents/skills/game-e2e-cdp-harness.md deleted file mode 100644 index 7c0fb8c3..00000000 --- a/.agents/skills/game-e2e-cdp-harness.md +++ /dev/null @@ -1,120 +0,0 @@ -# Canvas 游戏 e2e 证据 harness 配方(CDP on mini-desktop) - -> 适用:插件库/生成游戏的**真浏览器输入级 e2e**(触摸轨迹→状态机推进→四件套证据),区别于 DOM 走查(那个见 [`ui-walkthrough-cdp.md`](./ui-walkthrough-cdp.md))。 -> 首跑实证:T1b-α 参考件 7 轮调试链(教训全在 harness 侧,游戏逻辑零返工)。活样板=`game-runtime/games/wanglanmei-ref/test/{e2e-input.cdp.cjs,ref-e2e-runbook.sh}`。W-G1 生成游戏真玩(九门:假绿守卫 + latch 终态 + 控制手感)见 §7,样板 `game-runtime/games/_wg1-gen/_shared/play.cdp.cjs`。 - -## 1. 编排形制(runbook 骨架) - -精确 SHA scratch clone → esbuild 打包 → IP 门 → `systemd-run` 起 serve + chrome 两单元 → **就绪等待**(10×0.5s 探活)**再**做韧性探测(5×6s)→ 驱动器 → journal 归档 → 停单元。 -- **就绪/韧性必须分两段**:curl 抢在 listen() 前会把刚起的单元误判失败杀掉(journal 里 Started+Stopping 同秒 = 此坑签名)。 -- chrome 旗标:`--headless=new --no-sandbox --no-zygote --remote-allow-origins=* --autoplay-policy=no-user-gesture-required`(最后一项缺 → AudioContext 卡 suspended)。 -- 长驻一律 systemd-run 具名单元,可 journal 取证可 stop,不留孤儿。 - -## 2. 驱动器六律(e2e-input.cdp.cjs 形制) - -1. **启动等待轮询取证全局**(如 `__refBooted/__refBootError/__refHost`),超时给 25s——拿 bootError 文本比盲等截图有用得多。 -2. **坐标必须走 rect 映射**:游戏 zone 坐标(canvas 内坐标系)→ `getBoundingClientRect` → 页面 CSS 坐标再下发触摸。canvas 不在 (0,0) 或被缩放时直发坐标全偏。 -3. **触摸 = touchStart/touchEnd 成对 + ~90ms 间隔 + 步进若干帧**;拖动(滑条)用连续 touchMove。 -4. **zone/phase 名以游戏源码 computeZones 为唯一真相**——驱动器猜语义名必踩坑(实证:营业期 phase 叫 `open` 不叫 `serving`,循环秒退)。 -5. **计数器要驱动器侧实时累计**,勿赛后读游戏内环形缓冲(240 事件环溢出 → 假阴性 serve_ok=0)。 -6. **确定性对比须同存档态**:双开比哈希前 `localStorage.clear()`+reload(二开多画「继续」按钮属正确行为,不是缺陷)。 - -## 3. 两条出厂红线(游戏侧,门里逮过的真缺陷) - -- **页面壳**:canvas 必须置 (0,0) 满幅;状态条等 UI 用 absolute overlay + `pointer-events:none`。flex 布局把 canvas 压下/裁底 = 驱动器坐标漂移 + 真机底部按钮不可点(双重致命)。 -- **esbuild 全量预检**:出厂前在 /tmp 跑一次完整 bundle(`const` 被赋值这类错只在打包期爆,headless 单测覆盖不到所有渲染分支)。 - -## 4. 四件套证据口径 - -输入轨迹 JSONL / 截图+canvas 哈希 / 探针 JSONL / checklist JSON,落 `games//evidence/round-N/`;硬门(boot/phase 推进/确定性)与软活项(美术观感)分开判。 - -## 5. 引擎掌帧门(engine-takeover)增补(A0 门0 实证,T1b-β·2026-06-13) - -接「真引擎掌帧」(littlejsengine engineInit 五回调)而非 RAF 桩时,门0 多六坑: - -1. **serve 根对齐 index.html 的相对 bundle 路径**:index.html 以 `./dist/host-bundle.js` 加载 → 构建产物须落 `/dist/`、serve 根=该 index.html 所在目录(如 `host-dev/`)。错位=404 白屏(α 的 serve 根是游戏目录,易照抄错)。 -2. **scratch 装依赖禁 `npm init -y`**:会覆盖含引擎依赖的 package.json 丢 littlejsengine;直接 `npm i`(装 deps+devDeps=引擎+esbuild)再 `npm i ws`(CDP harness 额外依赖,不在 package.json)。 -3. **写 /tmp 的临时 cjs:`require('./x')` 锚脚本目录非 cwd**→ MODULE_NOT_FOUND;用 `require(require('path').resolve('test/harness/x.cjs'))`(cwd 锚)。 -4. **掌帧断言=帧增量区间,非 `>0`**:`time=frame++/frameRate` 是引擎定义式恒等,`>0`/`t1>t0` 可被「只 update 一次的假桩」骗过;真掌帧证据=500ms 内 frame 增量落 `[20,45]`(@60fps 理论 ~30),带上下界排单步假推进+失控空转。 -5. **dev 构建引擎自带污染源(只读源码才发现)**:littlejsengine 开发包默认 `debugWatermark=true`(每帧画非确定 averageFPS 进 mainContext 右上角,毁 readback 复现)→ 取证前必 `setDebugWatermark(false)`;`canvasClearColor` 默认 `CLEAR_BLACK` alpha=**0**(透明不铺底,非不透明黑)→ 须 `setCanvasClearColor(BLACK)`。prod min 包默 false,dev 包必显式调。WebGL 取证嫌麻烦可 `setGLEnable(false)`(须 engineInit 前)走纯 2D mainContext readback,避 preserveDrawingBuffer 坑。 -6. **引擎一 RAF 内追帧 N tick(N 受墙钟抖动)破异步逐像素确定性**:`frameCount>=target` 跨 RAF 异步采样落帧不确定 → 逐像素门交「手摇定量推帧」的桩通道(`?engine=stub`)独占,引擎通道只证掌帧+渲染落 2D(像素非空+主色命中,不比逐像素哈希)。门0 driver=`game-runtime/test/harness/gate0-engine-takeover.cjs`(双通道:real 证掌帧/stub 兜确定性+回滚)。 - -## 6. 引擎能力真接线门(门②·runtime call-ID)增补(A6 实证,T1b-β·2026-06-13) - -证「插件能力**经 ctx.getEngine() 运行时真调引擎**」(动态证据,区别于门①的 esbuild metafile 静态 import)。门 A6 6/6 实证,driver=`game-runtime/test/harness/a6-engine-wiring.cjs`,编排=`a6-runbook.sh`。 - -1. **门②探针形制=host-dev 侧 rec→window.__engineCalls**:在 host 的能力工厂(`makeEngineCaps`)给每个引擎能力叶方法(particles.spawnEmitter/audio.synth.synthSfx/math.easing.*)埋一行 `rec(id)` push 到 `window.__engineCalls`,**仅取证、绝不入渠道产物**(工厂只活 real 通道)。再加 `__hostdev.engineProbe()` 经**各插件真实公开 API**(非直调引擎)触发能力调用 → 断言 __engineCalls 含 call-ID。真接线靠「插件真实 API → rec 命中」双证,不靠直调引擎自欺。 -2. **引擎渲出色=spec,非旧 sim 口径**:删 sim 后粒子由引擎 ParticleEmitter 渲,颜色取 `spec.colorStart`(如 particles-juice burst 给**白** r=g=b=1)。A0 G0-7 的青蓝(`b>r+30`)口径对引擎渲染**失效**→像素门判据改「任意亮像素 `max(r,g,b)>80` 计数 + `maxCh` 全屏最亮」;`maxCh≈0`=确凿反证「GL 关致引擎粒子不落 2D」的全黑假象(实测 maxCh=240,引擎真落 2D,GL 关无碍 fillRect 路)。**换引擎能力后,像素门的颜色假设必同步重核**。 -3. **音频合成需 AudioContext 非空**:插件 playSfx 在 `audioOrSilent()==null` 时早返不合成→rec 不触发→探针须先 `unlockAudio`;chrome `--autoplay-policy=no-user-gesture-required` 下 headless 可合成(此项软门兜,headless 不可用时 deferred 不阻断,正确性由单测 mock-synth 注入兜)。 -4. **mini-desktop scratch 部署**:6c6g `./` rsync 会吞整个 monorepo(cwd 易被重置到仓根→`tar -C ` 或绝对路径,**严禁裸 `./`**);A6 仅需 host-dev/index.html + 预建 host-bundle.js(本机 esbuild 出,含探针)+ test/harness/*.cjs + `npm i ws`,tar-pipe 几文件即可,无须全树同步。 - -## 7. 生成游戏真玩九门 + 假绿守卫 + latch 终态 + 手感门(W-G1 实证,2026-06-13/14) - -便宜模型生成游戏的真玩门(driver=`game-runtime/games/_wg1-gen/_shared/play.cdp.cjs`),在 §1-6 基础上收敛为**九门全过才 PASS**(A–G 通用假绿守卫 + H 机制/latch + I 控制手感;**H/I 逐游戏可选**,play-spec 未声明则 SKIP 向后兼容)。生成侧配方见 [`cheap-model-game-generation.md`](./cheap-model-game-generation.md)。 - -**真玩驱动两态**:`play-spec.driver` 在=**适配性真玩**(读 `_forensicsView().state()` 的实体位置自动出招,如挡板追球);否则=`play-spec.inputs` 固定序列。**盲打固定坐标打不动技巧游戏**(球没接住→0进展)是 H 假阴性根因(创始人亲玩 + v4/v5 regen 双重实证),故技巧类必用 driver。 - -| 门 | 判据 | -|---|---| -| A 装载 | `__genBooted` 真、无 `__genBootError` | -| B 未捕获 | 无 page error / unhandledrejection | -| C 掌帧 | 500ms 内 frame 增量 ∈ [20,45](@60fps,排单步假推进 + 失控空转) | -| D 真渲染 | mainContext 有亮像素(`max(r,g,b)>80`) | -| E 活性 | 多采样 **≥2 个不同整帧哈希**(排静止假死;**静态待机游戏如 Simon 须多采样**,单采样会假阴) | -| F 真接线 | `__engineCalls` 含期望 call-ID(插件能力经 `ctx.getEngine()` 真调引擎,recHook 埋点;同 §6 门②) | -| **G 输入有效** | **确定性 A/B 对照**:同 seed **无输入** vs **有输入**两实例各推进到**同帧号**,比整帧哈希——**必须不同**才证输入真生效 | -| **H 机制+latch** | `play-spec.assertAfterPlay[]` 进展断言(如剩余↓,证非空心)全过 + `expectLatch` 时真玩到 `state().phase==='gameover'` 且**驻留**(600ms 后仍 gameover)。依赖游戏经 `_forensicsView()` 导出 phase(官方 latch 契约,见 cheap-model §latch) | -| **I 控制手感** | `play-spec.controlCheck`:连点目标 x,读控制体位置(如 `paddle.x`)验**平滑逼近**(\|moved\|≥阈 ∧ dist≤容差),逮「一格一跳」/卡死/不跟手 | - -**H/I = 把"能玩/手感"从主观变确定性**(W-G1 2026-06-14):H 借官方 latch 终态契约(phase 驻留 gameover)同时验"真结束(关得上闭环)+ 真有进展(非空心)";I 借导出的控制体位置验"跟手"。前提=游戏导出可观测态(可测性红线)。**尚未确定性覆盖**:碰撞穿透(规划门 J);**物理/碰撞/控制的主观手感** player agent(静态截图)判不出、须创始人/人锚(见 cheap-model §质量评估)。 - -**play-spec 来源 = design agent 自产 gatespec(非手写 brief,405394d)**:`exportState`/`driver`/`controlCheck`/`assertAfterPlay`/`expectLatch` 由生成链的 design agent 末尾产出、studio `_extract_gatespec` 抽取合入(`json_repair` 兜 + ballPath `.y→.x` 归一)——故 H/I 判据**随游戏自动生成、适任意游戏**,确定性门覆盖面随生成规模扩张(配方见 [`cheap-model-game-generation.md`](./cheap-model-game-generation.md) §7)。 - -**G 门 = 本 lane 关键发明,专逮"假绿"**:Pong 这类带**自走动画**的游戏,输入全失灵也"能动"、能骗过 C/D/E;G 门用同帧号 A/B 哈希对照隔离出"输入到底改没改变走向"。实证逮住一处**输入坐标契约写错**(生成 prompt 误称归一坐标、实为逻辑像素 `boot-game-host.js:295`)致"能编译能渲染能动但点击全失灵"的假绿。 - -**CDP 触摸下发坑**(承 §2 律3,生成游戏侧细化):tap 须**镜像 ref `realTapAt`**——裸 `{x,y}`(逻辑像素,经 §2 律2 rect 映射)、`touchStart`/`touchEnd` **背靠背**(无 radius/force/长按),否则触摸不达 `getInput()`。坐标契约 = **逻辑像素 [0..390]/[0..844],非归一**(便宜模型与人皆易错)。 - -## 8. scale-20 放量实证:driver 库泛化 + 门承重件 + 对抗审计硬化(W-G1 lane v3,2026-06-14) - -**适配 driver 库 1→8 型 + drag 输入事件**(`play.cdp.cjs`,`spec.driver.type` 分发;盲打打不动技巧/实时游戏=H 假阴根因,故按机制族建 driver): - -| driver | 机制族 | 读什么自动出招 | -|---|---|---| -| `paddle-intercept` | 挡板接球 | `ball.x` → 挡板对齐;**`drainAfter` 声明则跑满后【弃守排空】(挡板停 `drainX` 角落)让球漏光→打出 lose 终态(接球类靠一直接球永不失败→latch 不可达的解,multiball)** | -| `tap-targets` | 点击离散目标 | `state.targets[{x,y,occupied[,safe]}]` → 点未占用;**规避/推理族(扫雷)配 `safeOnly:true` 只点 `safe===true`、确定性避负把核心循环跑到 win**(井字棋/扫雷/打地鼠/Simon/invaders…) | -| `flap-to-gap` | 重力穿缝 | `bird.y` + **`bird.vy` 速度前瞻**(`位置+vy×lookahead` 预测仍偏低才拍、`aimBias` 瞄缝心上方留下落余量)→解高位缝/快下落『追不上·过冲』(flappy);缺 vy 退化为纯位置反应式 | -| `seek-x` | 横向趋近接台 | `bird.x` vs `nextPlatform.x` → 点左/右半 | -| `tap-pairs` | 相邻交换(三消) | `targets[k]`/`[k+1]` 成对点 | -| `key-cycle` | 纯按键 | 循环按 `keys[]` 到 gameover(**依赖宿主键盘桥**);填充型(2048)用 2 向键(如 `Up+Right`)比 4 向更快逼满盘,但**抗死锁类游戏仍难确定性到 latch=边界** | -| `drag-aiming` | 抛射瞄准(愤怒小鸟) | 暴露 `launch{gravity,powerScale}` → **45° 抛解析反解拖拽矢量(确定性命中+各发±力度微抖兜离散)**;未暴露→退化 `powers[]` 力度扫描+`upLead` 补下坠。**angrybirds pin+导出物理后 score 0→20 win=可测性边界转确定性闭口** | -| `aim-fire` | 射击瞄准(Asteroids) | 读 `ship{x,y,angle}`+`targets[{x,y}]` 选最近,旋转使 `|atan2方位-angle|` 收敛(**旋向自适应**:diff 变大翻向,免猜 CW/CCW)→对齐即开火;**须游戏 exportState 暴露目标坐标**(无坐标=可测性边界) | - -固定输入新增 `{t:'drag',from,to,ms}`(touchStart→插值 touchMove→touchEnd,合成 swipe/拖拽)。**driver 覆盖度 = 门能否兜住的前提**:shooter/填充型 latch 需足够步数驱动到终局(invaders 步数 30→50 即翻绿,实证)。 - -**★ driver-coverage v2 闭口:H 假阴四因归因铁律(2026-06-15,5 款实测)**。技巧/射击/填充类 H 假阴必先分因、**禁『模型造不出』笼统归因**(spec §9): -1. **宿主门面缺失**(系统性,L0 域):如键盘桥 `d754b71`——**失败严格沿『键盘 vs 指针』分界=最强信号**;宿主经 esbuild 打进 bundle,故修后须**重打包** bundle 才生效(`node scripts/build.mjs /entry-bundle.js /bundle.iife.js --global-name=__GameBundle`)→实证 t2048 `score 0→4`、asteroids `F_wiring 0→26`。 -2. **driver 太朴素**(我域,改 `play.cdp.cjs`):本轮增 flap-to-gap vy 前瞻 / paddle-intercept 弃守排空 / drag-aiming / aim-fire 四件;flappy・multiball 经此 + 重生成翻绿。 -3. **可测性边界**(游戏 `exportState` 不足以确定性盲玩):asteroids 无陨石坐标、angrybirds 无发射物理常数。**正解=enrich exportState 暴露所需(坐标/物理常数)+ 适配 driver**:asteroids 暴露 `asteroids:[{x,y}]`+aim-fire 旋向瞄准;angrybirds brief **pin+导出 `launch:{gravity,powerScale}`**+drag-aiming 45° 抛解析瞄准——**两者皆经此从『边界』转『确定性闭口』(asteroids score 0→6、angrybirds 0→20 清场)**。**抗死锁类(2048)的 latch 是设计性边界**(游戏意在不结束),宜放宽为强 progress(score↑∧board变)+G 兜。 -4. **生成实例缺陷 ≠ 模型能力**:multiball 原件底部丢球未实现(latch 不可达)、flappy 原件缝隙贴顶,但 flash 在**收紧 brief**(『球越底沿即出局不反弹』/『缝心落可达区间』)下**重生成即过**(multiball retries=0)。**区分『此实例 bug』与『模型短板』必须重生成验证,不可凭单件下结论**——这是『模型造不出』的最大伪报源。 - -**结论(scale-20 的 driver-coverage 失败款)**:0 个是模型能力天花板,0 个是 3D 硬界——真难点恒在 **harness driver 覆盖 + 宿主门面完备 + 游戏可测性导出**三者。 - -**★ 地板真承重件 = `expectLatch` + `G_input`,不是 progress 计数**(对抗审计实证):`H_progress.pass = progressPass && latchPass`;单条 `assertAfterPlay`(score/revealed/moves +1)鉴别力弱——saolei 踩雷也 revealed++、runner score 计时自增,可被"漂亮空壳"蹭过;真隔离空壳的是 latch(真到 gameover+600ms 驻留)+ G_input(同帧 A/B 哈希证输入真生效)。**新游戏务必让 progress 断言带终局语义**(全清/三连/真死),否则靠 latch+G 兜。 - -**★ 宿主键盘桥缺失(L0 硬缺口,实证)**:`boot-game-host.js attachInput()` 只桥 pointer 三态、**不桥 keydown/keyup** → `ctx.getInput()` 键盘通道空,所有方向键游戏(2048/Tetris/Asteroids)输入死。**失败严格沿"键盘 vs 指针"分界=最强系统性证据**(指针款全过、键盘款全挂)。修法对齐 `host-dev/host.js:427-428`(已 spawn_task 交 L0)。→ **移动端轻游戏优先 pointer/tap/swipe,键盘款待宿主补桥**;配套 `play.cdp.cjs` key() 对 Arrow 须传 `code===key`(原 undefined 致 event.key 空)。 - -**★ 对抗审计硬化门(Opus build-then-exit,ultracode workflow)**:脚手架期用 Opus 多 agent 对抗审计九门判定(反驳每个 PASS 找假绿 + 归因每个 FAIL)——实证抓出 saolei 弱断言(门+M3 都没抓到)、把 flappy 错归"模型天花板"纠正为"driver 缺陷"、定位宿主键盘根因。**生产无 Claude:门(地板)+ M3 便宜 player(视觉过滤:抓显性空心、漏截图不可见失败)+ 创始人(人锚)三层互补**;Opus 审完去硬化门/driver 即退出。 - -## 9. 首局体验门(firstPlay 派生超集)+ A/B 输入因果判定 + 2 harness 红线(W-G1 组C,2026-06-16) - -九门之上加**首局体验门**(`d4f16aab`,只动 `play.cdp.cjs`,**路A 零改 gatespec/契约**):`verdict.firstPlay:{playableMs, firstFeedback, coreLoopReached, categoryDerived}`,**additive 不并入 `verdict.pass`**(不阻断九门,H 仍机制硬地板);**品类从 driver 家族反推**(`tap-targets` 无 safeOnly→放置 / +safeOnly→规避 / `paddle-intercept` 等→技巧·action / `none`→退化),零改生成侧。三断言分层、复用现成:**③ 60s 品类核心闭环 = H 门(assertAfterPlay+latch)外包 60s 墙钟**(复用,几乎零新判定);**① 可玩≤2s = 页面侧 `performance.now()` 打 `window.__playableAtMs`**(navigationStart 为 0 点;避 CDP 轮询 ~300ms 粒度;`waitBoot:81` 的 `delay(800)` settle 只延后*读取*不污染*值*——优于"改短 settle",零碰装载检测语义、保超时兜底)。 - -**★ playableMs = warm 稳态,不是冷启**:headless 全新 Chrome 首次导航 ~24.7s(进程 JIT/GPU/bundle 解析一次性开销,**非游戏本征可玩时**),预热后稳态 53-58ms。pre-flight 先暖一趟、隔离冷启记 `warmupMs`。**局限诚实入档**:此门守得住"boot 永不完成/装载死循环"退化,**守不住"大 bundle/慢首加载"退化**(warm 测不出 bundle 体积)——真机 first-load(浏览器在跑·bundle 未缓存)阈值留 staging 冷缓存(`Network.clearBrowserCache`)校准。 - -**★ 首反馈即时·A/B 输入因果判定(核心技术,别用裸帧)**:验"首招是否真触发反馈"。**裸全帧像素/帧哈希 A/B 对动画自走类(动球)会被污染**——球每帧本在动 + 两趟自由运行落帧抖动,实测 breakout `signal≈noise`(804 vs 1156)→ 裸帧会**假 SKIP**(更糟:单趟"帧变了"对动球类是**重言式假绿**,球本就在动)。改判定阶梯(`measureFirstFeedbackAB`):**⓪ 控制体维度**(读 `controlCheck.paddlePath` 指的 input-controllable 位如 `paddle.x`,免动球/粒子抖动,最干净)→ moved >moveMin=真因果 `true`、≈0=真 FAIL;**① state 因果**(phase/score/moves/remaining 变,无歧义 `true`,静态盘走此);**② 像素 signal≥noise×3**(仅无控制体路径兜底);**③ noise 超顶=非确定性→SKIP**(血统债);**④ signal≈noise 无控制体→SKIP**(不假 FAIL)。**无假 PASS/假 FAIL/假 SKIP**(breakout 经控制体 paddle.x Δ=145 真判 `true`)。 - -**★ 2 条新 harness 红线(组C 采到)**: -1. **后台 CDP target 的 rAF 被冻结**:并发开多 target,headless Chrome **只让前台 target 跑 rAF**(后台冻结)→ A/B 多趟里后台趟卡 boot(frame=-1)、前台趟跑到 gameover,对照彻底失效。**必须串行单实例多趟**(各 fresh navigate),不可并发 target。 -2. **控制体因果探针须点"离默认位最远的边",非默认招/ball-x**:首招点 ball-x 可能 ≈ 控制体默认位(实测 ball≈198≈paddle195→Δ仅3),无法证因果。**改点最远 tapX(如 x=50)+ 连派 `tapsPerTarget` 拍**(镜像 `I_control`)→ 控制体大幅移开(Δ=145)干净。 - -**★ 受控面 determinism = A/B 对照前提**:seed 缺省固定(`0x1234abcd`)+ LittleJS 固定步 → 跨 fresh 实例同帧号(`atFrame`)可比(G 门已用此范式);real 引擎自由运行(host 不掌 RAF、无暂停/回退)故不强求帧精确,靠控制体维度规避抖动。无控制体维度且非确定性的 skill 游戏 → 诚实 SKIP(标血统债:需受控面 seed 或游戏导出控制体位置维度)。 diff --git a/.gitignore b/.gitignore index 7257f80f..6b3a8113 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,18 @@ coverage/ !.env.example .idea/ + +# ── IDEA 共享项目配置:允许提交模块、Maven、检查器、运行配置;个人状态仍由 .idea/.gitignore 忽略 ── +!.idea/ +!.idea/.gitignore +!.idea/*.iml +!.idea/*.xml +!.idea/inspectionProfiles/ +!.idea/inspectionProfiles/*.xml +!.idea/jsLinters/ +!.idea/jsLinters/*.xml +!.idea/runConfigurations/ +!.idea/runConfigurations/*.xml *.log .DS_Store .gstack/ diff --git a/SAA-INTEGRATION-TODO.md b/SAA-INTEGRATION-TODO.md deleted file mode 100644 index d66f3b2e..00000000 --- a/SAA-INTEGRATION-TODO.md +++ /dev/null @@ -1,13 +0,0 @@ -# SAA 接入·依赖统一 TODO (HJ-AGI-002 spike) - -日期 2026-06-15 · 分支 spike/saa-int · 机器 mini-desktop -现状: dependency:tree BUILD SUCCESS;Boot 3.5.14 / Redisson 4.4.0 / SCA 2025.0.0.0 / jackson 2.21.2 全保住,零冲突。 -框架集(完整推荐): graph-core + agent-framework + starter-graph-observation + starter-builtin-nodes(钉1.1.2.2) + spring-ai-starter-model-openai;经 spring-ai-bom:1.1.2 + spring-ai-alibaba-bom:1.1.2.2 + extensions-bom:1.1.2.2 管理。 - -## 待统一(unify)TODO -1. builtin-nodes 不在 SAA BOM → 现显式钉 1.1.2.2;待 BOM 纳入后改随 BOM,或提到 huijing-dependencies 用属性统一管理。 -2. SAA 编译基线 Boot 3.5.8 vs 本项目 3.5.14(已保住);若后续出 API 不兼容,再评估统一 Boot/SAA 版本。 -3. SAA redisson 3.x(optional,未拉) vs 项目 4.4.0;若启用 RedisSaver 需实测 redisson 4.x 兼容 RMap/RBucket/RLock。 -4. SAA 公共仓最新已到 1.1.2.3(本 spike 钉 1.1.2.2 对齐已分析源码);稳定后评估 bump 1.1.2.3。 -5. 三 BOM import 现放 aigc-server 局部;若多模块用 SAA,提到 huijing-dependencies 统一 import。 -6. builtin-nodes 连带拉入 document-parser-tika/markdown/bshtml/yaml,体积增;如不需可 exclusion。 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-001.txt b/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-001.txt deleted file mode 100644 index cb3da652..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-001.txt +++ /dev/null @@ -1,25 +0,0 @@ -# agent-loop v1 批次创意(batch-001,N=20)—— spec:HJ-AGENT-LOOP-EXEC-001 §7.1 -# 构成:C1 spike 13 条(gen_spike.py IDEAS 原样,含故意模糊/极简两条压泛化)+ 7 条新多样创意。 -# 一行一条;# 开头与空行跳过;v1 全部走 clicker 模板闭环。 -# ---- C1 spike 13 条(原样保序) ---- -王蓝莓的小卖部收银台,给顾客结账 -太空舱里捡星星补给能量 -农场里收割成熟的蔬菜 -深夜便利店招待来买夜宵的顾客 -校园运动会上的接力赛冲刺 -猫咖啡馆里撸猫攒爱心 -春节集市上抢福袋 -海底捞珍珠同时躲开鲨鱼 -烧烤摊翻烤串,别烤糊了 -地铁早高峰挤上即将关门的车 -做一个很好玩的游戏 -解压点点点 -中秋节帮嫦娥把月饼送上月宫 -# ---- 新增 7 条(题材/情绪/场景多样化:市井/校园/职场/节日/治愈/紧张/美食) ---- -雨夜帮路边馄饨摊老板撑伞收摊 -图书馆闭馆前把还回来的书归架 -奶茶店爆单日疯狂摇珍珠奶茶 -跨年夜零点在广场上点烟花倒计时 -给办公室加班的同事分下午茶蛋糕 -体育课一分钟跳绳挑战 -火锅店捞毛肚,七上八下别捞老了 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002.txt b/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002.txt deleted file mode 100644 index e4d8949f..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002.txt +++ /dev/null @@ -1,30 +0,0 @@ -# agent-loop v1 批次创意(batch-002,N=20)—— spec:HJ-AGENT-LOOP-EXEC-001 §7.1 -# 构成:与 batch-001 的 20 条零重复;题材混搭=市井生活4/校园3/节日3/职业4/治愈3/动作1/故意模糊2(压测对抗细则②)。 -# 一行一条;# 开头与空行跳过;v1 全部走 clicker 模板闭环。 -# ---- 市井生活 4 条 ---- -菜市场帮鱼摊老板捞活鱼装袋称重 -清晨早餐铺给排队的街坊盛豆浆 -老城天台抢在下雨前收晾晒的被单 -社区快递驿站双十一爆仓日扫码上架包裹 -# ---- 校园 3 条 ---- -晚自习偷偷传纸条别被老师发现 -食堂打饭窗口给同学打菜手别抖 -课间十分钟冲去小卖部抢最后一包辣条 -# ---- 节日 3 条 ---- -元宵灯会上猜灯谜赢花灯 -端午龙舟赛上擂鼓助威踩准节奏 -圣诞夜帮圣诞老人往烟囱里投礼物 -# ---- 职业 4 条 ---- -宠物美容店给狗狗吹毛做造型 -夜市煎饼摊摊煎饼别摊破皮 -消防员训练塔上速攀考核 -果园采摘节帮游客摘苹果装筐 -# ---- 治愈 3 条 ---- -给阳台上一排多肉植物挨个浇水 -温泉旅馆里给泡汤的客人递热毛巾 -深秋公园把落叶扫成大大的一堆 -# ---- 动作 1 条 ---- -屋顶跑酷躲开晾衣杆和花盆 -# ---- 故意模糊 2 条(无具象题材词,压测对抗 prompt v1.1.1 判定细则②) ---- -随便来个游戏 -给我整个上头的小游戏 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002b.txt b/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002b.txt deleted file mode 100644 index ddfce576..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/batch-002b.txt +++ /dev/null @@ -1,10 +0,0 @@ -社区快递驿站双十一爆仓日扫码上架包裹 -晚自习偷偷传纸条别被老师发现 -食堂打饭窗口给同学打菜手别抖 -课间十分钟冲去小卖部抢最后一包辣条 -端午龙舟赛上擂鼓助威踩准节奏 -消防员训练塔上速攀考核 -温泉旅馆里给泡汤的客人递热毛巾 -随便来个游戏 -夜市煎饼摊摊煎饼别摊破皮 -给阳台上一排多肉植物挨个浇水 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/idle-cal-10.txt b/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/idle-cal-10.txt deleted file mode 100644 index 759c7501..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/idle-cal-10.txt +++ /dev/null @@ -1,17 +0,0 @@ -# M-c 批② idle 校准批创意(idle-cal-10,N=10)—— spec:HJ-MC-TPL-EXEC-002 §8(拍板3) -# 口径:10 条校准批·不设硬门·不计 M2 口径,accept 为校准观测值;走 config.idle-designer v1.0.0(--template idle)。 -# 构成:6 条具象挂机/放置域(天然带「持续产出累积」语义)+ 2 条跨域改写压题文一致性 + 2 条模糊压泛化。 -# 一行一条;# 开头与空行跳过。 -# ---- 具象挂机/放置域 6 条 ---- -挂机种一片果树园攒满果实 -放置养鱼塘自动收鱼 -挂机养蜂群采蜜装罐 -自动钓鱼攒一桶渔获 -放置开矿洞挖满矿石 -挂机打理花田收满鲜花 -# ---- 跨域改写压题文一致性 2 条 ---- -王蓝莓的小卖部收银台给顾客结账 -帮奶茶店点单收银 -# ---- 模糊/极简压泛化 2 条 ---- -做个挂机放置的小游戏 -躺着也能一直涨 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-cal-10.txt b/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-cal-10.txt deleted file mode 100644 index 7d78859e..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-cal-10.txt +++ /dev/null @@ -1,18 +0,0 @@ -# M-c 批① merge 校准批创意(merge-cal-10,N=10)—— spec:HJ-MC-TPL-EXEC-001 §8-1(拍板3) -# 口径:10 条校准批·不设硬门·不计 M2 口径,accept 为校准观测值;走 config.merge-designer v1.0.0。 -# 构成:6 条具象合成域(养成/制作/经营题材,天然带等级链)+ 2 条跨域改写压题文一致性 -# + 2 条模糊/极简压泛化(沿 batch-001 模糊创意压测范式)。 -# 一行一条;# 开头与空行跳过;全部走 merge 模板闭环(--template merge)。 -# ---- 具象合成域 6 条 ---- -把多肉植物从叶插苗一路合成到爆盆老桩 -奶茶店里把小料合成出招牌满配奶茶 -铁匠铺把碎铁片合成传说宝剑 -小猫从奶猫合成长成猫中之王 -把云朵合成成会下雨的积雨云 -夜市摊把食材合成出深夜豪华套餐 -# ---- 跨域改写压题文一致性 2 条 ---- -深夜便利店招待来买夜宵的顾客 -太空舱里捡星星补给能量 -# ---- 模糊/极简压泛化 2 条 ---- -做个好玩的合成小游戏 -一直合一直爽 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-prod-20.txt b/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-prod-20.txt deleted file mode 100644 index 107241eb..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/merge-prod-20.txt +++ /dev/null @@ -1,27 +0,0 @@ -# M-c 批① merge 正式批创意(merge-prod-20,N=20)—— spec:HJ-MC-TPL-EXEC-001 §8-3(拍板3) -# 口径:20 条正式批,accept ≥80% 量级验收(校准批 merge-cal-10 = 10/10,prompt v1.0.0 未升版直开)。 -# 构成:14 条具象合成域 + 3 条跨域改写压题文一致性 + 3 条模糊/极简压泛化;与校准批 10 条零重叠。 -# 一行一条;# 开头与空行跳过;全部走 merge 模板闭环(--template merge)。 -# ---- 具象合成域 14 条 ---- -把橡果一路合成参天大树 -海边把贝壳合成出闪亮的珍珠王冠 -把小水滴合成汇成大海 -烘焙坊把面团合成出顶级蛋糕 -把萤火虫合成成照亮夜空的星星 -牧场把小毛球合成成保暖大毛毯 -把碎布头合成出华丽的婚纱 -工坊把齿轮合成出会走路的机器人 -把彩色糖果合成出巨型棒棒糖 -雪地里把雪球合成成大雪人 -把旧书页合成成魔法典籍 -果园把小青果合成成蜜桃之王 -把音符合成出一首交响乐 -渔村把小鱼干合成成豪华海鲜宴 -# ---- 跨域改写压题文一致性 3 条 ---- -农场里收割成熟的蔬菜 -王蓝莓的小卖部收银台,给顾客结账 -帮城市清理垃圾让街道变干净 -# ---- 模糊/极简压泛化 3 条 ---- -做个解压的小游戏 -越合越大 -来一局能上头的 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/tycoon-cal-10.txt b/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/tycoon-cal-10.txt deleted file mode 100644 index bc3c3f09..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/ideas/tycoon-cal-10.txt +++ /dev/null @@ -1,17 +0,0 @@ -# M-c 批② tycoon 校准批创意(tycoon-cal-10,N=10)—— spec:HJ-MC-TPL-EXEC-002 §8(拍板3) -# 口径:10 条校准批·不设硬门·不计 M2 口径,accept 为校准观测值;走 config.tycoon-designer v1.0.0(--template tycoon)。 -# 构成:6 条具象经营域(天然带「进货→卖货→赚差价」语义)+ 2 条跨域改写压题文一致性 + 2 条模糊压泛化。 -# 一行一条;# 开头与空行跳过。 -# ---- 具象经营域 6 条 ---- -开奶茶店进货原料卖奶茶赚钱 -经营面包摊烤面包卖给顾客 -摆地摊进零食卖给路人 -开花店进鲜花扎花束卖 -经营水果摊进货称斤卖 -开书报亭进报纸杂志卖 -# ---- 跨域改写压题文一致性 2 条 ---- -太空舱里捡星星补给能量 -农场里收割成熟的蔬菜 -# ---- 模糊/极简压泛化 2 条 ---- -做个经营赚钱的小游戏 -开店当老板数钱 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/.agent b/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/.agent deleted file mode 100644 index a75295aa..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/.agent +++ /dev/null @@ -1,26 +0,0 @@ -# agent-loop 编排器(生成 QA 闭环 / 批跑 / 走查 / 探针工具箱) - -> **定位**:本目录是项目的**生成 QA 闭环与走查工具箱**——批跑编排、裁决、成本核算、CDP 试玩/走查、信道探针。诞生于 HJ-AGENT-LOOP-EXEC-001(2026-06-09),现已超出单一 spec 范围、被多波次复用(batch-001/002/002b、M-c 校准批与正式批、UI 走查、回包链路取证、W4 成本薄片①)。 -> **户口注记(2026-06-11 harness 体检)**:本目录即 Doc B §2 登记的「未编目实存组件②(agent 生成 QA 闭环裁决器)」的实体;本 `.agent` 是其户口。**迁往顶层 `tools/` 的评估后置**(涉及 runs/ 相对路径与历史文档引用面,当前收益不急迫)。 - -## 组件清单 - -- **批跑主链**:`run_batch.py`(批次驱动/预算闸/熔断/发布段)/ `judge.py`(决策表 D1-D10 + Verdict 铸章)/ `ledger.py`(JSONL 账本+幂等重放)/ `llm_client.py`(new-api 调用)/ `prompts.py`(Registry 渲染)/ `backend_gw.py`(staging HTTP)/ `evalflow.py`(eval 回流)/ `report.py`(批报告)——详见 [`README.md`](./README.md) D3 段。 -- **成本**:`newapi_cost.py`——new-api `logs.quota` 权威成本(merge-prod-20 实测 ¥0.031/款),客户端估算降为 fallback。 -- **试玩/走查**:`player_cdp.py`(游戏试玩 CDP + BrowserPool)/ `admin_walk.py` + `run_walk.sh`(admin 审核台走查)。 -- **探针**:`probe_bridge_channel.py`(宿主↔iframe postMessage 双边探针,回包断裂取证常备)。 -- **测试**:`tests/`(judge 决策表全分支 + ledger 重放/预算/熔断)——**改裁决/账本逻辑必跑**。 -- Golden 回归 harness 位于 `../runs/golden-regression-*/golden_regression.py`(随黄金集版本目录走)。 - -## 边界 / 纪律 - -- 批跑/走查一律 **mini-desktop** 执行(本机 6c6g 严禁,见 [`.agents/skills/staging-ops.md`](../../../../.agents/skills/staging-ops.md));`NEWAPI_KEY` 仅经环境变量。 -- `../runs/` 是产物目录(账本/报告/证据/黄金集);**新工具代码放本目录,不再长进 runs/**。 -- 操作配方入口:[`.agents/skills/ui-walkthrough-cdp.md`](../../../../.agents/skills/ui-walkthrough-cdp.md)(走查)/ [`.agents/skills/staging-ops.md`](../../../../.agents/skills/staging-ops.md)(部署/冒烟)。 - -## 当前状态 / TODO(2026-06-11) - -- [x] 批跑/裁决/Golden 回归/成本/走查/探针全链可用(batch-002b 10/10、merge-prod-20 19/20=95% 实证)。 -- [ ] `llm_client.py` 补显式 max_tokens(C6 backlog:空 content 重试根因)。 -- [ ] Doc B 正式 T-id 编目(建议扩入 T-AGC-20/21 注记,随下次 Doc B 修订销账)。 -- [ ] `tools/` 迁移评估(后置)。 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/README.md b/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/README.md deleted file mode 100644 index c5969af9..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/README.md +++ /dev/null @@ -1,151 +0,0 @@ -# agent-loop v1 编排器 · 环境与依赖说明 - -> 本 README 按交付物分区维护(D3 编排器 / D5 玩家 agent 各自只动自己的分区)。 - -## D5 玩家 agent(player_cdp.py)环境前置 - -### 1. Python 依赖(spec §7.1:标准库优先,CDP 允许引入单一轻 websocket 依赖) - -唯一三方依赖 = `websocket-client`。mini-desktop(Ubuntu 24.04 / Python 3.12,受 PEP 668 -管制不可裸 pip)实测安装配方: - -```bash -# 首选:apt 系统包(2026-06-09 已在 mini-desktop 安装,版本 1.7.0) -apt-get install -y python3-websocket - -# 备选(无 apt 源时): -pip3 install --break-system-packages websocket-client -``` - -选择理由:mini-desktop 已有 `google-chrome` 146(无需另装浏览器);websocket-client 走 -apt 系统包零编译、与 PEP 668 不冲突,是最小代价方案。 - -### 2. 无头 Chrome CDP 实例(mini-desktop 侧启动,脚本连 127.0.0.1:9222) - -```bash -# root 运行必须 --no-sandbox;端口默认只绑 127.0.0.1(不暴露调试口,脚本与浏览器同机) -nohup setsid google-chrome --headless=new --no-sandbox --disable-gpu \ - --disable-dev-shm-usage --remote-debugging-port=9222 --window-size=420,900 \ - --user-data-dir=/tmp/qa-chrome-9222 about:blank >/tmp/qa-chrome-9222.log 2>&1 & - -# 探活 -curl -s http://127.0.0.1:9222/json/version -``` - -第二实例(§7.3 浏览器池 ≤2)按需换端口 9223 + 独立 user-data-dir 再起一个。 - -### 3. 自测(spec §9.7 / §12.2;前端 :4173 与 staging :48080 须在跑) - -```bash -python3 player_cdp.py --self-test --version-id 9001 -``` - -夹具 9001 现实(2026-06-09 staging 实查):`game_runtime_package.package_json` 仅 `{}`、 -checksum 为占位 `a`×64 → 宿主校验必失败回退 demo 兜底。自测通过线 = 取证全链可用 -(loaded / 真实点击 / game_end 捕获 / 蛇形→驼峰映射 / 证据落盘)且 demo 信号被正确识别 -(`demoFallback=true` 属预期);不要求 `packageChecksumVerified=true`。真实落包后的 -五条 AND 全绿验证走 §12.3-⑥(依赖 D4 合入部署)。 - -### 4. 批跑调用面(D3 对接) - -```python -from player_cdp import play, BrowserPool, verify_package_backend - -pool = BrowserPool(["http://127.0.0.1:9222"]) # ≤2 端点 -backend_chk = verify_package_backend(...) # §9.5 实玩前编排器侧核验(F7) -with pool.acquire() as lease: - report = play(cdp_http=lease.endpoint, ..., - continue_on_demo=False, # 批跑必须 False - backend_verified=backend_chk["ok"]) # F7 闸结果传入(⑤合成判定要件) -# report["infraSignal"] / report["runnableOk"] / report["demoFallback"] → judge 输入 -``` - -### 5. 实测踩坑记录(2026-06-09 self-test 实证,批跑配置必读) - -1. **批跑 frontend 必须传 `http://localhost:4173`(不是 100.64.0.7)**:宿主 manifest - 完整性校验用 `crypto.subtle`(inject.ts sha256Hex),仅安全上下文(https/localhost) - 可用。经 `http://100.64.0.7:4173` 访问时 crypto.subtle 缺失 → 即使 D4 落了真包也会 - 永走 demo 兜底(self-test 实测 warn 原因即「crypto.subtle 不可用」)。Chrome 与前端 - serve 同在 mini-desktop,浏览器内用 localhost 访问即解(前端调后端走 bundle 内置的 - 绝对地址 VITE_API_BASE=http://100.64.0.7:48080,不受影响)。 -2. **CDP WebSocket 握手 403**:Chrome 111+ 拒绝带 Origin 头的 CDP 连接;脚本已用 - `suppress_origin=True` 修复(不依赖 `--remote-allow-origins` 启动旗标)。 -3. **manifest 响应体经 `Network.getResponseBody` 确定性不可取**(spec §9.5 与现实矛盾, - 已上报主 agent):宿主用 fetch 流式读 manifest,体读完即释放且不进资源缓存——导航后 - 0.26s 的最早窗口取体仍报 No resource with given identifier(非时序问题)。脚本处置: - 保留 spec 原文取体路径(即时缓存 + 兜底再取,未来浏览器行为变化仍可用);取不到时 - 五条 AND ⑤ 走「三角证据合成判定」(manifest 200 响应存在 ∧ 宿主 crypto.subtle 校验 - 无 demo 信号 ∧ 编排器侧 F7 闸对同 URL 原文比对通过,`backend_verified` 传入), - 报告 `checksumVerifyMethod` 字段如实标注 browser_body/synthesized/none。 - -## D3 编排器(run_batch.py 等) - -> spec:HJ-AGENT-LOOP-EXEC-001 §7 + §10。python3 标准库实现,无第三方依赖(CDP 依赖归 D5,见上)。 - -### 1. 文件清单 - -| 文件 | 职责 | spec 锚点 | -|---|---|---| -| `run_batch.py` | 主入口:批次驱动/阶段流水/预算闸/熔断/发布段/换模型抽检/稳定性重测/回流/报告 | §7 | -| `judge.py` | 裁决引擎:决策表 D1-D10 逐行落码 + runnable 五条 AND 复核 + 模板 schema 深度校验 + Verdict 铸章 | §10/§9.4 | -| `ledger.py` | JSONL 账本 + designId 幂等重放 + 预算闸(§7.3 八项硬编码常量)+ 熔断(§7.4 四条 + F10) | §7.2-7.4 | -| `llm_client.py` | new-api 调用(json_object/温度 0.4/0.3s 间隔/重试 ×2,沿 gen_spike 配方;NEWAPI_KEY 仅环境变量) | §7.1 | -| `prompts.py` | Registry 加载与 `{{input.*}}` 渲染(git 即事实源,prompt 不内嵌代码;残留占位符即报错) | §7.1 | -| `backend_gw.py` | staging HTTP 封装(B1 鉴权配方;draft/generate/getTask/callback/package/manifest/publish/review/feed) | §7.1 | -| `evalflow.py` | eval 回流 `contracts/prompts/eval//` + C1 spike 52 条种子转入(均幂等) | §7.7 | -| `report.py` | 批报告 report.md/report.json(§7.5 全字段;同时即 prompt-eval.yml 闸②④数据源) | §7.5 | -| `tests/` | `test_judge.py`(决策表全分支+防御 raise)/ `test_ledger.py`(重放/预算/熔断桩验证) | §7.8 | - -### 2. 运行(mini-desktop;本机严禁批跑) - -```bash -cd docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator -# 单测(纯标准库;§12.2) -python3 -m unittest tests/test_judge.py -v -python3 -m unittest tests/test_ledger.py -v -# spike 52 条种子一次性转入 eval(幂等可重跑;§7.7) -python3 evalflow.py --seed-spike -# 批跑(NEWAPI_KEY 必须走环境变量;NEWAPI_AUDIT_MODEL 供换模型抽检,未配则抽检如实降级并入报告披露) -NEWAPI_KEY=sk-xxx python3 run_batch.py --ideas ../ideas/batch-001.txt --cdp http://127.0.0.1:9222 -# 断点续跑(§7.2:已终判 designId 整体跳过;infra_fail 从 submit 重走新 taskId) -NEWAPI_KEY=sk-xxx python3 run_batch.py --resume batch-001 -``` - -退出码:0=正常收口;2=配置/密钥/契约件(D1 prompt、D2 schema)缺失;3=试玩环境不可用整批暂停(§7.4-3); -4=infra 占比 >30% 熔断(§7.4-1);5=连续 5 条同因 kill 熔断(§7.4-2)。 - -### 3. D3↔D1 渲染变量约定(prompt 模板按此写 `{{input.<名>}}` 占位符) - -| prompt id | 渲染变量 | -|---|---| -| `config.clicker-designer` | `idea` / `template_schema`(clicker schema 全文)/ `banned_list`(批内已登记 title/theme)/ `findings`(首轮空串;schema 重出轮=错误清单文本——模板须容忍该段为空) | -| `quality.adversary-review` | `idea` / `game_design`(GameDesign 全文 JSON) | -| `fix.design-revise` | `game_design`(round=0 原稿)/ `findings`(P1 项 JSON 数组)——D1 正文实际只消费这两个占位符;编排器多供给 `idea`/`template_schema` 属冗余传参(render 为替换式,多传无害) | - -渲染后若残留任何 `{{input.*}}` 占位符,编排器立即报错(联调期暴露变量名不齐,禁止把花括号发给 LLM)。 - -### 4. 关键执行决断(实现层固化,spec 锚点可溯) - -1. **阶段执行序** `submit → design → schema_gate → dedup_gate → adversary → [fix 回炉重走] → callback → verify_package → play → judge`: - submit 先行依据 = §3 mermaid(IDEAS→ST 与设计路径并行)∧ §6.2 Verdict.taskId 必填(fix 中间 Verdict 也要有)∧ - §16-1 文本面 kill 须回调 failed 终态化(任务先存在,才有「queued 残留」可避免)。 -2. **发布段置批末(换模型抽检之后)**:使 §7.4-4「分歧 >10% 冻结本批发布开关」真实可执行; - F12「已发布金丝雀保留」覆盖跨 resume 场景。 -3. **designId 轮级口径(§16 D2-a 裁决,已废止先前「全生命周期稳定」决断)**:designId=sha256(idea+templateId+round) - **含 round 因子**——round=0(root)与 round=1(回炉轮)两轮 designId 必不同;账本阶段/judge/verdict 行落当前轮 - designId、幂等重放以各轮 designId 为键;rootDesignId(=round0 designId)由阶段行 data 携带,作 fix 前后对照 - (labels.jsonl 落该字段)与报告/查重登记的创意级关联键。预算闸 ①LLM/②实玩为「每创意」口径,一律以 root 计数。 -4. **resume 时 decision=fix 不算终判**:D5 行语义=「全流程重走 E1」,fix 中断的创意以 round=1 的 designId - 从回炉轮续跑(fix 输入从 root 的 round0 design/adversary 账本行恢复;恢复不到按 infra_resume_gap 收口告警); - resume 重发布前对账本 accept 证据**再裁决验章**(发布仅凭 judge 铸章跨进程依然成立)。 - infra_fail 重放语义=「infra 行使该 designId 此前 ok 产物失效」(resume_state 清空重积累,支持多次中断时序)。 -5. **§9.5「编排器记账的 sha256(T1)」落地**:后端组包字节面无法在编排器侧复现(Jackson 序列化), - 实操=复用 D5 `verify_package_backend`(RespVO.checksum ↔ sha256(manifest 原文) 双向核对 + 包内 target/title 等值), - 通过后以 RespVO.checksum 为实玩浏览器侧核验基准。 -6. **预算口径**:①LLM ≤8/创意、②实玩 ≤3/创意为流水线内闸;批末换模型抽检/稳定性重测为批级 QA 调用, - 不占创意预算、成本计入批报告 cost。 -7. **五条 AND ⑤ 的 judge 侧双重核对(§16 D5-a)**:除 `packageChecksumVerified=true` 外,judge 还核对 - D5 超集字段 `checksumVerifyMethod ∈ {browser_body, synthesized}`——none/缺失一律判⑤不过(「none 不得通过」 - 的代码层落实;编排器侧 F7 `verify_package_backend` 原文比对仍为权威锚点)。该字段属 D5 内部披露, - 铸 Verdict 时按契约七字段闭集投影剥除(gameEnd 同做 completed/durationMs 两键闭集投影, - durationMs 缺失/None/float 防御归一化为非负 integer——契约 gameEnd.durationMs 不可 null)。 diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/admin_walk.py b/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/admin_walk.py deleted file mode 100644 index 0a8b56fa..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/admin_walk.py +++ /dev/null @@ -1,165 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -admin 审核台 链路② UI 走查 —— 最小 CDP 客户端(websocket-client 直驱)。 -在 mini-desktop 本地驱动 headless chrome(:9222)走查 game-admin(:4174): -登录 → 项目审核队列 → 点「通过」approve 真实待审游戏 → 取证。 -普通 DOM 页面,evaluate 用于受控点击(非游戏试玩,不受 player_cdp 只读纪律约束)。 -阶段:recon(看登录页) / login(登录+进队列+dump) / approve(登录+进队列+点通过+确认+验证)。 -""" -import json, base64, time, sys, urllib.request -import websocket # websocket-client 1.7.0 - -CDP_HTTP = "http://localhost:9222" -ADMIN = "http://localhost:4174" -TARGET_GAME = sys.argv[2] if len(sys.argv) > 2 else "" # approve 阶段指定 gameId - - -def new_target(url="about:blank"): - """Chrome 111+ 必须用 PUT /json/new 建 target。""" - req = urllib.request.Request(f"{CDP_HTTP}/json/new?{url}", method="PUT") - d = json.load(urllib.request.urlopen(req, timeout=10)) - return d["webSocketDebuggerUrl"], d["id"] - - -class CDP: - def __init__(self, ws_url): - self.ws = websocket.create_connection(ws_url, max_size=None, timeout=40, - suppress_origin=True) - self._id = 0 - - def send(self, method, params=None, timeout=40): - self._id += 1 - mid = self._id - self.ws.send(json.dumps({"id": mid, "method": method, "params": params or {}})) - end = time.time() + timeout - while time.time() < end: - self.ws.settimeout(max(0.1, end - time.time())) - try: - msg = json.loads(self.ws.recv()) - except Exception: - continue - if msg.get("id") == mid: - if "error" in msg: - raise RuntimeError(f"{method}: {msg['error']}") - return msg.get("result", {}) - raise TimeoutError(method) - - def evaljs(self, expr, timeout=40): - r = self.send("Runtime.evaluate", - {"expression": expr, "returnByValue": True, "awaitPromise": True}, - timeout) - if "exceptionDetails" in r: - return {"__js_error__": json.dumps(r.get("exceptionDetails"), ensure_ascii=False)[:300]} - return r.get("result", {}).get("value") - - def nav(self, url, settle=6): - self.send("Page.navigate", {"url": url}) - time.sleep(settle) - - def shot(self, path): - r = self.send("Page.captureScreenshot", {"format": "png"}) - with open(path, "wb") as f: - f.write(base64.b64decode(r["data"])) - - def close(self): - try: - self.ws.close() - except Exception: - pass - - -# ---- JS 片段 ---- -JS_DUMP_LOGIN = r"""(()=>{ - const inp=[...document.querySelectorAll('input')].map(e=>({type:e.type,ph:e.placeholder||'',val:(e.value||'').slice(0,20)})); - const btn=[...document.querySelectorAll('button')].map(e=>(e.innerText||'').replace(/\s+/g,'')).filter(Boolean); - return {href:location.href, title:document.title, inputs:inp, buttons:btn}; -})()""" - -JS_CLICK_LOGIN = r"""(()=>{ - const btns=[...document.querySelectorAll('button')]; - const b=btns.find(e=>(e.innerText||'').replace(/\s+/g,'')==='登录'); - if(b){b.click(); return 'clicked登录';} - return 'notfound登录|avail:'+btns.map(e=>(e.innerText||'').replace(/\s+/g,'')).filter(Boolean).join(','); -})()""" - -JS_DUMP_QUEUE = r"""(()=>{ - const rows=[...document.querySelectorAll('.el-table__row')].map(r=>{ - const cells=[...r.querySelectorAll('td')].map(td=>(td.innerText||'').trim().replace(/\s+/g,' ').slice(0,40)); - const btns=[...r.querySelectorAll('button')].map(b=>(b.innerText||'').replace(/\s+/g,'')); - return {cells, btns}; - }); - return {href:location.href, rowCount:rows.length, rows:rows.slice(0,8), - bodyText:(document.body.innerText||'').replace(/\s+/g,' ').slice(0,260)}; -})()""" - -def js_click_pass(game): - return r"""(()=>{ - const rows=[...document.querySelectorAll('.el-table__row')]; - for(const r of rows){ - const txt=r.innerText||''; - if(txt.includes('%s')){ - const pass=[...r.querySelectorAll('button')].find(b=>(b.innerText||'').replace(/\s+/g,'')==='通过'); - if(pass){pass.click(); return 'clicked通过 for %s';} - return 'row matched but no通过btn'; - } - } - return 'gameid %s not found in rows'; - })()""" % (game, game, game) - -JS_CONFIRM = r"""(()=>{ - const btns=[...document.querySelectorAll('.el-message-box button, .el-overlay button, .el-dialog button')]; - const ok=btns.find(b=>{const t=(b.innerText||'').replace(/\s+/g,'');return t==='确定'||t==='确认';}); - if(ok){ok.click(); return 'confirmed';} - return 'no-confirm-dialog|btns:'+btns.map(b=>(b.innerText||'').replace(/\s+/g,'')).join(','); -})()""" - - -def do_login(c): - """导航到 / → 被弹去登录 → 点登录(表单已预填 admin/admin123/芋道源码)。""" - c.nav(f"{ADMIN}/", settle=7) - c.shot("/tmp/aw_login.png") - print("LOGIN_PAGE:", json.dumps(c.evaljs(JS_DUMP_LOGIN), ensure_ascii=False)) - print("CLICK_LOGIN:", c.evaljs(JS_CLICK_LOGIN)) - time.sleep(6) # 等鉴权 + 跳转 - print("AFTER_LOGIN_HREF:", c.evaljs("location.href")) - - -def main(): - stage = sys.argv[1] if len(sys.argv) > 1 else "recon" - ws_url, tid = new_target("about:blank") - c = CDP(ws_url) - c.send("Page.enable") - c.send("Runtime.enable") - - if stage == "recon": - c.nav(f"{ADMIN}/", settle=7) - c.shot("/tmp/aw_recon.png") - print(json.dumps(c.evaljs(JS_DUMP_LOGIN), ensure_ascii=False, indent=1)) - - elif stage == "login": - do_login(c) - c.nav(f"{ADMIN}/wanxiang/review", settle=6) - c.shot("/tmp/aw_queue.png") - print("QUEUE:", json.dumps(c.evaljs(JS_DUMP_QUEUE), ensure_ascii=False, indent=1)) - - elif stage == "approve": - do_login(c) - c.nav(f"{ADMIN}/wanxiang/review", settle=6) - c.shot("/tmp/aw_before.png") - before = c.evaljs(JS_DUMP_QUEUE) - print("BEFORE:", json.dumps(before, ensure_ascii=False)) - print("CLICK_PASS:", c.evaljs(js_click_pass(TARGET_GAME))) - time.sleep(2) - c.shot("/tmp/aw_dialog.png") - print("CONFIRM:", c.evaljs(JS_CONFIRM)) - time.sleep(4) # 等 API 回 + 刷新队列 - c.shot("/tmp/aw_after.png") - after = c.evaljs(JS_DUMP_QUEUE) - print("AFTER:", json.dumps(after, ensure_ascii=False)) - - c.close() - - -if __name__ == "__main__": - main() diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/backend_gw.py b/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/backend_gw.py deleted file mode 100644 index db76ec34..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/backend_gw.py +++ /dev/null @@ -1,233 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -staging 后端 HTTP 网关(D3 件)—— spec:HJ-AGENT-LOOP-EXEC-001 §7.1 - -封装编排器对 staging 单体(默认 http://100.64.0.7:48080,在跑勿动)的全部读写: -draft / generate / getTask / callback / package / manifest / publish / review / feed 探测。 - -鉴权配方(B1 已验):`Authorization: Bearer test1` + `tenant-id: 1`(staging mock; -内网环境地址与 mock 口令允许入库——repo 既有纪律)。 - -错误分类(对齐 §11 失败路径表): -- transport 类(网络异常/HTTP≥500/401/403/超时)→ BackendError(kind="transport"), - 默认重试 ×2 指数退避(F3/F4 口径); -- business 类(HTTP 200 但 CommonResult.code != 0)→ BackendError(kind="business"), - 不重试(F5:回调写链失败任务已被补偿置终态,重复重放同 traceId 必拒)。 -全部外部交互打中文日志(可追溯)。 -""" - -import hashlib -import json -import time -import urllib.error -import urllib.parse -import urllib.request - -# B1 已验 staging mock 鉴权(内网 staging 专用) -DEFAULT_BACKEND_BASE = "http://100.64.0.7:48080" -DEFAULT_TOKEN = "test1" -DEFAULT_TENANT_ID = "1" - -# HTTP 重试纪律(F3/F4:重试 ×2,指数退避 1s/2s) -HTTP_MAX_RETRIES = 2 -HTTP_TIMEOUT_SECONDS = 30 - -# 发布去向专区:staging 既有夹具 9001/9002 与 B3 种子全部为 launch_zone_id=0 / feed zone_id=0 -#(seed-staging-report.md §3.2 实测基线),批跑沿用同一专区 -DEFAULT_LAUNCH_ZONE_ID = 0 - - -class BackendError(Exception): - """后端调用失败。kind ∈ {"transport","business"};business 携带业务码 biz_code(如 1101003001)。""" - - def __init__(self, message, kind, http_status=None, biz_code=None): - super(BackendError, self).__init__(message) - self.kind = kind - self.http_status = http_status - self.biz_code = biz_code - - -def sha256_hex(text): - """对响应原文计算 sha256 hex(manifest 完整性核验 §9.5 用;UTF-8 字节面)。""" - return hashlib.sha256(text.encode("utf-8")).hexdigest() - - -class BackendGateway(object): - """staging 后端网关:CommonResult 解包 + 错误分类 + 重试 + 中文日志。""" - - def __init__(self, base=DEFAULT_BACKEND_BASE, token=DEFAULT_TOKEN, tenant_id=DEFAULT_TENANT_ID, - sleeper=time.sleep, opener=None, log=None): - self.base = base.rstrip("/") - self.token = token - self.tenant_id = tenant_id - self._sleep = sleeper - self._open = opener or urllib.request.urlopen - self._log = log or (lambda msg: print(msg, flush=True)) - - # ------------------------------------------------------------------ 基础请求 - - def _request(self, method, path, json_body=None, raw=False, retries=HTTP_MAX_RETRIES): - """ - 发请求并按错误分类返回。 - :param raw: True=返回响应原文字符串(manifest 端点不包 CommonResult,原样返回——§2.1); - False=解 CommonResult,code!=0 抛 business 类错误,否则返回 data。 - :param retries: transport 类重试次数(business 类一律不重试)。 - """ - url = self.base + path - body = None - headers = { - "Authorization": "Bearer " + self.token, - "tenant-id": self.tenant_id, - } - if json_body is not None: - body = json.dumps(json_body, ensure_ascii=False).encode("utf-8") - headers["Content-Type"] = "application/json" - - last_err = None - for attempt in range(1, retries + 2): - req = urllib.request.Request(url, data=body, method=method, headers=headers) - try: - with self._open(req, timeout=HTTP_TIMEOUT_SECONDS) as resp: - text = resp.read().decode("utf-8") - if raw: - return text - envelope = json.loads(text) - code = envelope.get("code") - if code != 0: - # business 类:后端业务异常(含回调写链失败补偿后的 ServiceException),不重试 - raise BackendError( - "后端业务错误 code=%s msg=%s(%s %s)" % (code, envelope.get("msg"), method, path), - kind="business", biz_code=code) - return envelope.get("data") - except BackendError: - raise # business 类直接上抛 - except urllib.error.HTTPError as ex: - detail = "" - try: - detail = ex.read().decode("utf-8", "replace")[:200] - except Exception: # noqa: BLE001 —— 读错误体失败不掩盖原错误 - pass - last_err = BackendError("HTTP %s(%s %s)%s" % (ex.code, method, path, detail), - kind="transport", http_status=ex.code) - self._log("[backend] 第 %d 次尝试 HTTP %s:%s %s" % (attempt, ex.code, method, path)) - except Exception as ex: # 网络超时/连接异常/JSON 解析失败 - last_err = BackendError("通道异常 %s(%s %s)" % (ex, method, path), kind="transport") - self._log("[backend] 第 %d 次尝试通道异常:%s %s(%s)" % (attempt, method, path, ex)) - if attempt <= retries: - self._sleep(1.0 * (2 ** (attempt - 1))) # 指数退避 1s/2s - raise last_err - - # ------------------------------------------------------------------ studio 链(submit 阶段) - - def create_draft(self, title, template_id, prompt): - """建草稿:POST /app-api/studio/draft → {id: sessionId, gameId, ...}(P-CRT-10/P-TPL-03)。""" - self._log("[backend] 建草稿 title=%s templateId=%s" % (title, template_id)) - return self._request("POST", "/app-api/studio/draft", { - "title": title, "templateId": template_id, "prompt": prompt, - }) - - def studio_generate(self, session_id, prompt): - """一句话生成:POST /app-api/studio/generate → 任务链 {id, aigcTaskId, gameId, ...}(P-CRT-01)。""" - self._log("[backend] 提交生成 sessionId=%s" % session_id) - return self._request("POST", "/app-api/studio/generate", { - "sessionId": session_id, "prompt": prompt, - }) - - def get_aigc_task(self, task_id): - """生成任务轮询:GET /app-api/aigc/task/{id} → AigcTaskRespVO(含 traceId/status/versionId)。""" - return self._request("GET", "/app-api/aigc/task/%d" % int(task_id)) - - # ------------------------------------------------------------------ 回调(写入面唯一交叉点,§3) - - def dify_callback(self, payload, allow_retry=True): - """ - 伪装 Dify 出参回调:POST /admin-api/aigc/dify/callback(契约 #6 output)。 - transport 类按 F4 重试 ×2;business 类按 F5 不重试(任务已终态拒重入,resume 走新任务)。 - """ - self._log("[backend] Dify 回调 traceId=%s status=%s" % (payload.get("traceId"), payload.get("status"))) - return self._request("POST", "/admin-api/aigc/dify/callback", payload, - retries=HTTP_MAX_RETRIES if allow_retry else 0) - - # ------------------------------------------------------------------ runtime 取包(§9.5 前置核验) - - def get_package(self, version_id, scene="preview"): - """取包清单:GET /app-api/runtime/package/{versionId}?scene= → RuntimePackageRespVO(含 checksum)。""" - return self._request("GET", "/app-api/runtime/package/%d?scene=%s" - % (int(version_id), urllib.parse.quote(scene))) - - def get_manifest_raw(self, version_id): - """取 manifest 原文:GET …/manifest(原样字符串返回,不包 CommonResult——§2.1 已核)。""" - return self._request("GET", "/app-api/runtime/package/%d/manifest" % int(version_id), raw=True) - - # ------------------------------------------------------------------ 发布段(§7.6,仅 accept 走) - - def submit_publish(self, game_id, version_id, launch_zone_id=DEFAULT_LAUNCH_ZONE_ID): - """①提交发布:POST /app-api/project/{gameId}/publish → {admitted, gates...}(门禁聚合)。""" - self._log("[backend] 提交发布 gameId=%s versionId=%s zone=%s" % (game_id, version_id, launch_zone_id)) - return self._request("POST", "/app-api/project/%d/publish" % int(game_id), { - "versionId": int(version_id), "launchZoneId": int(launch_zone_id), - }) - - def review_approve(self, game_id, version_id, reason): - """②审核通过:POST /admin-api/project/review decision=1(staging 自动批,reason 即审计线索——§7.6)。""" - self._log("[backend] 审核通过 gameId=%s versionId=%s" % (game_id, version_id)) - return self._request("POST", "/admin-api/project/review", { - "gameId": int(game_id), "versionId": int(version_id), "decision": 1, "reason": reason, - }) - - def get_project(self, game_id): - """项目详情:GET /app-api/project/{id}(postcheck 用:status=4 已发布)。""" - return self._request("GET", "/app-api/project/%d" % int(game_id)) - - # ------------------------------------------------------------------ feed(postcheck/探活) - - def feed_stream(self, size=30): - """feed 流:GET /app-api/feed/stream?size=(B3 assert_feed 配方;postcheck 金丝雀可见性)。""" - data = self._request("GET", "/app-api/feed/stream?size=%d" % int(size)) - # 兼容字段名定位卡片列表(沿 assert_feed.py 配方) - if isinstance(data, dict): - for key in ("list", "cards", "items", "records"): - if isinstance(data.get(key), list): - return data[key] - if isinstance(data, list): - return data - raise BackendError("feed/stream 响应未找到卡片列表字段:%r" % (data,), kind="business") - - def feed_find_game(self, game_id, page_size=30, max_pages=10): - """feed 流逐页查找指定 gameId(postcheck 金丝雀可见性专用)。 - - 修复背景(批 batch-001 P1 误熔断):后端 /app-api/feed/stream 为 cursor 分页且单页上限 30, - 原 postcheck 用 size=50 直接被参数校验拒(code=400「单页条数不能超过 30」)→ 连续 2 条 - accept_publish_fail → F10 误停发布段。本方法按 cursor 翻页直到找到 / 翻尽 / 达页数上限, - 同时消灭「feed 超过一页后新游戏(quality 基线 0 沉底)落在首页外被误判不可见」的同款隐患。 - - :param game_id: 目标游戏 ID - :param page_size: 单页条数(钳制到后端上限 30) - :param max_pages: 安全页数上限(防异常 cursor 死循环) - :return: True=在流中找到该游戏;False=翻尽未找到 - """ - size = min(int(page_size), 30) # 后端单页硬上限 30,超出会 400 - cursor = None - for _ in range(int(max_pages)): - path = "/app-api/feed/stream?size=%d" % size - if cursor: - path += "&cursor=%s" % cursor - data = self._request("GET", path) - cards = data.get("list") if isinstance(data, dict) else None - if not isinstance(cards, list): - raise BackendError("feed/stream 响应未找到 list 字段:%r" % (data,), kind="business") - if any(c.get("gameId") == game_id for c in cards): - return True - # nextCursor 空串=已到底(T-FED-06 契约);hasMore=False 同义兜底 - cursor = data.get("nextCursor") - if not cursor or data.get("hasMore") is False: - return False - # 翻页达上限仍未找到:如实返回不可见(不抛错,交由 postcheck 记 fail 留证) - return False - - def probe_staging(self): - """staging 探活(F9/§7.4-3 前置):GET /app-api/feed/zones 只读端点。失败抛 BackendError。""" - self._request("GET", "/app-api/feed/zones") - self._log("[backend] staging 探活通过:%s" % self.base) - return True diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/dash_walk.py b/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/dash_walk.py deleted file mode 100644 index 22160801..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/dash_walk.py +++ /dev/null @@ -1,276 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -看板「数据接口建设中→转真」专项 CDP 走查(mini-desktop 本地驱 headless chrome:9222 → studio:4173)。 -复用 studio_walk.py 的最小 CDP 客户端范式(websocket-client 直驱),但聚焦数据看板三处接线核验: - · 完玩率 ← telemetry /my/summary completionRate - · 广告收益 ← trade /my/income-summary totalNet(分→元) - · 七日趋势 ← telemetry /my/game-stat/trend?days=7 真柱状 - -为同时取证「真数据」与「真实空态」,本脚本登录两个账号各跑一遍看板: - A) 18818260272/8888 —— 该创作者名下作品有近 7 日聚合(completionRate=0.5/trend 2 天有数)→ 看板显真值+真柱。 - B) 13800001234/8888 —— 无作品 → 看板显真实空态(完玩率 0%/¥0.00/趋势空态),证明无数据不伪造。 - -取证手段(双锚):① Network 域抓三端点真响应体(证 UI 真消费 live 数据); - ② 读看板新 DOM 选择器(.pending-row__value / .trend__bar / .trend__empty)证渲染落地。 -不改后端/DB,仅 UI 走查取证。 -""" -import json, base64, time, urllib.request -import websocket # websocket-client - -CDP_HTTP = "http://localhost:9222" -APP = "http://localhost:4173" -SHOT_DIR = "/tmp/dash-wired" - -# 三个目标端点(用于从 Network 事件里挑出对应响应) -TARGET_EPS = [ - "/app-api/telemetry/my/summary", - "/app-api/trade/my/income-summary", - "/app-api/telemetry/my/game-stat/trend", -] - - -def new_target(url="about:blank"): - req = urllib.request.Request(f"{CDP_HTTP}/json/new?{url}", method="PUT") - d = json.load(urllib.request.urlopen(req, timeout=10)) - return d["webSocketDebuggerUrl"], d["id"] - - -class CDP: - def __init__(self, ws_url): - self.ws = websocket.create_connection(ws_url, max_size=None, timeout=45, - suppress_origin=True) - self._id = 0 - self.console = [] - # requestId -> {url} ;以及 requestId -> 响应体(按需 getResponseBody 拉) - self._net_url = {} - self._net_done = [] # [{url, requestId, status}] - - def send(self, method, params=None, timeout=45): - self._id += 1 - mid = self._id - self.ws.send(json.dumps({"id": mid, "method": method, "params": params or {}})) - end = time.time() + timeout - while time.time() < end: - self.ws.settimeout(max(0.1, end - time.time())) - try: - msg = json.loads(self.ws.recv()) - except Exception: - continue - self._collect(msg) - if msg.get("id") == mid: - if "error" in msg: - raise RuntimeError(f"{method}: {msg['error']}") - return msg.get("result", {}) - raise TimeoutError(method) - - def _collect(self, msg): - m = msg.get("method") - if m == "Network.requestWillBeSent": - rid = msg["params"]["requestId"] - url = msg["params"]["request"]["url"] - self._net_url[rid] = url - elif m == "Network.responseReceived": - rid = msg["params"]["requestId"] - url = msg["params"]["response"]["url"] - status = msg["params"]["response"]["status"] - if any(ep in url for ep in TARGET_EPS): - self._net_done.append({"url": url, "requestId": rid, "status": status}) - elif m == "Runtime.consoleAPICalled": - t = msg["params"].get("type") - if t in ("error", "warning"): - args = msg["params"].get("args", []) - txt = " ".join(str(a.get("value", a.get("description", ""))) for a in args)[:240] - self.console.append({"level": t, "text": txt}) - elif m == "Runtime.exceptionThrown": - d = msg["params"].get("exceptionDetails", {}) - self.console.append({"level": "error", "text": (d.get("text") or "")[:240]}) - - def drain(self, secs=1.0): - end = time.time() + secs - while time.time() < end: - self.ws.settimeout(max(0.05, end - time.time())) - try: - msg = json.loads(self.ws.recv()) - except Exception: - continue - self._collect(msg) - - def evaljs(self, expr, timeout=45): - r = self.send("Runtime.evaluate", - {"expression": expr, "returnByValue": True, "awaitPromise": True}, timeout) - if "exceptionDetails" in r: - return {"__js_error__": json.dumps(r.get("exceptionDetails"), ensure_ascii=False)[:300]} - return r.get("result", {}).get("value") - - def nav(self, url, settle=5): - self.send("Page.navigate", {"url": url}) - time.sleep(settle) - self.drain(0.8) - - def shot(self, name): - r = self.send("Page.captureScreenshot", {"format": "png"}) - path = f"{SHOT_DIR}/{name}" - with open(path, "wb") as f: - f.write(base64.b64decode(r["data"])) - return path - - def get_target_bodies(self): - """对捕获到的三端点响应逐个 getResponseBody,返回 [{url,status,body}]。""" - out = [] - # 去重:同一 url 取最后一次 - latest = {} - for n in self._net_done: - latest[n["url"].split("?")[0]] = n - for url_key, n in latest.items(): - body = None - try: - r = self.send("Network.getResponseBody", {"requestId": n["requestId"]}) - body = r.get("body") - if r.get("base64Encoded"): - body = base64.b64decode(body).decode("utf-8", "ignore") - except Exception as e: - body = f"" - out.append({"url": url_key, "status": n["status"], "body": (body or "")[:300]}) - return out - - def reset_net(self): - self._net_url.clear() - self._net_done.clear() - - def close(self): - try: - self.ws.close() - except Exception: - pass - - -# ---------- JS 片段 ---------- - -def js_set_by_ph(ph, val): - return r"""(()=>{ - const el=[...document.querySelectorAll('input,textarea')].find(e=>(e.placeholder||'').includes('%s')); - if(!el) return 'no-input:%s'; - const tag=el.tagName==='TEXTAREA'?window.HTMLTextAreaElement:window.HTMLInputElement; - const setter=Object.getOwnPropertyDescriptor(tag.prototype,'value').set; - setter.call(el, %s); - el.dispatchEvent(new Event('input',{bubbles:true})); - el.dispatchEvent(new Event('change',{bubbles:true})); - return 'set:'+(el.value||'').slice(0,20); - })()""" % (ph, ph, json.dumps(val)) - - -JS_CHECK_AGREE = r"""(()=>{ - const cb=[...document.querySelectorAll('input[type=checkbox]')][0]; - if(!cb) return 'no-checkbox'; - if(!cb.checked) cb.click(); - return 'agree:'+cb.checked; -})()""" - - -def js_click_btn(text): - return r"""(()=>{ - const bs=[...document.querySelectorAll('button')]; - const b=bs.find(e=>(e.innerText||'').replace(/\s+/g,'').includes('%s')); - if(b){b.click(); return 'clicked:%s';} - return 'notfound:%s'; - })()""" % (text, text, text) - - -# 退出登录(清 localStorage 真 token,下一账号干净登录)——直接清键,最稳 -JS_LOGOUT = r"""(()=>{ - Object.keys(localStorage).filter(k=>/token/i.test(k)).forEach(k=>localStorage.removeItem(k)); - return 'cleared:'+Object.keys(localStorage).filter(k=>/token/i.test(k)).length; -})()""" - - -# 提交态探针:列出所有按钮文案 + 提交按钮 disabled 状态(诊断点击是否落到提交而非 Tab) -JS_SUBMIT_STATE = r"""(()=>{ - const bs=[...document.querySelectorAll('button')].map(e=>({ - txt:(e.innerText||'').replace(/\s+/g,''), disabled:e.disabled})); - const submit=bs.find(b=>b.txt.includes('登录/注册')||b.txt.includes('注册并登录')); - return {buttons:bs, submit}; -})()""" - - -# 看板「转真」核验:读新 DOM 选择器(运营指标真值 + 趋势真柱/空态) -JS_DASH = r"""(()=>{ - const metrics=[...document.querySelectorAll('.metric')].map(m=>({ - label:(m.querySelector('.metric__label')||{}).innerText||'', - val:(m.querySelector('.metric__val')||{}).innerText||''})); - // 运营指标行:label + 真值(完玩率/广告收益) - const ops=[...document.querySelectorAll('.pending-row')].map(r=>({ - label:(r.querySelector('.pending-row__label')||{}).innerText||'', - value:(r.querySelector('.pending-row__value')||{}).innerText||'', - // 旧占位徽标是否还在(应为 0:已转真) - hint:(r.querySelector('.pending-row__hint')||{}).innerText||''})); - // 趋势:真柱数量 + 每根柱 title(含数值)+ 空态文案 - const bars=[...document.querySelectorAll('.trend__bar')].map(b=>b.getAttribute('title')||''); - const xlabels=[...document.querySelectorAll('.trend__xlabel')].map(e=>e.innerText); - const emptyTitle=(document.querySelector('.trend__empty-title')||{}).innerText||''; - // 全页是否还残留「数据接口建设中」字样(应为 false) - const bodyHasUnderConstruction=(document.body.innerText||'').includes('数据接口建设中'); - return {metrics, ops, barCount:bars.length, barTitles:bars, xlabels, - trendEmptyTitle:emptyTitle, bodyHasUnderConstruction}; -})()""" - - -def out(tag, obj): - print(f"@@{tag}@@ " + json.dumps(obj, ensure_ascii=False)) - - -def login(c, mobile): - """走真实登录表单登录指定手机号(码恒 8888),返回 after-login href。""" - c.nav(f"{APP}/login", settle=6) - print(f"--[login {mobile}]--") - print("SET_MOBILE:", c.evaljs(js_set_by_ph("手机号", mobile))) - print("SET_CODE:", c.evaljs(js_set_by_ph("短信验证码", "8888"))) - print("CHECK_AGREE:", c.evaljs(JS_CHECK_AGREE)) - time.sleep(0.4) - print("CANSUBMIT_PROBE:", c.evaljs(JS_SUBMIT_STATE)) - # 提交按钮文案=「登录 / 注册」(去空白=登录/注册);精确匹配避免误中 Tab「验证码登录」 - print("CLICK_SUBMIT:", c.evaljs(js_click_btn("登录/注册"))) - time.sleep(6) - c.drain(1.0) - href = c.evaljs("location.href") - print("AFTER_LOGIN_HREF:", href) - return href - - -def walk_dashboard(c, tag, mobile): - """登录 mobile → 进看板 → 抓三端点响应 + 读 DOM + 截图。""" - login(c, mobile) - c.reset_net() # 只抓看板这一次的端点响应 - c.nav(f"{APP}/dashboard", settle=6) - c.drain(1.5) # 多等一会确保三端点都回 - shot = c.shot(f"dash_{tag}.png") - out(f"DASH_{tag}_DOM", c.evaljs(JS_DASH)) - out(f"DASH_{tag}_NET", c.get_target_bodies()) - print(f"SHOT_{tag}:", shot) - # 退出登录,给下一账号让位 - c.evaljs(JS_LOGOUT) - - -def main(): - import os - os.makedirs(SHOT_DIR, exist_ok=True) - ws_url, tid = new_target("about:blank") - c = CDP(ws_url) - c.send("Page.enable") - c.send("Runtime.enable") - c.send("Log.enable") - c.send("Network.enable") - - # A) 有数据创作者:看板显真值 + 真柱 - walk_dashboard(c, "A_creator_withdata", "18818260272") - # B) 无数据账号:看板显真实空态(不伪造) - walk_dashboard(c, "B_player_empty", "13800001234") - - c.drain(0.5) - out("CONSOLE_ERRORS", c.console[:30]) - c.close() - print("=== DASH_WALK_DONE ===") - - -if __name__ == "__main__": - main() diff --git a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/evalflow.py b/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/evalflow.py deleted file mode 100644 index 31760241..00000000 --- a/docs/agent-specs/2026-06-09-agent-loop-v1/orchestrator/evalflow.py +++ /dev/null @@ -1,251 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -eval 资产回流(D3 件)—— spec:HJ-AGENT-LOOP-EXEC-001 §7.7(每批强制,非可选) - -回流目标目录:contracts/prompts/eval//(D1 交付目录骨架;缺目录时本模块自建)。 -每条 Verdict 按其 evidence.promptVersions 涉及的 prompt id 追加两文件: -- inputs.jsonl:一行 = 该 prompt 当次调用的输入变量快照(含 idea/banned_list/findings, - 兼容 prompt 治理 §5.3 inputs.jsonl 字段); -- labels.jsonl:一行 = {designId, rootDesignId, decision, reasons, round, batchId} - (kill 负例 / fix 前后对照 / accept 正例)。 - rootDesignId 口径(§16 D2-a 裁决):designId 哈希因子含 round,fix 前后(round 0 与 1) - 两行 designId **必不同**——以 rootDesignId(=round0 的 designId)为父子关联键做对照; - 映射源 = 账本阶段行 data.rootDesignId(run_batch 落账时携带),缺位时回落 designId 自身 - (round=0 行的 root 即自身)。 - -幂等:两文件均 append-only;以 seedKey/(batchId,designId,promptId,round) 为去重键, -resume 重跑同批不会写出重复行。 - -种子(§7.7):把 C1 spike 52 条(spike-eval.csv)一次性转入 eval/config.clicker-designer/: -- 全部 52 条入 inputs.jsonl,标 source=legacy_spike; -- 仅 clicker 13 条带 label。诚实口径:spike 仅验证了「结构层」(schema_valid),无实玩/对抗证据, - 故 label 的 decision 取 "schema_pass"(受控的 legacy 专用值)而非伪造 accept—— - 避免把未经四条 AND 验证的样本污染为正例。 -""" - -import csv -import json -import os - -import ledger as ledger_mod - -# 种子批次的固定 batchId(labels 行可溯源) -SPIKE_SEED_BATCH_ID = "c1-spike-52" -# 种子 label 的诚实 decision 值:spike 只验了结构层,不得伪造 accept -SPIKE_SEED_DECISION = "schema_pass" - - -class EvalFlowError(Exception): - """eval 回流失败(目录不可写/数据形状异常)。""" - - -def _existing_keys(path, key_field): - """扫描既有 JSONL 的去重键集合(文件不存在返回空集;append-only 文件行数有限,线性扫描足够)。""" - keys = set() - if not os.path.exists(path): - return keys - with open(path, "r", encoding="utf-8") as fh: - for line in fh: - line = line.strip() - if not line: - continue - try: - obj = json.loads(line) - except ValueError: - continue # 坏行跳过(不阻断回流) - if obj.get(key_field): - keys.add(obj[key_field]) - return keys - - -def _append_jsonl(path, rows, key_field): - """带去重键的 append(幂等);返回实际写入条数。""" - os.makedirs(os.path.dirname(path), exist_ok=True) - existing = _existing_keys(path, key_field) - written = 0 - with open(path, "a", encoding="utf-8") as fh: - for row in rows: - key = row.get(key_field) - if key and key in existing: - continue # 幂等:已写过的键跳过 - fh.write(json.dumps(row, ensure_ascii=False) + "\n") - existing.add(key) - written += 1 - return written - - -# ============================== 批账本 → eval 回流(每批强制) ============================== - -def flow_batch(ledger_path, eval_root, log=None): - """ - 从批账本回流 eval 资产。 - 数据流:verdict 行给 labels;该 designId 的 design/fix/adversary 阶段 ok 行中 - 记录的 promptId+inputs 快照给 inputs(run_batch 在阶段 data 中落 {"promptId","promptVersion","inputs"})。 - 返回 {"inputs": 写入条数, "labels": 写入条数}。 - """ - log = log or (lambda msg: print(msg, flush=True)) - rows, bad = ledger_mod.Ledger.load_rows(ledger_path) - if bad: - log("[evalflow] 账本存在 %d 条坏行(崩溃残行),已跳过" % bad) - - # 0) 建 designId → rootDesignId 映射(§16 D2-a:fix 前后对照关联键): - # 源=阶段行 data.rootDesignId;verdict 行本身按契约(additionalProperties:false)不携带该键 - root_map = {} - for row in rows: - if row.get("type") != "stage": - continue - data = row.get("data") or {} - if row.get("designId") and data.get("rootDesignId"): - root_map[row["designId"]] = data["rootDesignId"] - - # 1) 收集每 designId 的 LLM 调用输入快照(阶段行里由 run_batch 落好) - snapshots = [] # [{promptId, promptVersion, inputs, designId, round, batchId}] - for row in rows: - if row.get("type") != "stage" or row.get("status") != "ok": - continue - data = row.get("data") or {} - if row.get("stage") in ("design", "fix", "adversary") and data.get("promptId"): - snapshots.append({ - "promptId": data["promptId"], - "promptVersion": data.get("promptVersion"), - "designId": row.get("designId"), - "round": row.get("round"), - "batchId": row.get("batchId"), - "inputs": data.get("inputs") or {}, - }) - - # 2) verdict 行 → labels(按 evidence.promptVersions 的 prompt id 分发) - inputs_written = 0 - labels_written = 0 - for row in rows: - if row.get("type") != "verdict": - continue - design_id = row.get("designId") - prompt_versions = (row.get("evidence") or {}).get("promptVersions") or {} - for prompt_id in prompt_versions: - label_row = { - # 去重键:批+设计+轮次(同一终判只落一行) - "evalKey": "%s:%s:%s:%s" % (row.get("batchId"), design_id, prompt_id, row.get("round")), - "designId": design_id, - # rootDesignId:round0 行映射缺位时即自身(§16 D2-a) - "rootDesignId": root_map.get(design_id, design_id), - "decision": row.get("decision"), - "reasons": row.get("reasons"), - "round": row.get("round"), - "batchId": row.get("batchId"), - } - labels_written += _append_jsonl( - os.path.join(eval_root, prompt_id, "labels.jsonl"), [label_row], "evalKey") - - # 3) 输入快照 → inputs.jsonl(按快照自身的 promptId 归桶) - # 行形态对齐 D1 eval README:变量快照平铺到顶层(idea/banned_list/findings/template_schema 等), - # 与元数据键(designId/round/batchId/promptVersion/evalKey)同级;变量名与元数据键无冲突(已核) - for snap in snapshots: - input_row = { - "evalKey": "%s:%s:%s:%s" % (snap["batchId"], snap["designId"], snap["promptId"], snap["round"]), - "designId": snap["designId"], - "round": snap["round"], - "batchId": snap["batchId"], - "promptVersion": snap["promptVersion"], - } - for key, value in (snap["inputs"] or {}).items(): - input_row.setdefault(key, value) # setdefault 防御:变量名万一与元数据键撞车时元数据优先 - inputs_written += _append_jsonl( - os.path.join(eval_root, snap["promptId"], "inputs.jsonl"), [input_row], "evalKey") - - log("[evalflow] 回流完成:inputs 新增 %d 行,labels 新增 %d 行(目标 %s)" - % (inputs_written, labels_written, eval_root)) - return {"inputs": inputs_written, "labels": labels_written} - - -# ============================== C1 spike 52 条种子一次性转入(§7.7) ============================== - -def seed_spike(csv_path, eval_root, log=None): - """ - 把 spike-eval.csv(C1 52 条)转入 eval/config.clicker-designer/: - - 52 条全部入 inputs.jsonl(source=legacy_spike;非 clicker 39 条仅作输入语料); - - 仅 clicker 13 条写 labels.jsonl(decision=schema_pass 诚实口径,理由见模块头注释)。 - 幂等:seedKey=legacy: