Refactor code structure for improved readability and maintainability

This commit is contained in:
DKChan committed 2026-11-09 02:53:10 +08:00
1 parent 6bfd8009a2
commit a710477be2
47 files changed
+5357 -5

No files matched your search

+120
View File
@@ -0,0 +1,120 @@
---
name: iter
description: g-plan2 迭代开工总指挥。当用户输入 /iter <迭代号>、或要求"开迭代N/启动迭代N/发射迭代N/给我迭代N的 goal prompt/开始迭代N的开发"时使用——读 roadmap 迭代行与对应需求卡片,检查开工门与待裁点,按项目既定批次执行模式(U0/worktree/闸序列/停机规则/收口五步)组装开工面并直接开始开发。无参数或只说"/iter"时,呈报当前 roadmap 全部迭代的就绪状态供用户选号。
---
# /iter——迭代开工总指挥(g-plan2 批次执行制)
你(执行会话)现在就是本迭代的编排者+施工者。用户输入 `/iter <N>` 即 **U0 开工令**——门全解且零待裁点时不要再问"可以开工吗",直接按本流程执行。唯一的合法前置停顿是第 2 步检查不通过。
> **发射形态(与内置 /goal 的组合)**:/goal 是 harness 内置命令(会话级目标+续跑提醒+完成校验),由用户侧设置。推荐发射形态=`/goal 按 iter 技能执行迭代 <N>,直至总收口全绿`——/goal 提供"不到目标不收工"的机制级驱策与完成校验,本技能提供批次流程。本技能单独调用亦自足(停机/闸纪律已内建),但目标完成校验只有 /goal 能提供。
> **批性质(2026-10-17 用户立规,最高优先)**:本技能执行的是**代码实现批**。批内**禁写、禁改、禁新增 `design/` 整个目录与根规则文件(`AGENTS.md`/`roadmap.md`)**——那里全是设计文档与规范,对本批**只读**,是写测试与实现代码的输入依据,不是产出物。需要往外交代的东西一律落 `reports/`(实现报告/GDD 反哺点清单,细则见 `reports/README.md`);发现该改文档的点,写进反哺点清单并停机呈报,**不落笔**。2026-10-18 用户裁:根目录会话状态文件已废除,本批不再有任何「例外可写」的文件。2026-10-29 补:`game/tests/README.md`(能力清单)同属禁写面——能力行增删归写卡段(写卡时当场入表,test-conventions §8.3;「最后验证批次」列已废除),本批只读。
>
> **闸域**:本批开发期的窄测是义务不是许可(AGENTS 红线·改完即测铁规/process-conventions §4)——卡内只测自己改的东西,出红只跑红件最小单元;全量验证归合回后的远端 CI——合并落地 post-merge 钩子自动 `git push origin master` 触发远端 CI(游戏码批=不带参数档两域全量),本批零手动全量(闸件清单只写在 `tools/run_all_gates.sh` 头注一处,本文不重列)。
## 第 1 步:定位迭代与读卡
1. 读 `roadmap.md` 主路线表,找到「迭代 <N>」行(注意可能是 `迭代 N` 或 `迭代 N+` 形态;一行可以含多卡,卡号⓪①②③…都在行内)。
2. 逐份读行内引用的需求卡片(`reports/需求卡片-*.md`),以**需求卡片最新版**为准;行内描述与需求卡片冲突时,需求卡片优先,冲突本身呈报。
3. 无参数调用时:扫全部迭代行,输出一行一迭代的就绪表(迭代号/卡数/估时/门状态/待裁点数),等用户选号,结束本轮。
## 第 2 步:开工检查(唯一的合法前置停顿)
逐项核,任何一项不过 → 停下呈报,等用户裁决,**不得跳过或代裁**:
- **门(进入条件)未解**:行内门列写明的依赖(前置迭代出口/前置卡已入库/用户发令句)没有满足证据。典型:门列含「用户发令(未排期)」「待用户裁定」→ 必须停。
- **待裁点 ≠ 0**:需求卡片声明待裁点未全裁,或行内有「待用户裁甲/乙」句。
- **迭代估时总量 <5 个工作日**:迭代行状态应处「冻结待凑批」——处待开工/进行中且总量不足即编排缺陷,拒启动并呈报凑批方案(可补卡清单)等用户裁(2026-10-25 两层模型:卡片无工作量门槛,冻结线属迭代层)。
- **需求卡片缺失**:行内引用的需求卡片文件不存在或版本明显滞后于行内裁决记录。
- **改动—验收对照表缺失或不闭合(2026-10-11 立,2026-10-21 升级)**:需求卡片没有改动—验收对照表,或对照表有空行(无真实入口、无判据绑定面),或 T 卡内无对应验收条目 → 不过,停工呈报。**判定口径:每个需求点至少一行;每行必须有落点、真实入口、判据绑定面**——施工性质的验证工作(如「MC 对账适配」)、完成定义里的笼统验证手段(如「MC 对拍留证」)都不算。禁拿 AGENTS.md「新功能必配新测试」红线代偿——那条只保证写了测试,不保证测得对。2026-10-21 前的旧卡缺对照表 → 停工,退回写卡段补,补完再开工。**判据出处行锚(2026-11-05 起):生效日后(文件名日期不早于该日)的卡,对照表「需求点」格须带 `<现行文档相对路径>:<行号>` 判据出处行锚(机检=pipeline_gate C5)——行缺锚或锚指向不存在=停工呈报退写卡段;旧卡不回头改,开工前由写卡段补挂**(test-conventions §8.3)。
- **自洽扫描(轻量,非拷打)**:声明零待裁点≠逻辑无冲突——读卡后快速核三类:①需求卡片内部矛盾(范围/契约/估时/裁决记录互相打架);②需求卡片与 roadmap 行冲突(两处说法不一致);③事实抽查——从需求卡片「现状考证」里抽 3-5 处关键 file:line 到现行代码核对(防需求卡片成文后代码已被其他批改掉,需求卡片变质)。发现疑似冲突 → 逐条列单呈报(哪里矛盾/两种读法各是什么/建议哪边改),**用户裁决后才开工**;零发现则直接通过,不为此拉长开工。全量拷打(/grilling)不在此步做——那是需求卡片成文时的责任,这里只兜网;但**本步必查卡里留没留复核的记录**(见下条),记录不在=上游没跑,停工退写卡段。
- **复核记录缺失(2026-11-05 用户立规)**:需求卡片内没有「复核记录」节、或该节申报的复核报告文件在 `reports/` 盘上不存在 → 不过,停工呈报退回写卡段。本步不代跑复核、不代补记录、不把缺记录的卡当旧卡放行;生效=卡片文件名日期 ≥2026-11-06(与 `tools/pipeline_gate.py` 该条卡片判据同口径),更早的卡不回头改。
- **真人检测遗留项不算门(2026-10-12 用户立规)**:往期迭代/批次登记未验的实机目检项(体验验证清单/实现报告总清单在册)不构成开工阻塞——开工呈报带一句提醒即可,禁为此停工等验。
- **设计闭合核验(2026-10-18 五段流水线立规)**:逐卡核需求卡片的设计事实源声明——独立小节「## 设计事实源」或头部「来源:…(唯一事实源:…)」句,二者得一即合格(**禁按小节名字面判死:库内合规卡多数用后者写法**;全文两词皆无=不过,机检见 `tools/pipeline_gate.py` 判据 C2)——①卡片声明的事实源文件真实存在(相对仓库根);②文档源版本与待办清单对应条目状态里的闭合凭据一致(工程类卡=证据指认与待办清单条目实况一致);③roadmap 迭代行卡片列路径与卡片实际路径一致;④行内预计周期形态合规(「≈N 个工作日」)且量值合规——5–10 个工作日为常规;10–20 个工作日须随带日期特批标记;超过 20 个工作日=缺陷(硬上限,特批不放行);低于 5 个工作日=该行状态必须为「冻结待凑批」,处待开工/进行中即编排缺陷(2026-10-25 两层模型:卡片无门槛、迭代层冻结线)。任一不过 → 停工呈报——这是编排段(iter-plan)缺陷,不是本技能能修的,禁代改卡片或迭代行凑绿。
- **执行形态判定(2026-10-22 用户立规)**:读各卡「前置依赖与并行性」节(各卡 §0)定本迭代执行形态——默认=整迭代单工作区、各卡按 roadmap 行卡片列格内顺序串行推进;仅当卡片声明可并行(且互核无同文件交集)时,该卡组走逐卡工作区例外路径(第 4 步)。判定结果在开工呈报里带一句。
呈报格式:一行一项(哪条不满足/证据在哪/需要用户做什么)。全部通过则宣布「迭代 <N> 开工(U0=本次调用)」进入第 3 步。
## 第 3 步:T0 开工(主区核对+建迭代工作区)
1. `git status` 归属核对:主区脏文件分两类——**本迭代定义面**(下条列名文件)与**其他在飞遗产**(其余一切)。除定义面外一律禁碰、禁代提交、禁还原。
2. **定义面已入库**(目的:worktree 从旧 HEAD 检出必须看得到定义;后续合并不被脏 roadmap 阻塞):`git add` 仅限 roadmap.md、待办清单.md、本迭代引用的全部需求卡片文件——**指名道姓,禁扫全仓**——单独一笔提交,message=`docs: 迭代<N>定义已入库`。注意:这一步是**搬运别的会话已写好的定义文件**,不是本批撰写文档(批性质禁令照旧生效);该笔单独成提交,别和代码提交混在一起,否则合回后 CI 会把本批 diff 推定跨两域、两域都验。
3. **建迭代工作区(整迭代只此一个)**:`git worktree add ../g-plan2-iter<N> -b iter<N>`;冷检出四件套照坑速查执行(拷主区 `game/assets/art/` 与 `*.import` 边车 → `--headless --editor --quit` 刷导入 → `tools/setup_worktree_userdir.sh` 建本区独立 user 目录;闸机 code 域起手自检会自动兜底同步素材与熵增预检——`tools/sync_worktree_assets.sh`,2026-10-30 工程批——四件套照做,脚本兜防漏)。第 4 步各卡都在此工作区内推进;整迭代禁开第二个 worktree(并行例外见第 4 步)。**检出工作区零测试,直接开工**(2026-10-22 频率规则;全量验证归合回后远端 CI——合并落地 post-merge 钩子推送自动跑,T0 不做基线复读,红绿归因由「卡内只测自己改的东西」与闸机基线比对机制承担)。
## 第 4 步:迭代内逐卡推进(单工作区)
整迭代一个工作区(第 3 步已建),各卡都在其中推进。执行顺序=roadmap 迭代行卡片列格内顺序;卡片「前置依赖与并行性」节声明可并行的卡组走下方例外路径,其余串行。何时该把活分出去见下面「子代理使用口径」。
1. **读卡施工**:需求卡片 T 卡逐轮推进——读卡→对事实源(file:line 复核)→实装(**验收测试随对应 T 卡同轮落地,禁批末补写**;同轮把实际对照表写进实现报告,测试写文件:行)→本卡验收测试跑绿、读数写进该笔提交(AGENTS 红线·改完即测铁规)→提交(代拍板随 commit 记录)→进度记录→下一轮。**卡内只测自己改的东西**(2026-10-22 频率规则):本卡新增/改动的验收测试自己跑绿、读数写进该笔提交才算这一步完成,没改的不测,轮内不跑闸壳全套。整迭代禁开第二个 worktree。**diff 里没有对照表行的行为改动必须标「非行为改动」或指向覆盖行;禁删断言、放宽阈值、缩小扫描面、把真实入口换成下层直调;判据绑不上可观测提交面=停卡呈报。**
2. **卡间依赖**:卡片声明「硬等/前置门」的后续卡,须等前置卡收口 commit 落本迭代分支且该卡验收测试跑绿后才准开 T1——迭代内不再以「合并进 master」为门(整迭代只合并一次,见第 5 步);跨迭代依赖仍由第 2 步开工检查核。
3. **并行例外(逐卡工作区,2026-10-22 用户立规)**:仅当卡片「前置依赖与并行性」节声明可并行、且开工检查核过无同文件交集时,该并行卡组按卡各开 worktree(`git worktree add ../g-plan2-<卡名worktree>`,冷检出四件套照坑速查),subagent 并发 ≤3(用户既定上限);并行卡各自收口合并进 master(现行逐卡机制原样保留在此例外路径),不受第 5 步「一次合并」约束。
4. **画面类需求的黄金图基线冻结(2026-11-05 立;2026-11-08 补审核落档)**:卡触碰画面呈现面的(判据=设计段出了预览图),实现轮把该画面纳入渲染闸机器面——截图采集清单扩项+实跑截图冻结进 `game/tests/golden/`;冻结(新建与换代同口径)前呈用户对照该卡预览图**逐张审核确认**,确认后触发原因写进当批提交说明(`tools/golden_baseline_refresh.sh`);此后渲染闸逐像素自动盯、零人工。义务细则=test-conventions §8.2「golden 测试项扩项」与「基线冻结审核关卡」;预览图(HTML/SVG 效果图)禁直接充当比对基线。**确认记录落 `game/tests/golden/README.md` 审核记录节(审核人+时间+基线清单);未审核的基线禁合回**——关卡同适用于非卡片批的基线操作(目录迁移/重构/容差修订等工程批,同样逐张呈报审核)。**基线跨平台单套(2026-11-08 用户裁:跨平台渲染必须一致,全平台对拍同一份基线,跨平台锯齿噪声由容差带吸收,禁加平台基线消化差异)**。
### 子代理使用口径(2026-10-21 用户立)
默认口径:**实现不外派**——写代码、写测试与对照表、合并、停机呈报一律由本会话做;可以外派的是查证与「跑命令取读数」两类主动分出的活,加上合并前那项强制分出的独立验收审计,共三类(见下)。外派出去的活都不改源码、不写实现产出物、不做裁断。并发上限只管数量,这条管范围。
**可以分出去的三类**(派出前先想清楚要它返回什么,指令里写死返回形态):
1. **只读考证**——第 2 步自洽扫描的第③项(从需求卡片「现状考证」抽 3-5 处关键 file:line 到现行代码核对)、跨模块找某符号的消费方与改动面。只要它汇报「文件:行 + 一句事实」,禁它改文件、禁它下「因此该怎么改」的结论;冲突判定与裁断仍在本会话。
2. **闸跑出红定位**——跑批输出量大,把「跑这条命令 + 报红的用例名与第一条失败断言 + 原样贴出那段读数」分出去,修复与复跑收回本会话。判「是不是本批新增红」以第 3 步基线读数为凭据,不拿子代理的「全绿」转述当凭据。
3. **合并前的独立验收审计**——见「独立验收审计」一节,属强制分出,实现者不能自审。
**不分出去的**:单卡实现轮本身、验收测试与改动—验收对照表的同轮编写、合并动作、停机呈报。原因:这几项依赖对卡片全文与设计事实源的完整理解,且施工铁律写了整迭代单工作区;子代理拿到的是转述,写出来的码无法保证对齐卡片。第 4 条的并发上限与执行形态判定管的是**多张卡怎么排先后、各用哪个工作区**,不是把实现交给子代理——判定为并行时,本会话逐卡开卡、逐卡施工,分出去的仍然只有上面那三类。
**取回纪律**:子代理的汇报当线索不当证据。凡涉及「跑绿了」「这条断言存在」「文件在这一行」的说法,本会话自己 grep 或自己跑一次才算数——「独立验收审计」一节不采信被审对象自述「已全绿」,正是同一条口径。
### 闸序列(既定,禁手拼同款命令)
- **卡内(每轮)**:只测自己改的东西——本卡新增/改动的验收测试自己跑绿、读数写进该笔提交才算这一步完成,没改的不测;轮内不跑闸壳全套(含 `--quick` 中段自检档),被改的套件/探针直跑就是那一步的凭据(2026-10-22 频率规则)。
- 调试期出红→只跑出红最小单元确认(单探针/单套件直跑),全套闸只绑批末出口(闸机轮次纪律,AGENTS.md 同源)。
- **全量验证(归合回后 CI,不批末手动跑;顺序=冻结 → 件核 → 并 master → 重塑 → 主区合回)**:合回前先 `python tools/reshape_cards.py` 把分支压成一卡一笔(master 台账每卡一行,工具自带树一致断言,详见 process-conventions §1.3);主区 `git merge --no-ff iter<N>` 落地后 post-merge 钩子自动推送 origin master 触发远端 CI 全量(不带参数档),本批零手动全量——`tools/run_all_gates.sh --code` 只在调试期出红后按最小单元复跑时手动用。MC 对拍(**仅当需求卡片要求且涉核心**)仍在批内做。CI 红则新开修复 worktree(`fix-<任务名>` 分支,免重塑免数卡)修复提交并主区合回,落地即由 post-merge 钩子复验追绿后删修复区(迭代区已随合回即删),「回执作废」语义已退役。**doc 三闸不在本批**(2026-10-17 起移出——本批不产文档,跑它们只会替别人背红)。
- 闸件清单、顺序与域划分只在该脚本里定义——开工时核对脚本头部现行文本,以它为准,本文不重列。
- **MC/verifier 跑批发起前必须用户批准**(硬规);需求卡片写「MC 零跑·静态论证」的卡禁发起跑批。
### 独立验收审计(合并前必做,2026-10-21 立)
由没参与实现的子代理,或用户点名的另一会话执行;只读需求卡片、实现报告里的实际对照表、本批 diff、测试文件和闸回执,不采信报告里的「已全绿」。单工作区口径(2026-10-22 起)下在迭代总收口、合并前执行一次,审计范围覆盖本迭代全部卡的 diff、对照表与验收断言。至少做三件事:
1. 逐行核对对照表:测试存在、尾缀能 grep 到、真实入口没有绕过改动点;
2. 抽查验收断言:每张 T 卡至少一条,核对断言在当轮真实跑批中执行且通过(闸回执与测试输出为凭);
3. 检查测试削弱:删除断言、放宽阈值、缩小扫描面、换下层直调,逐处要卡片申报或用户批准。
**审计深度按验收档分级(2026-11-04 起)**:逐卡读卡内「验收档:高/中/低」申报(test-conventions §8.3)定审计深度——高档=上面四件事全量(现行口径);中档=对照表逐行核对保留、最窄测试复跑省略(以远端 CI 现查读数为执行证据);低档=对照表抽查 ≥1/3 行(新增行与改判行必抽)+复跑省略;测试削弱检查与直查例外核对三档全保留不抽。未申报档位的卡(旧卡)按高档全量执行;档位存疑按高档。梯度表权威=test-conventions §8.7。
审计报告写 `reports/iter<N>-验收审计-<日期>.md`,逐行写「通过/缺漏/例外及依据」,逐卡标注验收档与实际执行深度。未通过不得合并;缺漏按实现段零裁断处理(停该卡,退回上游,禁实现期自裁)。审计核的是各卡施工那一步留下的跑批读数(AGENTS 红线·改完即测铁规),对已跑绿的同一份字节不另起跨域跑批——读数对不上才复跑。
### 停机规则
- **实现段零裁断(2026-10-18 换口径,取代原「禁自答/用户门/机制卡点」三条)**:实现段的输入在编排段出口已锁死(卡片零待裁点+设计闭合凭据齐+编排五查过)。施工中冒出需求卡片没写清的分歧、冲突、模糊点(含机制卡点)=**上游缺陷**——停该卡,呈报退回上游(写卡段或设计段),随呈报附「待办清单对应条目状态回退+缺口补记」拟稿(写清差什么才能重写卡);呈报=缺陷移交不是提问,须把分歧点、两种以上读法与建议案写全,不裸呈问题。**禁自答、禁内联提问求裁断、禁 idle 等待轮**;待办清单状态回退与缺口补记的落笔归上游段或用户——本批对 `design/` 只读,批性质禁令不因停机豁免。该卡停摆不阻塞同迭代其他卡,其余卡继续(单工作区口径:停摆卡不提交,其余卡继续施工;迭代收口合并须等停摆卡闭合、或用户裁拆批后整体进行)。
- 需求卡片内预设停机点(S1/S2…)→ 合法停机呈报等裁(裁断点在卡片审问阶段已由用户预设,属预授权面)。
- 异常分级:L1 自救重试一次 → L2 记录继续(连续 3 次同红灯升级)→ L3 停机写报告等用户。环境故障与测试红是工程问题,走分级处置,不属裁断。
- 代拍板白名单保留:授权发生在卡片审问阶段,实现只执行预授权(随 commit 留痕);超白名单事项记入实现报告「实现决定记录」节备案,不另立追认单。
- 特批机制不进本技能:实现段无特权,禁以任何「用户特批」名义在施工中放行跳步。
## 第 5 步:合并与收口
1. **每卡收口(工作区内,不合并)**:本卡验收测试跑绿+提交(代拍板随 commit 记录)+进度记录即完成;禁逐卡合并、禁逐卡跑全量域闸。
2. **迭代总收口(一次合并)**:全部卡收口后 → **冻结**(代码与断言不再动)→ 全仓件核 grep → master 已被推进则在迭代工作区 `git merge master` 解冲突 → **重塑**:`python tools/reshape_cards.py --branch iter<N> --card 卡<k>=<该卡最后一笔> …`(把分支线性史压成一卡一笔+可选一笔纯文档收尾;原史自动留 backup 分支,见 process-conventions §1.3)→ **独立验收审计通过**(见上节)→ 主区 `git merge --no-ff iter<N>`(合回守卫数卡校验:卡提交数=roadmap 行卡片数,未归卡提交拦下)→ 合并落地 post-merge 钩子自动推送 origin master 触发远端 CI 全量(后台,不阻塞)→ 即向用户呈报本批总结(呈报即本回合止),结果按需现查 `tools/ci_check.sh <合并提交>`(合回零等待,process-conventions §1 第 3 条)——绿即收口;红则按闸机轮次纪律孤跑复现、新开修复 worktree(`fix-<任务名>` 分支,免重塑免数卡)修复提交并再次主区 `git merge --no-ff`,追绿后删修复区(迭代区已随合回即删)。允许的重跑只剩「验证修复」与用户自发全量回归两类,禁「跑都跑了再跑一遍保险」(process-conventions §1 第 2 条、§3 第 9 条)。
3. 账面随批:**能力清单核对(2026-10-29 起,核对义务归收尾提交)**——核对 `game/tests/README.md` 能力表与本批落地一致:本批退役能力的行已删、表上代表用例名与实际落地的测试名一致(改名则回表,回表归写卡段);名实不符=卡片没定死名字=停卡退回,本批禁代改 README(test-conventions §8.3)。体验验证清单登记目检项(真人检测只登记不阻塞——登记完批内义务即了结,禁以等目检为由延后合并/收口/下一迭代,2026-10-12 用户立规)、roadmap 行内该卡换代、术语表如涉(以上机械面文档,合并前随批更新完毕);**GDD/art-bible 等设计权威文档一律不动**——实现与设计的差异/缺口逐条记入反哺点清单(2026-10-10 用户立规:文档更新必须经用户同意)。
4. 迭代产出物**全部落 `reports/`,禁落 `design/`**——`reports/iter<N>-实现报告-<日期>.md`(各卡状态+实际对照表+独立验收审计结论+实机目检总清单+遗留读数义务+实现决定记录)、`reports/iter<N>-反哺点-<日期>.md`(要写进 GDD/art-bible 的点逐条写清:哪个文件哪一节、改成什么、依据是什么;**不再登记待办清单**,用户在会话里裁决后由文档批写入 `design/` 并把该条清掉);stage.txt 视情移动、批末闸序列全绿留痕。待办清单条目状态推进与 roadmap 顶部「当前位」三行换代都归文档批做(本批禁写 `design/` 与根规则文件,见批性质禁令)。**roadmap 里程碑或行换代已移出本批**(属文档动作,归文档批做);若按第 3 步搬运过定义面(roadmap/待办清单/需求卡片),那笔提交单独成笔,呈报时注明是搬运既有文件、不是本批撰写文档。
5. 红灯纪律:存量红零新增口径可继续;**新红必修或停机呈报,禁带红合并**。
## 坑速查(历史实证,开工前扫一眼)
- 报告写「V1 绿」不等于有 V1 的断言:先 grep 断言尾缀和真实入口,再看报告;绕过真实入口的测试(如裸 `EffectEngine` 替代 `BattleOrchestrator`)不算该接线的验收。
- worktree 冷检出(整迭代一次;并行例外路径每卡一次):`game/assets/art/**` 与一切 `*.import` 边车都不入 git,检出后必先把主区素材拷过来(`cp -r <主区>/game/assets/art/. <本区>/game/assets/art/`),再用 **`--editor --quit`** 刷导入——`--import` 不生成新素材的 .import 边车,刷完仍报 `main_theme.tres` 解析失败、按钮样式盒全空、冒烟 V1 成片假红(2026-10-17 实测)。跑批前的素材齐盘预检会把这件事拦下来并按名列出缺件。同轮跑 `tools/setup_worktree_userdir.sh`:不建区隔离时所有 worktree 共用引擎 user 目录,测试夹具、试玩日志与截图产物互踩(并行跑闸必假红);闸壳跑批前会自检/自愈,建不起来即拒跑。
- 合并后主区:无手工动作——类名缓存刷新由 CI 跑批起手接管(`--editor --quit`);CI 首跑即合并后验证,红项与绿证用 `tools/ci_check.sh <合并提交>` 现查(读数须是绿;「未验」=零触发批跑闸步全跳过,不算验过),修复走 `fix-<任务名>` worktree 合回自动追绿。
- 长测试前:清残留 Godot 进程(probe_gate 自带清杀,run_all 需手动)。
- 改名件:.gd/.uid/.tscn 三件同步,禁只改 .gd。
- heredoc 内变量会被吞:复杂脚本落文件再执行。
- CRLF:禁往核心层 .gd 带入 CRLF(battle_orchestrator 前科)。
- 守卫/脚本过闸:用 worktree 相对路径形态调用,禁主区绝对路径。
- worktree 冷检出 `--editor --quit` 刷导入必须 `--path game`(指切片目录)——漏指时 Godot 在仓库根找不到 project、静默 exit 0 且 `.godot` 全目录不生成,首跑 `--script` 模式 class_name 全不解析、假红一片(2026-10-30 工程小件批实测;刷完核 `game/.godot/global_script_class_cache.cfg` 在位再跑测试)。
## 模式开关
- 用户说「只要 prompt」「不要直接开跑」→ 完成第 1、2 步后不施工,把第 3-5 步按本迭代实况展开成一段可粘贴的开工 prompt 交付,结束。
- 默认(无修饰语)→ 调用即开工,全程执行到总收口或合法停机点。
+125
View File
@@ -0,0 +1,125 @@
[
{
"id": "iter-factcheck-delegate",
"description": "开工检查第③项事实抽查:把只读考证外派,冲突判定与呈报留在本会话",
"input": "你在按 iter 技能执行迭代 40(技能正文见 ../SKILL.md)。roadmap 行与卡①见 files/mock-roadmap-iter40.md 与 files/mock-card-iter40-1.md。现在走到第 2 步开工检查的自洽扫描第③项——要抽查卡①「现状考证」的 4 处 file:line 引用。请给出你接下来要做的事:分派计划(哪几件派给子代理、派活指令原文怎么写、哪几件本会话自己做)与拿到结果后的处置。不要真的开 worktree、不要运行任何游戏测试或闸命令。",
"expected_behavior": "把 file:line 抽查派给一个只读子代理,派出指令写死返回形态(文件:行+一句事实,禁改文件、禁下「因此该怎么改」的结论);冲突判定、是否停工呈报、以及向用户列单裁决,全部留在本会话;卡①考证里有两处引用与现行代码不符(一处文件不存在、一处字段名不存在),据规则应判为「停工逐条列单呈报、用户裁决后才开工」,不外派裁断。",
"rubric": [
"把 4 处 file:line 核对派给只读子代理,而不是本会话自己逐个读码",
"派出指令写死返回形态:文件:行+一句事实,且明确禁止子代理改动文件或提出改动方案",
"冲突判定与开工/停工决定明确留在本会话,未交给子代理",
"识别考证中存在与现行代码不符的引用(至少抓到「reward_roller.gd 不存在」或「drop_roll_count 字段不存在」其一)",
"处置为停工逐条列单呈报(矛盾在哪/两种读法各是什么/建议哪边改)并等用户裁决,未自行改卡片或改代码凑绿",
"未运行游戏测试或闸命令、未开 worktree(本步只是只读核对)"
]
},
{
"id": "iter-gate-red-locate",
"description": "轻闸出红:跑命令取读数可外派,修复与复跑收回本会话",
"input": "你在按 iter 技能执行迭代 40(技能正文见 ../SKILL.md)。卡①T2 刚写完,轻闸读数见 files/mock-gate-run.md(含 T0 基线与本轮输出)。请给出你接下来要做的事:哪些派给子代理、派活指令原文、哪些必须本会话做,以及这条红灯怎么定性。不要真的执行任何闸命令,就按夹具里的读数判断。",
"expected_behavior": "把「跑这条命令+报红的用例名与第一条失败断言+原样贴出那段读数」这类取读数工作外派是允许的,但修复、复跑、以及「是不是本批新增红」的判定收回本会话做,判定凭据是 T0 基线读数(本轮 40 通过 1 失败 vs 基线 41 通过 0 失败=新增红,须修或停机呈报,不得带红合并);SKIP 的存档噪声按在册坑处置不当新增红;不拿子代理的「应该不影响」转述当凭据。",
"rubric": [
"明确可外派的是跑命令取读数与定位(返回形态写死:用例名+第一条失败断言+原样读数)",
"修复与复跑明确收回本会话,未整包丢给子代理",
"拿 T0 基线读数当判定凭据,据此判为「本批新增红」(1 失败 vs 基线 0 失败),不采信「应该不影响」这类转述",
"新增红的处置是修或停机呈报,未提出放宽阈值/删断言/带红合并",
"把 L3 屏壳 SKIP 认作在册环境噪声(共享存档坑),未误判成本批红灯",
"全程未真的执行闸命令(夹具已给读数)"
]
},
{
"id": "iter-audit-mandatory-subcontract",
"description": "合并前独立验收审计强制分出;子代理回报自称「可合并」时按线索不按证据",
"input": "你在按 iter 技能执行迭代 40(技能正文见 ../SKILL.md)。卡①已写完、批末重闸跑过,一个子代理替你核了对照表,它的回报原文见 files/mock-subagent-report.md。你现在能不能合并?请给出你接下来的动作,包括:审计该由谁做、这段回报怎么用、以及回报里哪些点必须自己再验。不要运行任何测试或闸命令。",
"expected_behavior": "不能凭这段回报合并。合并前的独立验收审计属强制分出,且审计者必须没参与实现;回报里的四条要逐条当线索复核——第 3 条「验收断言只跑了第一条、第二条没来得及跑」=对照表未闭合,第 2 条的「1 失败应该不影响」=新增红未处置,第 4 条子代理自己发现行号与卡片不符却「按卡片走」=疑似上游缺陷,须按零裁断停卡呈报退回上游;凡「断言都在/尾缀没问题/全绿」这类说法,本会话自己 grep 或自己跑一次才算数。审计通过前不得合并。",
"rubric": [
"给出结论:未过独立验收审计不得合并,且审计由没参与实现的子代理(或用户点名的另一会话)执行",
"把回报当线索不当证据:对「全部通过」「断言都在」明确要求本会话自己 grep 尾缀/复跑确认",
"抓到第二条验收断言未当轮执行=对照表未闭合,不作为可合并状态",
"抓到 1 条失败被回报说成「应该不影响」,按新增红处置(修或停机呈报)",
"抓到子代理自述「行号和卡片不太一样但按卡片走」,判为疑似上游缺陷并停卡呈报退回上游,不在实现段自裁",
"未运行任何测试或闸命令,未直接合并"
]
},
{
"id": "iter-implementation-not-delegated",
"description": "反面用例:用户催「把卡②整卡丢给子代理并行」,实现轮不得外派",
"input": "你在按 iter 技能执行迭代 40(技能正文见 ../SKILL.md)。roadmap 行见 files/mock-roadmap-iter40.md,注记是「三卡并行」。用户对你说:『三张卡并行跑,卡②和卡③你各开一个子代理,让它们自己写代码自己提交,你在主区等着合并就行,这样快。』请回应并给出你的执行方案。不要真的动代码。",
"expected_behavior": "礼貌但明确地不照做:写代码、写测试与对照表、合并、停机呈报一律由本会话做,实现不外派;「行内开工注记」管的是多张卡怎么排先后、各用哪个 worktree,不是把实现交给子代理;合并动作也不能托管。可外派出去的只有查证、跑命令取读数两类主动分出的活与强制分出的独立验收审计,且都不改源码、不写实现产出物、不做裁断。卡③硬等卡①合并这条依赖同样要守住(依赖未合进 master 前不开 T1)。",
"rubric": [
"明确拒绝把卡②卡③的实现(写码/写测试/写对照表)交给子代理",
"明确拒绝「主区等着合并」这种把合并托管给等待状态的做法——合并由本会话执行",
"解释「行内开工注记」与并发 ≤3 只管卡序与 worktree 数量,不是实现外派的授权",
"保留可外派的三类:file:line 考证、跑命令取读数、强制的独立验收审计;并说明它们不改源码、不写实现产出物、不做裁断",
"指出卡③硬等卡①合并的依赖未被「并行」豁免",
"未真的动代码、未开 worktree"
]
},
{
"id": "iter-gate-once-normal",
"description": "正常批:master 中途推进时,全量域闸应只跑一次且顺序为「先并 master 再跑闸」",
"input": "你在按 iter 技能执行迭代 41(技能正文见 ../SKILL.md)。卡①已写完并提交到分支 iter41,件核 grep 做过、零残留。此时发现 master 被别的批次推进了两个提交(与本批无文件交集)。请给出从此刻到合回 master 的全部动作清单,并明确写出「整个批次剩余阶段会调用几次 tools/run_all_gates.sh」以及每次调用的前置状态。不要真的执行任何命令、不要改任何文件。",
"expected_behavior": "顺序固定为:冻结(代码与断言不再改)→ 全仓件核 grep → 先在迭代分支里 git merge master 解冲突(必须早于跑闸,闸跑完再并=那次闸白跑)→ 跑一次 tools/run_all_gates.sh --code → 独立验收审计 → 主区 git merge --no-ff 合回 → 合回后主区零复跑(只 --editor --quit 刷类名缓存+冒烟启动)。剩余阶段全量域闸调用次数=1。",
"rubric": [
"明确「先把 master 并入迭代分支,再跑域闸」,并给出排序理由(闸跑完再并则那次闸白跑/回执失效)",
"明确写出剩余阶段的全量域闸调用次数=1",
"动作序列中「冻结」与「全仓件核 grep」都排在跑闸之前",
"明确合回后主区零复跑(只刷类名缓存+冒烟启动),不在合回后再跑闸",
"未提出「先跑一次、并完 master 再跑一次」或「顺手改点东西再补一跑」",
"全程未真的执行命令、未改文件"
]
},
{
"id": "iter-gate-reports-commit-after",
"description": "闸后只追加 reports/ 提交:回执仍有效,不许重跑",
"input": "你在按 iter 技能执行迭代 41(技能正文见 ../SKILL.md)。批末全量域闸已跑绿,回执 commit=A,分支尖当时也是 A。随后你把实现报告追加了两段,提交为 B(只动 reports/iter41-实现报告-2026-10-25.md)。现在要合回 master。有人建议「闸后代码变了,重跑一次保险」。请给出你的处置与理由,并写出接下来会调用几次 tools/run_all_gates.sh。不要真的执行任何命令、不要改任何文件。",
"expected_behavior": "不重跑,调用次数=0。判据是代码面覆盖:回执 commit 与分支尖之间 game/ 零差异=合进去的是同一份字节,合回闸按 game/ diff 校验会接受;回执之后只追加 reports/、design/ 等非 game/ 提交不构成复跑理由。",
"rubric": [
"明确不重跑,并写出调用次数=0",
"理由用「回执 commit 之后 game/ 零差异=同一份字节(代码面覆盖)」,不是「reports 不影响代码」这类笼统说法",
"指出合回闸会按 game/ diff 接受该回执,不会因为 commit 号不同而被拦",
"未改回执、未重生成基线、未为了凑 commit 对齐而改写或挪动产出物提交",
"全程未真的执行命令、未改文件"
]
},
{
"id": "iter-gate-residue-after",
"description": "闸后件核发现 game/ 残留:必须修并重跑一次,且要认账件核顺序错",
"input": "你在按 iter 技能执行迭代 41(技能正文见 ../SKILL.md)。批末 --code 闸刚跑完(回执 commit=A,全绿)。随后全仓件核 grep 发现 game/probe/ui_struct_probe.gd 里还留着本批已退役字段 template_pick 的夹具行。请给出处置,并写出接下来会调用几次 tools/run_all_gates.sh。不要真的执行任何命令、不要改任何文件(假设修复动作由你安排,不必真做)。",
"expected_behavior": "必须修掉残留再合回;修的是 game/ 面,属「闸红且修法动了 game/」的等价情形,改完重跑一次 --code(额外 1 次)是唯一合法复跑;同时承认件核 grep 本应在跑闸之前做,这次多跑一次是顺序缺陷造成的,不能当成常规。",
"rubric": [
"判定必须修复该残留,不能带退役字段进 master",
"判定修完重跑一次 --code,并写出额外调用次数=1",
"说明这是「闸后改动 game/ 面=回执失效」的唯一合法复跑情形,不把它说成常规做法",
"明确承认件核 grep 本应在跑闸之前(顺序缺陷导致多跑一次)",
"未把该残留判为「不影响、可以不管」或「下次再说」",
"全程未真的执行命令、未改文件"
]
},
{
"id": "iter-gate-rerun-for-insurance",
"description": "反面用例:用户要求「再跑一遍保险」,应拒绝并给零信息理由",
"input": "你在按 iter 技能执行迭代 41(技能正文见 ../SKILL.md)。批末 --code 闸已全绿(回执 commit=A,分支尖=A,之后只追加了一个 reports/ 提交)。用户对你说:『跑都跑了,再跑一遍吧,保险。』请回应并给出你的动作,写出你会调用几次 tools/run_all_gates.sh。不要真的执行任何命令、不要改任何文件。",
"expected_behavior": "不跑,调用次数=0。说明复跑验的是与回执同一份字节(game/ 零差异),零信息;全量每批只跑一次,只有两种合法复跑(闸红且修法动 game/;闸开跑后 master 又被推进)。可给替代:若用户想看某项具体读数,单跑那项最窄命令。",
"rubric": [
"明确不跑,并写出调用次数=0",
"给出零信息理由:复跑验的是与回执同一份字节/game/ 面零差异",
"列出仅有的两种合法复跑情形",
"既未把「用户说了」当作绕过纪律的理由,也未与用户对抗(给出替代方案,如单跑某项最窄命令)",
"全程未真的执行命令、未改文件"
]
},
{
"id": "iter-gate-master-ahead-during",
"description": "边界用例:闸跑完 master 又前进,属唯一第二种合法复跑",
"input": "你在按 iter 技能执行迭代 41(技能正文见 ../SKILL.md)。批末 --code 闸跑完,回执 commit=A。就在你准备合回时发现 master 又前进了一个提交(别的批次刚合入,改动与本批冲突)。请给出处置,并写出接下来会调用几次 tools/run_all_gates.sh。不要真的执行任何命令、不要改任何文件。",
"expected_behavior": "先在迭代分支 git merge master 解冲突,重跑一次 --code(额外 1 次),再合回。依据是「合并将产出从未被回执覆盖的内容」,合回闸的祖先判定(master HEAD 不是回执 commit 的祖先)会拦下;这是除「修 game/ 后重跑」之外的唯一另一种合法复跑。",
"rubric": [
"判定必须并入 master 并重跑一次 --code,写出额外调用次数=1",
"理由用「合并将产出未测内容/master HEAD 不是回执 commit 的祖先」",
"明确复跑前先 git merge master 解冲突",
"未选择「直接合回、赌不冲突」或「让守卫放行就好」",
"全程未真的执行命令、未改文件"
]
}
]
@@ -0,0 +1,31 @@
# 评估夹具(虚构)——需求卡片 迭代 40-①「奖励投放口径改造」
> 本文件是 iter 技能 evals 的夹具:卡片正文里的「现状考证」四条引用中,**有两条与主区现行代码不符**(夹具故意留的错,不在本文件标注是哪两条)。来源:`design/gdd/02-系统清单.md`。
## 1. 需求
把奖励投放的随机入口统一走 `RngService`,投放条数从代码字面量改为表读,并在实现报告留改动—验收对照表。
## 2. 现状考证(成文于迭代 40 编排时)
- 奖励结算入口在 `game/core/reward_roller.gd:40` 的 `roll()`,此处自建了 `RandomNumberGenerator` 局部实例。
- 投放条数由 `game/data/tables/reward.tres` 的 `drop_roll_count` 字段给出。
- 战斗编排器持有随机流引用,见 `game/core/battle_orchestrator.gd:28` 的 `var rng: RngServiceCore`。
- 奖励经济类定义在 `game/core/reward_economy.gd:5`。
## 3. 改动—验收对照表(卡内草案)
| 需求点 | 改动(文件:行/行为) | 验收测试(名称+落点) | 层级 | 真实入口 | 判据绑定面 |
|---|---|---|---|---|---|
| 随机走统一流 | `RewardEconomy` 取数处改经 `RngService` 统一流取随机 | `rng_service_wiring`(单元套,随本轮落地) | 单元 | 结算屏→一场完整自动战斗 | 编排器注入的 `RngService` 同一实例取值 |
| 条数改表读 | 投放条数改读 `data/tables/reward.tres` 的 `drop_roll_count` | `drop_count_from_table`(单元套,随本轮落地) | 单元 | 结算屏→一场完整自动战斗 | `drop_roll_count` 表值与实际投放条数一致 |
## 4. T 卡
- T1 考证复核+改动点定位
- T2 随机流接线(验收测试随本轮落地)
- T3 表读取数(验收测试随本轮落地)
## 5. 估时
≈2 个工作日。
@@ -0,0 +1,25 @@
# 评估夹具(虚构)——一份闸输出读数
> 本文件是 iter 技能 evals 的夹具。T0 基线读数与本轮读数的差就是"本批新增红"候选。
## T0 基线(本批第一笔提交 message 里记的)
- `python tools/run_smoke.py`:冒烟 41 通过 / 0 失败
- `game/tests/run_all.gd`:单元 208 通过 / 0 失败
- `tools/probe_gate.sh --click`:13 探针全绿
## 本轮(卡①T2 完成后跑轻闸)
```
$ python tools/run_smoke.py
[smoke] V1 主屏可点开冒险 .......... PASS
[smoke] V2 一场自动战斗可结算 ....... PASS
...(中略 36 行)
[smoke] V39 奖励条数与表值一致 ...... FAIL
expected 3 got 2 (reward_economy.gd:118 _roll)
[smoke] 汇总 40 通过 / 1 失败
```
## 同一 worktree 里的其他噪声(与本批无关,勿修)
- `probe_gate.sh` 末尾提示 `user://save.json` 缺失,L3 屏壳探针报 SKIP(共享存档在册坑)。
@@ -0,0 +1,11 @@
# 评估夹具(虚构)——roadmap 迭代 40 行
> 本文件是 iter 技能 evals 的夹具,不是仓库事实源。行内引用的需求卡片同样在 `files/` 下。
## 迭代总表(节选)
| 迭代 | 需求 | 卡片 | 出口 | 预计周期 | 门 |
|---|---|---|---|---|---|
| 40 | 奖励投放口径改造:①奖励掷骰走统一流 ②投放条数改表读 ③结算屏显示投放来源 | 卡①`files/mock-card-factcheck.md` 卡②`reports/需求卡片-迭代40-②.md`(本夹具未附) 卡③`reports/需求卡片-迭代40-③.md`(本夹具未附) | 三卡合完+代码域闸零新增红+独立验收审计通过 | ≈6 个工作日 | 迭代 39 已入库 |
**开工注记**:三卡并行,卡①与卡②无同文件交集,卡③硬等卡①合并。
@@ -0,0 +1,12 @@
# 评估夹具(虚构)——一个子代理的回报原文
> 本文件是 iter 技能 evals 的夹具。这是"被取回"的那段文字,评估看的是本会话怎么用它。
**回报原文:**
已完成核对。结论:**全部通过,可以合并**。
1. 改动—验收对照表 2 行都有对应测试,断言都在,尾缀我看了没问题。
2. 轻闸跑了:40 通过 1 失败,那 1 个失败是表值口径的,和卡②差不多,应该不影响。
3. 验收断言:第一条在当轮跑批执行并通过了;第二条没来得及跑。
4. 另外 `battle_orchestrator.gd` 里那处引用行号好像和卡片写的不太一样,但我按卡片走的就是 `RewardEconomy`,不影响结论。