docs(card): 需求卡片 v1.2——开工前自查,钉死四处会卡住施工方的口径
逐条自查「施工方会不会回头问」,查出并定死四处(另有两处笔误订正):
**1. S11 词表范围与 §4「不做」自相矛盾(最严重)**
原 T1 写「词表=退役词对照 + 用语规范 A 表禁用列全部」,但 §4 已把 A 表词
(不得 14/报错 18/对标 1/若干 1/buff 22)列为「不做、待用户另裁」。
⇒ 原写法会让 S11 一落闸就红 56 处,批末闸必然红、无法合回。
定死:词表=退役词对照节第一列 + 显式追加「完美排雷」完整短语;
明确不收 A 表词、不收单字「雷」。A 表将来裁入时另行扩表并单独立批。
**2. 单字「雷」会误伤 26 处保留词**
「排雷玩法/排雷规则」是内部机制名(§10 明定不扩大禁词面),
按单字「雷」扫会全部误判。定死:只收「完美排雷」完整短语。
**3. N7 修法不可行——_fx_emit 有状态,重复调用重复消费限次**
_fx_emit = _fx.dispatch(battle_orchestrator.gd:90-93),forgive_seal_miss 行
走 when lt 1 限次并由 _apply_counter_hit 记账 ⇒ 「先跑一次算 hl 再跑原循环」
会消费两次限次、归因行发两次。
定死:改为把 _emit_row("seal_miss")(:302)**后移**到 _fx_emit 循环(:308-317)之后,
循环跑完 _perfect_forgiven 已就位再判 hl。已实测
grep "insurance_used|perfect_insurance" game/smoke/smoke_all.gd 零命中
⇒ 行序调换不涉冒烟断言。
**4. A10/A11 断言落点不可执行**
原写「断言日志出现/不出现字样」,但日志文本由呈现层 battle_log_view._format_row
生成,core 层单测拿不到。定死:断言 seal_miss 行的 highlight 字段值
(未装备 == "perfect_broken"/装备 == ""),落点 tests/unit/core/;
另加 A12 断言两态文案与呈现分支一致且不含「雷」。
**另订正两处**:§4「做」列表重复第 6 项(完美排雷出现两次);
T4 步骤 adventure_runner.gd 漏列 :771(写 11 处只列 10 个行号)。
**同步新增**:契约 9 S11 闸门自指豁免(smoke_all.gd:1319 的禁字面检查行与
ui_font_asset_test.gd:18-19 字形夹具不含对照性信号,会被自指判红);
变异验证增「去掉自指豁免」一条;代拍板/范围边界措辞同步。
处数对账复核:T3=26/T4=35/T5=11/T6=9,与 §2 清单一致。
流水线闸 PASS:06 条目 64 · 总表数据行 32 · 交叉核 3 链 · 卡片口径 22 张全过。
This commit is contained in:
1 parent
0da014d4f1
commit
869d00d678
1 file changed
+31
-20
@@ -4,7 +4,8 @@
|
||||
- **日期**:2026-10-20
|
||||
- **批次性质**:工程债/重构 + 缺陷修复(两类均属工程直入四类,凭 06 在册条目与代码级证据直接写卡)
|
||||
- **设计事实源**(唯一事实源:`design/gdd/术语表.md`「退役词对照」+「用语规范 A 表」+「对外命名纪律」节;`design/gdd/systems/战斗循环/战斗结算.md`「完美排雷」规则节;req-card 三选一之③工程直入证据指认):扫描读数=`game/` 下 195 个文件(.gd/.tres/.md/.json/.sh/.txt)逐处实测,落点带 file:line(见 §2);复现命令见 §2 末。
|
||||
- **版本**:**v1.1**(2026-10-20:grilling 复核门查出 N7 概念冲突,新增需求点与 T7 卡;T2 的对外文案由「机械换词」改为「按概念两态改写」)
|
||||
- **版本**:**v1.2**(2026-10-20:开工前自检查出四处会卡住施工方的未定口径——S11 词表范围/「雷」字面误伤面/N7 修法可行性与限次重复消费/A10·A11 断言落点——全部钉死;T7 修法由「上移豁免」改为「后移 `_emit_row`」,已核实 `_fx_emit` 有状态不可重复调用)
|
||||
- 历史:v1.1(2026-10-20:grilling 复核门查出 N7 概念冲突,新增需求点与 T7 卡;T2 的对外文案由「机械换词」改为「按概念两态改写」)
|
||||
- **迭代归属**:待编入 roadmap 迭代 32(本卡不自行编入;编排归 iter-plan 段)
|
||||
- **上游依据**:2026-10-19 用户裁——「完美排雷」**全库统一**换代为「完美封印」,含代码内部注释
|
||||
|
||||
@@ -54,7 +55,7 @@
|
||||
|
||||
1. `game/` 内 `完美排雷`/`板级`/`门票`(注释面)/`正主`/`落籍` 五词,**疑似现行计数全部为 0**(豁免=含对照/历史信号的行)。
|
||||
2. 对外文案三处不含「雷」字面,读作「完美封印」。
|
||||
3. **N7**:装备「完美保险」专长时本战首次标错 → 日志**不**出现「已破」字样,改出现豁免态文案;未装备时首次标错 → 出现「已破」态文案。两态各有正向断言。
|
||||
3. **N7**:装备「完美保险」专长时本战首次标错 → `seal_miss` 行的 `highlight` 字段为 `""`(豁免态,无金框),且 `perfect_sweep_earned() == true`;未装备时首次标错 → `highlight` 为 `"perfect_broken"`(已破态,金框),且 `perfect_sweep_earned() == false`。两态各有正向断言(A10/A11)。
|
||||
4. 冒烟绿数与改前基线一致(现行 1151 项 0 失败)、单元测试 34 套全绿、探针段绿。
|
||||
5. S11 规则在位:注入一次禁用词 → `game/tests/static_scan.sh` 判红;还原后绿;变异验证记录进实现报告。
|
||||
6. 代码域闸按域选档跑通,回执 `game/tests/.gates/receipt.json` 的 commit = 分支 tip 且 `all_green=true`。
|
||||
@@ -139,8 +140,9 @@
|
||||
4. 🔴 **完美封印判据单点**——「是否已破」只允许由 `battle_orchestrator.perfect_sweep_earned()` 的有效误标口径派生,禁在 `grant_segment.gd` 另立 RAW 计数判据;两处口径不一致即为缺陷。
|
||||
5. 🔴 **游戏行为零变化**(N1–N5、N7 判据修正前)——纯中文文本替换,禁止改动逻辑、数值、权重、条件判断。N7 判据修正是**本批唯一允许的逻辑改动**,其验收为「日志文案与真值一致」,不改奖励兑付结果。
|
||||
6. 🔴 **S11 规则先落、后修码**——先把规则写进 `game/tests/static_scan.sh` 并跑出红,再动注释(code-conventions 缺陷-规范对照表纪律)。
|
||||
7. 🔴 **S11 词表不内联第二份**——规则脚本从 `design/gdd/术语表.md`(「退役词对照」+「用语规范 A 表」两节)解析词面;禁止在脚本里另抄一份词表(单一事实源红线,ADR 漂移教训同类)。
|
||||
8. 🔴 **S11 必须带扫描面零命中自检**——先数一遍扫描面文件数,为零即判红(沿 S3 教训:路径写歪时自检一起歪、一起红,不会静默恒绿)。
|
||||
7. 🔴 **S11 词表范围=本批清理范围,且从术语表解析不内联**——词表面=`design/gdd/术语表.md`「退役词对照」节第一列全部词面(去括号注),**显式追加 `完美排雷` 完整短语**(该词受「对外命名纪律」约束,不在退役词对照表里,故需显式列入)。**明确不收**:①术语表「用语规范」A 表词面(`不得`/`报错`/`对标`/`若干`/`buff`)——§4 已列「不做」,收进来批末必然红;②单字「雷」——会误伤 26 处保留词「排雷玩法/排雷规则」(内部机制名,§10 明定不扩大禁词面)。**禁止在脚本里另抄一份词表**(单一事实源红线,ADR 漂移教训同类)。A 表词将来若被裁决纳入,另行扩词表并单独立批清扫。
|
||||
8. 🔴 **S11 必须带两道零命中自检**——①扫描面文件数为零即判红;②从术语表解析出的词面数为零即判红(沿 S3 教训:路径写歪或表格结构变了时,自检一起歪、一起红,不会静默恒绿)。
|
||||
9. 🔴 **S11 闸门自指豁免**——命中行若属「检查禁用词本身」的闸门形态(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 等检查或禁令表述),或含 `doc_term_audit.py` 同源的对照/历史信号,一律豁免、不判红。现存受此豁免的两处:`game/smoke/smoke_all.gd:1319`(禁字面检查逻辑)与 `game/tests/unit/presentation/ui_font_asset_test.gd:18`/`:19`(字形覆盖夹具)。
|
||||
9. 🔴 **禁碰并行会话在改的文件**——`AGENTS.md` 与 `design/dev/code-conventions.md`(分支 `changelog-retire-20261019` 在盘未合回)。S11 规则说明自持于 `game/tests/static_scan.sh` 头注与 `game/tests/README.md`。
|
||||
10. 🔴 **对照性文本豁免**——含退役/更名/禁令等信号的行不改写(术语表用语规范 B 类豁免条款)。
|
||||
|
||||
@@ -155,11 +157,10 @@
|
||||
3. `game/` 内注释面 `门票`→`专长凭证`(35 处,剔除移交 3 处)
|
||||
4. `game/` 内注释面 `正主`→`现行事实源`(11 处,剔除误报 1 处)
|
||||
5. `game/` 内注释面 `落籍`→`已入库`(9 处,剔除历史注记 1 处)
|
||||
6. `game/` 内 `完美排雷`→`完美封印`(16 处)
|
||||
7. **N7**:封印未中行归因锚改用有效误标判据,文案按两态改写
|
||||
8. 代码域静态扫描闸新增 S11 规则(含零命中自检)
|
||||
9. `game/README.md`/`game/tests/README.md` 同步
|
||||
10. 全量冒烟+单元+探针验证,绿数与基线一致
|
||||
6. **N7**:封印未中行归因锚改用有效误标判据,文案按两态改写
|
||||
7. 代码域静态扫描闸新增 S11 规则(词表=退役词对照+`完美排雷`;含两道零命中自检与闸门自指豁免)
|
||||
8. `game/README.md`/`game/tests/README.md` 同步
|
||||
9. 全量冒烟+单元+探针验证,绿数与基线一致
|
||||
|
||||
**不做**(去向):
|
||||
|
||||
@@ -225,13 +226,17 @@
|
||||
|
||||
### T1 · S11 规则落闸并见红(≈1.0–1.5h)
|
||||
|
||||
- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 一行说明(规则名+权威出处+扫描面)
|
||||
- [ ] 在 `game/tests/static_scan.sh` 头部注释补 S11 一行说明(规则名+权威出处+扫描面+词表来源)
|
||||
- [ ] 新增 S11 段:扫描面=`game/` 全域(.gd/.tres/.md/.json),与迭代 31 V4 判据同口径
|
||||
- [ ] 逐行取注释文本段(`#`/`;` 前缀),剔除含对照/历史信号的行
|
||||
- [ ] 词表面从 `design/gdd/术语表.md` 解析:「退役词对照」表第一列全部词面(去括号注)+「用语规范」A 表「禁用」列全部词面
|
||||
- [ ] 规则先数扫描面文件数,为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1`
|
||||
- [ ] 词表面从 `design/gdd/术语表.md`「退役词对照」节解析第一列全部词面(去括号注),**显式追加 `完美排雷` 完整短语**;不收 A 表词、不收单字「雷」(契约 7)
|
||||
- [ ] 命中行先过闸门自指豁免(行内含 `contains(`/`find(`/`grep`/`has_char(`/`禁「`/`禁『`/`零「`/`零『` 即跳过),再判红(契约 9)
|
||||
- [ ] 自检一:扫描面文件数为零即 `echo "[static_scan] S11 FAIL: 扫描面为空"` 并 `fail=1`
|
||||
- [ ] 自检二:解析出的词面数为零即 `echo "[static_scan] S11 FAIL: 词表解析为空"` 并 `fail=1`
|
||||
- [ ] 命中即打印 `file:line + 命中词`,段末 `fail=1`
|
||||
- [ ] 在 `game/tests/README.md` 的静态扫描登记处补 S11 一行(规则名/扫描面/词表来源/豁免条款)
|
||||
- [ ] 注入验证:在 `game/core/battle_orchestrator.gd` 某注释里临时写回「板级」一词 → 跑 `bash game/tests/static_scan.sh` 见红并记输出摘要 → `git checkout -- game/core/battle_orchestrator.gd` 精确还原 → 记录进实现报告变异验证表
|
||||
- [ ] 反向验证:在 `game/smoke/smoke_all.gd:1319`(禁字面检查行)写回原句 → 跑闸**仍为绿**(验证自指豁免生效)→ 还原
|
||||
|
||||
**取用**:无。
|
||||
**产出**:`game/tests/static_scan.sh` 的 `S11` 段(退出码语义=任一硬失败规则命中即 `exit 1`,与现役同段同规)。
|
||||
@@ -261,7 +266,7 @@
|
||||
|
||||
### T4 · 门票 → 专长凭证(注释面,≈1.0h)
|
||||
|
||||
- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/788/796/1033/1034)
|
||||
- [ ] `game/core/adventure_runner.gd` 11 处注释换代(67/68/69/477/664/751/771/788/796/1033/1034)
|
||||
- [ ] `game/core/level_runner.gd` 4 处(51/781/826/831)
|
||||
- [ ] `game/data/schemas/adventure_table.gd` 3 处(92/96/97)+ `shop_table.gd:18`
|
||||
- [ ] `game/data/tables/shop.tres:104` 注释换代
|
||||
@@ -288,9 +293,13 @@
|
||||
|
||||
### T7 · N7 归因锚判据修正(≈1.5h)
|
||||
|
||||
- [ ] 把 `core/settlement/grant_segment.gd:300` 的判据由 RAW 计数 `oc._perfect_hit_false == 1` 改为**有效误标**口径 `_perfect_hit_false - _perfect_forgiven == 1`
|
||||
- [ ] 把豁免累加 `_perfect_forgiven += 1`(:314)上移到 `_emit_row`(:302)**之前**,使归因锚与谓词口径同源
|
||||
- [ ] 文案两态:未豁免 → `(本图完美封印已破——清图奖励不再加倍)`;已豁免 → `(首次封印落空已豁免——不计入完美封印判定)`
|
||||
**修法(已核实可行,禁另选他法)**:`_fx_emit`(`battle_orchestrator.gd:90-93`)是 `_fx.dispatch` 的**有状态派发**——`forgive_seal_miss` 行走 `when lt 1` 限次并由 `_apply_counter_hit` 记账,**重复调用会重复消费限次**。因此**禁止**"先跑一次 `_fx_emit` 算 `hl` 再在原位置跑一次"的做法。
|
||||
|
||||
- [ ] 把 `core/settlement/grant_segment.gd:302` 的 `oc._emit_row("seal_miss", ...)` **后移**到 `for h in oc._fx_emit("seal_missed", ...)` 循环(:308-317)**之后**——循环结束后 `_perfect_forgiven` 已就位,判据才有真值可用
|
||||
- [ ] 判据改有效误标:`var hl := "perfect_broken" if oc._perfect_hit_false - oc._perfect_forgiven == 1 else ""`(替代原 :300 的 RAW 计数 `oc._perfect_hit_false == 1`)
|
||||
- [ ] 确认行序调换的零影响:`grep -n "insurance_used\|perfect_insurance" game/smoke/smoke_all.gd` 已实测**零命中**——冒烟未断言这两行的相对顺序,调换不涉断言
|
||||
- [ ] 文案两态:未豁免(`hl == "perfect_broken"`)→ `(本图完美封印已破——清图奖励不再加倍)`;已豁免(`hl == ""`)→ `(首次封印落空已豁免——不计入完美封印判定)`
|
||||
- [ ] 豁免态**不加金框**——`hl == ""` 时 `battle_log_view.gd:195` 走普通色分支;金框语义=强调负面事件,豁免是正向事件,靠同批已存在的 `insurance_used` 行(:316-317)承载反馈即可。不新增高光标记
|
||||
- [ ] 正向断言 A10/A11(见 §7)
|
||||
|
||||
**取用**:T2 的对外文案换代结果。
|
||||
@@ -326,8 +335,9 @@
|
||||
| A7 | N6 | S11 规则在位:注入禁用词 → 退出码 1 且输出含 `S11 FAIL`/命中行 | 注入实验,落点 `game/tests/static_scan.sh` | 自动(人工执行一次取证) |
|
||||
| A8 | 全域 | 冒烟绿数 == 基线 1151、单元 34 套全绿、探针段绿 | 跑所选域档 | 自动 |
|
||||
| A9 | 全域 | 回执 commit == 分支 tip 且 `all_green=true`,零新增红 | 跑闸后读 `game/tests/.gates/receipt.json` | 自动(合回闸) |
|
||||
| **A10** | **N7** | **未装备完美保险:首次标错 → 日志出现「完美封印已破」,且 `perfect_sweep_earned() == false`** | 新增断言,落点 `tests/unit/core/feat_vouchers_test.gd`(现有专长套件) | 自动 |
|
||||
| **A11** | **N7** | **装备完美保险:首次标错 → 日志出现豁免态文案,且不出现「已破」;`perfect_sweep_earned() == true`(加倍仍发)** | 同上 | 自动 |
|
||||
| **A10** | **N7** | **未装备完美保险:本战首次标错 → `seal_miss` 行的 `highlight` 字段 == `"perfect_broken"`,且 `perfect_sweep_earned() == false`** | 新增断言,落点 `tests/unit/core/feat_vouchers_test.gd`(现有专长套件,core 层可直取行字段) | 自动 |
|
||||
| **A11** | **N7** | **装备完美保险:本战首次标错 → `seal_miss` 行的 `highlight` 字段 == `""`,且 `perfect_sweep_earned() == true`(加倍仍发)** | 同上 | 自动 |
|
||||
| **A12** | **N7** | 两态文案常量与 `battle_log_view.gd` 呈现一致:`_format_row` 对 `hl=="perfect_broken"` 输出「已破」态、对 `hl==""` 输出豁免态,两态均不含「雷」字面 | 断言落点 `tests/unit/core/feat_vouchers_test.gd`(取行字段后按同一分支规则格式化比对) | 自动 |
|
||||
|
||||
**测试方式两分法**:A1–A7、A10–A11 属能力验证(静态扫描/断言直取数据)与取证实验;A8–A9 为运行期验证。玩家可见文案的最终观感归**用户目检**(登记不阻塞):结算明细中封印未中行的两态文案可读性。
|
||||
|
||||
@@ -342,8 +352,9 @@
|
||||
| `game/core/battle_orchestrator.gd:265` 注释 | 写回「板级完美排雷」原措辞 | `bash game/tests/static_scan.sh` | `S11 FAIL` + 命中行输出 |
|
||||
| 同上对外文案 | `game/core/battle_orchestrator.gd:925` 写回「完美排雷!…」 | 冒烟清图段 | 断言 A2 红 |
|
||||
| S11 扫描面 | 临时把 `DIR_CORE` 改成不存在目录 | `bash game/tests/static_scan.sh` | `S11 FAIL: 扫描面为空` |
|
||||
| **N7 判据(反)** | 把 `grant_segment.gd:300` 改回 `_perfect_hit_false == 1`(RAW) | `tests/unit/core/feat_vouchers_test.gd` | 断言 A11 红(豁免态应无「已破」却出现) |
|
||||
| **N7 判据(正)** | 把 :300 改成 `_perfect_hit_false - _perfect_forgiven <= 0`(恒真) | 同上 | 断言 A10 红(未豁免态应「已破」却缺失) |
|
||||
| **N7 判据(反)** | `grant_segment.gd` 判据改回 `_perfect_hit_false == 1`(RAW 计数) | `tests/unit/core/feat_vouchers_test.gd` | 断言 A11 红(装备专长时 `highlight` 应为 `""` 却得 `"perfect_broken"`) |
|
||||
| **N7 判据(正)** | 判据改成 `_perfect_hit_false + _perfect_forgiven == 1`(符号写反) | 同上 | 断言 A10 红(未装备专长时 `highlight` 应为 `"perfect_broken"` 却得 `""`) |
|
||||
| **S11 自指豁免** | 去掉 S11 的闸门自指豁免分支 | `bash game/tests/static_scan.sh` | `smoke_all.gd:1319` 与 `ui_font_asset_test.gd:18` 判红 |
|
||||
|
||||
注入后一律 `git checkout -- <file>` 精确还原,四件(变异点 file:行/跑的闸/红输出摘要/还原结论)记进实现报告变异验证记录表。
|
||||
|
||||
|
||||
Reference in new issue
Block a user