merge(写卡): S13 基线键治本需求卡片——四待裁点拍板(稳定身份键/恶化判据 X=0/治本+批内刷新/对账自检),待办状态推进已写卡;docs 域闸全绿(07 doc_link 较基线改善·零新增红)

This commit is contained in:
DKChan committed 2026-10-25 02:22:42 +08:00
commit a74d75402f
2 files changed
+163 -2

No files matched your search

@@ -0,0 +1,161 @@
# 需求卡片——S13 基线键治本(稳定身份键+恶化判据+刷新对账自检)
- 批名:S13 基线键治本|日期:2026-10-25|批次性质:非迭代批(tools/ 闸机面;改动面=tools/+game/tests/ → 代码域档)
- 估时:0.4–0.6 工作日(T0 0.2/T1 0.15/T2 0.15;软盒上限 0.6,超出按异常分级 L3 停机呈报)
- 来源:待办清单「S13 gdstyle 免名单把数字当身份——存量债改小也报『基线外新违规』」(2026-10-25 登记,来源=批次移交,设计面=工程直入)
- 验收证明口径:按 2026-10-24 用户裁定,一切验收走撤销证明。待办条目原文写「变异验证四项」,本卡以撤销证明等价覆盖同四判据(新增必红=R2/漂移不冒新=R1/恶化必红=R3/禁闸内自动重生成自检=R5+R6),不另做变异类测试。
## 1 目标与完成定义
**做什么**:三件套治本——① `tools/gdstyle_gate.py` 的违规匹配键从「文件|规则|消息全文」改为稳定身份键「文件|规则|函数名」(无函数名条目退化为「文件|规则」;解析不出数值的条目退化为现行全文键);② 新增恶化判据——同身份当前值大于基线登记值即判红(X=0,不分规则,2026-10-25 用户裁);③ `--refresh` 加对账自检(打印新旧两向清单+骤降守卫)。批内人工重生成基线(239 条→234 条),两处文案随动。
**完成定义**:验收对照表 R1–R8 全过+按改动域选档跑闸全绿+基线 234 条落盘+`reports/` 三份产出物(实现报告/代拍板追认单/反哺点清单)齐+待办清单 S13 条目状态由流水线推进。
## 2 设计事实源
工程直入证据指认(与待办条目一致,写卡会话 2026-10-25 已实查复核):
- `tools/gdstyle_gate.py:82`——`keys.add("%s|%s|%s" % (file_path, f["rule"], f.get("message", "")))`,消息全文入键,而消息文本自带具体数字(如 `function 'resume_adventure' is 104 lines long (max 50)`),数字一变即匹配失败、被判「基线外新违规」
- master 尖 `a913ad44` 实测(2026-10-25):扫描面 100 个 .gd、命中 234 条、基线内 222 条、基线外新违规 12 条(红);基线 241 行=2 行头注+239 条
- gdstyle v0.4.0(钉版)JSON 输出字段=`file/rule/message/severity/span`,无结构化指标字段——函数名与数值只能从 message 正则提取
## 3 现状事实
(全部实查,开工自行复核)
- 键构造:`tools/gdstyle_gate.py:82`(引文见上);判定段 `:103-111` 只做 `keys - base` 差集判 NEW
- `--refresh` 现状:`tools/gdstyle_gate.py:84-92`——直接覆盖写基线、零对账输出;头注 `:11-13` 自述「基线键=文件|规则|消息 三元组」
- 基线:`tools/gdstyle_baseline.txt` 241 行(2 行头注+239 条),行格式=`文件|规则|消息全文` 逐字存原句
- 调用链:`tools/run_all_gates.sh:251`(09 静态扫描段)→ `game/tests/static_scan.sh:247` → `tools/gdstyle_gate.py`;static_scan.sh `:239-246` 段头注描述三元组口径;`game/tests/README.md:64` 速查表 S13 行同口径。`tools/run_all_gates.sh` 全文无 S13 直述(待办条目预计改动面所写「run_all_gates.sh 头注随动」据此订正为 static_scan.sh 头注)
- master 尖 12 条假新增(2026-10-25 闸输出原样):`adventure_runner.gd` 5 条(分支 11/类变量 42/文件 1051 行/`_start_current_level` 53 行/`resume_adventure` 108 行)+`config_db_cross_validator.gd` 4 条(`cross_validate`:分支 21/107 行/局部变量 24/嵌套 5)+`level_runner.gd` 2 条(类变量 38/`start_level_external` 参数 7)+`main.gd` 1 条(1507 行)
- 239 条旧基线对账(写卡会话差集脚本实测):222 条现键仍命中+12 条漂移旧值(即上列 12 条的前身,如 `resume_adventure' has 10 branches`、`cross_validate' is 159 lines`)+5 条已还真债(`level_runner` 文件 1013 行、`level_table.gd` `_validate_graph` 3 条+`_validate_level_nodes` 1 条——迭代 35 当场拆四段修掉)
- 刷新后基线应=234 条:当前 234 条命中的身份全部能在旧基线中找到同身份;其中 3 条较登记值恶化(`resume_adventure` 分支 10→11、行数 104→108;`adventure_runner` 文件 1050→1051)、9 条改善(其余漂移全为改小,如 `_start_current_level` 55→53、`cross_validate` 159→107)
- 消息形态实证(数值提取依据):函数级五规则消息均含 `function '名字'`+当前值+`(max N)`(行数/分支/局部变量/参数/嵌套);类级 `class has N variables (max 15)` 与文件级 `file is N lines long (max 1000)` 无名字
## 4 设计契约(违反即返工)
- 🔴 身份键=文件|规则|函数名:函数名从消息提取 `function '([^']+)'`;类级/文件级无名字条目退化为「文件|规则」;消息解析不出「当前值+max 值」的条目退化为现行「文件|规则|消息全文」键(保守路径:任何文本变化即新违规)。基线文件行格式不变(仍存原消息全文——保持可人读、登记值可解析)
- 🔴 恶化判据 X=0(2026-10-25 用户裁):同身份「当前值>基线登记值」→ 判 WORSE 红;当前值≤登记值=基线内绿(改善可打印计数,禁止判红)
- 🔴 `--refresh` 对账自检:刷新时打印旧→新条数+逐条「新登记/消失」清单;新条数<旧条数×0.8 或旧基线文件缺失 → 拒绝写盘、退出非零,除非显式 `--allow-shrink`;闸正常判定路径零写基线文件;`--refresh` 仍只允许人工发起
- 🔴 禁动口径面:gdstyle.toml 规则与阈值、扫描面三目录(game/core、game/data、game/presentation)、钉版 v0.4.0 一律不动;12 条假新增涉及的 game/ 源文件零改动(它们的数字漂移是合法编辑的结果,不是缺陷)
## 5 范围边界
做:`gdstyle_gate.py` 三段改造(键构造/判定/refresh)+自身头注;基线重生成;`static_scan.sh:239-246` 与 `game/tests/README.md:64` 两处文案随动。
不做(去向):
- 不还 234 条存量债——免名单继续豁免,还债属后续迭代批按卡处理
- 不新增 python 单测件——tools/ 下 39 个 .py 闸件各自独立、无单测先例,验收走撤销证明,闸件自身即断言载体;若日后要求持久回归件,登记待办清单再议
- 不动 `run_all_gates.sh`(实测全文无 S13 直述,无需随动)
- 不处理其他闸(S6/S7/S8 落地等另有条目)
## 6 关联文档同步面
| 文档 | 关联点 | 同步义务 |
|---|---|---|
| `game/tests/static_scan.sh:239-246` | S13 段头注自述「文件|规则|消息 三元组……基线外新违规才红」 | 批内直改(game/tests/ 属本批改动面) |
| `game/tests/README.md:64` | 速查表 S13 行「存量基线外新违规才红」 | 批内直改(同上) |
| `tools/gdstyle_gate.py:11-13` | 闸件头注自述三元组键 | 批内直改(本批主改文件自身头注) |
| `待办清单.md` S13 条目 | 状态推进「已写卡」→ 批完结整条退役 | 流水线状态机推进(写卡段回写、批后收尾退役),实现批禁顺手改 |
design/ 全树对 gdstyle/S13 零提及(2026-10-25 grep 实证)→ 本批无设计文档反哺点,反哺点清单如实写零条。
## 7 文件结构图与落位预检
### 7.1 文件结构图
| 文件 | 职责 | 行为改动 |
|---|---|---|
| `tools/gdstyle_gate.py` | 闸件本体:键构造段改稳定身份键+数值解析(:77-90 区域);判定段加 WORSE 分支(:103-111 区域);refresh 段加对账与骤降守卫(:84-92 区域);头注随动(:11-13) | 行为改动——对照表 R1–R6 |
| `tools/gdstyle_baseline.txt` | 存量基线数据件,`--refresh` 重生成 239→234 条 | 非行为改动(数据件重排)——R7 验收 |
| `game/tests/static_scan.sh` | S13 调用段头注文案随动(:239-246) | 非行为改动——R8 |
| `game/tests/README.md` | 速查表 S13 行文案随动(:64) | 非行为改动——R8 |
### 7.2 落位与可复用性预检
- 复用面:本批零新增文件;闸件内新增两个纯函数(`build_identity`/`parse_metric`)——tools/ 39 个 .py 无共享解析模块(无 common/util 件,闸件自含是仓库现行形态),无既有件可复用
- 唯一面:身份键构造与恶化比对只落 `gdstyle_gate.py` 一处;static_scan.sh 与 README 的文案只述口径、禁止复写规则细节(口径唯一出处=闸件头注);基线登记值唯一事实源=基线行内消息文本
- 分层与交互面:纯 python 闸件,零游戏层交互;调用链=run_all_gates.sh(代码域档 09 段)→ static_scan.sh:247 → gdstyle_gate.py → gdstyle.exe(GDSTYLE_BIN 可覆盖)→ 基线读写;正常判定路径只读基线,唯 `--refresh` 写
## 8 任务卡
### T0 身份键与恶化判据(估时 0.2 工作日)
- 取用:无(首卡)
- 产出:`parse_metric(message: str) -> tuple[int, int] | None`(当前值与 max 值,解析不出返回 None);`build_identity(file_path: str, rule: str, message: str) -> str`(稳定身份键,含两级退化);判定输出新增 WORSE 行与改善计数(T2 与验收依赖)
步骤:
- [ ] 在 `gdstyle_gate.py` 落 `parse_metric` 与 `build_identity`(签名见产出块,落点=键构造段 :77-90 区域),两级退化路径齐备:无函数名退化「文件|规则」、解析不出数值退化全文键
- [ ] 判定段改为身份比对:基线行解析出身份与登记值 → 基线外身份判 NEW(现行语义不变);基线内身份且当前值>登记值判 WORSE;≤登记值判绿并计改善条数
- [ ] 闸件头注 `:11-13` 随动改写(身份键口径+恶化判据+退化路径)
- [ ] 窄确认:`PYTHONIOENCODING=utf-8 python tools/gdstyle_gate.py` → 必须得到「基线外新违规 0 条」+ WORSE 恰 3 条(`resume_adventure` 分支 11>10、`resume_adventure` 行数 108>104、`adventure_runner` 文件 1051>1050)+退出码 1(基线未刷新前恶化在红是预期态);数字不符=L3 停机
### T1 `--refresh` 对账与骤降守卫(估时 0.15 工作日)
- 取用:基线行格式约定(=现行「文件|规则|消息全文」,T0 不改格式)
- 产出:`--refresh` 对账输出(旧→新条数+逐条新登记/消失清单);骤降守卫(新<旧×0.8 或旧基线缺失 → 拒绝;`--allow-shrink` 放行)
步骤:
- [ ] refresh 段加对账:与旧基线逐行差集,打印新登记/消失两向清单与条数
- [ ] 加骤降守卫与 `--allow-shrink` 参数(用法说明行随动;拒绝状态下基线文件保持不变)
- [ ] 窄确认(夹具):临时 stub(GDSTYLE_BIN 指向一个应答 `--version` 为 0.4.0、扫描输出仅 1 条固定 JSON 的脚本)跑 `--refresh` → 拒绝、退出非零、`git diff` 基线为空;加 `--allow-shrink` → 写盘且对账打印「新登记 1/消失 239」级清单;`git checkout -- tools/gdstyle_baseline.txt` 还原(stub 为临时件,禁止入库)
### T2 基线重生成+文案随动+产出物落位(估时 0.15 工作日)
- 取用:T0 判定逻辑与预期读数;T1 refresh 对账
- 产出:基线 234 条落盘;两处文案;三份产出物
步骤:
- [ ] 正式刷新:`PYTHONIOENCODING=utf-8 python tools/gdstyle_gate.py --refresh` → 对账必须为「新登记 12/消失 17/总条数 239→234」;不符=L3 停机
- [ ] 窄确认:`python tools/gdstyle_gate.py` → 退出码 0
- [ ] 文案随动:`static_scan.sh:239-246` 头注与 `game/tests/README.md:64` 行(口径=稳定身份键+恶化判据+对账自检;禁止复写规则细节)
- [ ] 里程碑步:按改动域选档跑全套闸(本批只碰 tools/ 与 game/tests/ → 代码域档)全绿
- [ ] 验收对照表 R1–R8 逐条执行,撤销证明记录(变更点/命令/红输出摘要/还原结论)落实现报告
- [ ] 产出物落位:`reports/S13基线键治本-实现报告-<日期>.md`(含对账留档与撤销证明记录)、`reports/S13基线键治本-代拍板追认单-<日期>.md`、`reports/S13基线键治本-反哺点清单-<日期>.md`(零 design/ 反哺点+同步面四条去向闭环)——三份齐方算本卡完结
## 9 验证闸(改动—验收对照表)
证明口径=撤销证明(2026-10-24 用户裁定):变更被测面(回退改动段或更换基线夹具)→ 跑最窄闸 → 对应断言必须红 → 还原复绿。
| # | 需求点 | 改动(文件/行为) | 验收测试 | 层级 | 真实入口 | 撤销证明 |
|---|---|---|---|---|---|---|
| R1 | 数字漂移禁止再冒新违规 | gdstyle_gate.py 键构造改 build_identity | 刷新后闸跑「基线外新违规 0」 | 闸 | `python tools/gdstyle_gate.py` | 回退 T0 键构造改动段 → 12 条 NEW 复现红,还原复绿 |
| R2 | 名单外新违规仍必红 | 同上(身份匹配依赖基线在场) | 临时删基线一行无漂移条目(action_economy 类变量行)→ 该条 NEW 红、退出 1;还原复绿 | 闸 | 同上 | 删行夹具复红/还原复绿;回退 T0 改动段后同夹具仍红=拦截力保持的对照 |
| R3 | 恶化必红(X=0) | 判定段新增 WORSE 分支 | 临时把基线 `resume_adventure` 行数行的登记值 108 改 104 → WORSE 红、退出 1;还原复绿 | 闸 | 同上 | 回退 WORSE 判据改动段 → 同夹具不再红 |
| R4 | 改善禁止判红 | 同判定段 | T0 窄确认输出中 `_start_current_level`(55→53)与 `cross_validate` 四条等 9 条无 NEW 无 WORSE | 闸 | 同上 | 回退 T0 改动段后这 9 条变 NEW 红=改善判定系于 T0 |
| R5 | 骤降守卫+对账 | refresh 段 | stub 夹具:`--refresh` 拒绝且基线 git diff 为空;`--allow-shrink` 放行并打印两向清单 | 闸 | `GDSTYLE_BIN=<stub> python tools/gdstyle_gate.py --refresh` | 回退守卫改动段 → 同夹具直接写盘(不再拒绝) |
| R6 | 判定路径零写基线 | 判定段无写盘调用 | 跑闸后 `git diff --stat tools/gdstyle_baseline.txt` 为空 | 闸 | `python tools/gdstyle_gate.py` | 结构性(判定段零写调用,代码审读+行为验证双证) |
| R7 | 基线重排 234 条 | `--refresh` 正式跑 | wc -l=236(2 行头注+234 条)+对账「新 12/失 17」 | 闸 | `--refresh` | `git checkout` 基线 → 闸回到 WORSE 3 红态(绿态确实来自 234 条新基线的互证) |
| R8 | 文案两处随动 | static_scan.sh:239-246+README:64 | 人工核对与闸件口径一致,代码域档 09 段跑绿 | 文档面 | 按改动域选档跑闸 | 非行为改动,人工核对兜底 |
测试削弱申报:本批不删不放宽任何既有断言(闸自身判定逻辑更换内核,判据强度只升不降:NEW 拦截保持+新增 WORSE)。
独立验收审计:审计入口=未参与实现的会话按本表逐条抽查撤销证明记录;报告落 `reports/S13基线键治本-验收审计-<日期>.md`,未过禁合并。
## 10 异常分级
- L1 自救:对账/计数行的打印格式、排序、措辞问题——自助修
- L2 记录继续:未知规则消息形态触发全文键退化路径(设计内行为)——记进实现报告继续
- L3 停机呈报:任何窄确认预期数字不符(T0 非「NEW 0/WORSE 3」、T1 守卫未拒、T2 对账非「新 12/失 17/234 条」)——停机写呈报等用户
## 11 代拍板白名单
- 正则具体写法与转义细节(`function '([^']+)'`、当前值/max 值提取的容错)
- WORSE/改善/对账各行的输出措辞与排序
- 头注与 README 行的具体措辞(语义与判据不变)
- stub 夹具脚本的实现形态(临时件,禁止入库)
超出以上范围=呈报,禁自行拍板。
## 12 待裁点
零待裁点,开工门=U0。四点已于 2026-10-25 用户拍板(全案并列与淘汰依据留档):
1. 键形态=**B 稳定身份键**(淘汰 A 数字规范化——104→300 行的恶化被一并放过;淘汰 C 结构化输出——钉版二进制 JSON 无指标字段已实证,fork 超本批规模)
2. 恶化判据=**超登记值即红,X=0 不分规则**(淘汰 20% 宽容量——留温水通道、登记值缓慢失真;淘汰分规则给值——多一套参数面要维护)
3. 存量处置=**本批治本+批内人工刷新**(淘汰只刷新不改键——下一批再动这些文件必然重演;淘汰先冻结 S13 段——防线空窗+二次批成本)
4. 刷新自检=**加对账+骤降守卫**(淘汰不加、仅靠人工发起纪律——误跑一次即把新债静默洗进基线)
+2 -2
View File
@@ -41,13 +41,13 @@
#### S13 gdstyle 免名单把数字当身份——存量债改小也报「基线外新违规」(2026-10-25 登记,来源=批次移交,设计面=工程直入)
**现状**:工程债证据=迭代 35 卡② 合回前后实测(master 合回笔 `5499eb9c`)。闸件 `tools/gdstyle_gate.py:82` 把每条违规登记成三元组「文件|规则|消息全文」,而 gdstyle 的消息文本里带具体数字(如 `function 'resume_adventure' is 104 lines long (max 50)`),基线 `tools/gdstyle_baseline.txt`(241 行)按整句逐字比对——**只要某函数的行数/分支数/变量数发生变化,老违规就匹配不上,被判「基线外新违规」并判红,改小也算新增**。卡② 一批即因此冒出 12 项假新增,逐条对基线旧值核实全是存量债的计数漂移:`config_db_cross_validator.cross_validate` 159→107 行/31→21 分支/39→24 局部/嵌套 6→5(本批按卡片删除跨表校验④整段所致,债变小)、`level_runner` 类变量 40→38 且其「文件 1013 行超长」违规已消失(债被还掉)、`start_level_external` 参数 8→7、`main.gd` 1509→1507、`adventure_runner` 类变量 43→42/文件 1050→1051/`resume_adventure` 104→108 行(本批加断点代差标记键拒绝检查多 4 行)。本批真正新写的超标仅 1 处(新函数 `validate_graph` 72 行/20 分支),已当场拆成四段修掉。**盘面后果**:卡② 按用户令零复跑合回,master 尖 5499eb9c 从未整套跑绿过代码域闸;下一次任何批跑代码域闸都会看到 S13 红这 12 项(不处理则每批重复一次「要么重生成基线、要么被红挡在合回前」)。
**现状**:工程债证据=迭代 35 卡② 合回前后实测(master 合回笔 `5499eb9c`)。闸件 `tools/gdstyle_gate.py:82` 把每条违规登记成三元组「文件|规则|消息全文」,而 gdstyle 的消息文本里带具体数字(如 `function 'resume_adventure' is 104 lines long (max 50)`),基线 `tools/gdstyle_baseline.txt`(241 行)按整句逐字比对——**只要某函数的行数/分支数/变量数发生变化,老违规就匹配不上,被判「基线外新违规」并判红,改小也算新增**。卡② 一批即因此冒出 12 项假新增,逐条对基线旧值核实全是存量债的计数漂移:`config_db_cross_validator.cross_validate` 159→107 行/31→21 分支/39→24 局部/嵌套 6→5(本批按卡片删除跨表校验④整段所致,债变小)、`level_runner` 类变量 40→38 且其「文件 1013 行超长」违规已消失(债被还掉)、`start_level_external` 参数 8→7、`main.gd` 1509→1507、`adventure_runner` 类变量 43→42/文件 1050→1051/`resume_adventure` 104→108 行(本批加断点代差标记键拒绝检查多 4 行)。本批真正新写的超标仅 1 处(新函数 `validate_graph` 72 行/20 分支),已当场拆成四段修掉。**盘面后果**:卡② 按用户令零复跑合回,master 尖 5499eb9c 从未整套跑绿过代码域闸;下一次任何批跑代码域闸都会看到 S13 红这 12 项(不处理则每批重复一次「要么重生成基线、要么被红挡在合回前」)。已写卡(2026-10-25,卡片=reports/需求卡片-S13基线键治本-2026-10-25.md):四待裁点已拍板——稳定身份键/恶化判据超登记值即红/本批治本+批内刷新基线/refresh 加对账自检与骤降守卫;验收按 2026-10-24 撤销证明口径执行。
**预计改动面(两档,第一条只治标)**:① 治标=人工跑一次 `python tools/gdstyle_gate.py --refresh` 重生成基线+一笔提交,约 5 分钟,但键形态未改,下一批再动这些文件还会重演;② 治本=改 `tools/gdstyle_gate.py` 的键构造段(:77-90,约 10–20 行)为「文件|规则|函数名」——函数名从消息里正则提取 `function 'x'`,无函数名的条目(类变量数/文件长度)退化为「文件|规则」,并**另加一条恶化判据**防新键吞掉真问题(同一函数当前指标较基线登记值恶化超阈值即判红,纯规范化数字会把 104→300 行的恶化也放过去,不可只靠数字抹平);随动=重生成 `tools/gdstyle_baseline.txt`(241 行按新键重排)、`tools/run_all_gates.sh` 头注与 `game/tests/README.md` 工具速查表的 S13 描述各一行、变异验证四项(新增一处真超标必红/同函数改小改大的数字漂移禁止再冒新/恶化超阈值必红/禁闸内自动重生成清基线换绿的自检仍绿)。合计约 **0.5 个工作日**,非迭代批(tools/ 闸机与文档面),零待裁点即可写卡。
**归属**:tools/ 静态扫描域(闸件批,非迭代批)——与「S9 类型闸正则失灵修复」「S6/S7/S8 静态规则落地」两条同族:规则扫描面自身失灵/失准,防线不可信即等于没有防线
**状态**:待写卡
**状态**:已写卡
#### S6/S7/S8 静态规则落地——编排唯一性/禁 await/信号纪律三闸(2026-10-24 登记,来源=审计发现,设计面=工程直入)