fix(m162-r3): 金表条数与内容同源(堵住「少挂一段仍绿」的假绿)+ 补两条覆盖缺口

P2-1(r3 抓到的假绿):`golden::len()` 从「各段 len() 相加」改成 **`rows().count()`**。
r3 实测的变异是:删掉 `rows()` 里的 `chain(tail2::ROWS)` 后 `split_keeps_every_translation`
仍绿——因为条数来自一处手工聚合(仍含 tail2 ⇒ 459 == `Key::ALL.len()`)而内容只遍历
`rows()`(少了 213 行)。现在条数与内容同源,漏挂一段当场对不上。
- 变异复现(删 chain):`rows().count()=246 len()=246 Key::ALL.len()=459` ⇒ 用例
  **FAILED**(`left: 459 / right: 246`,「key 条数与拆分前不一致」);
- 恢复后:`rows().count()=459 len()=459 Key::ALL.len()=459` ⇒ **ok**;
- 断言一字未改(没有放宽成「只比条数」或「只比前缀」)。

顺带三条:
1. `golden.rs` 的 `rows()` 文档补上 `tail2`(并写明「加段必须也 chain 上,条数与内容只能从
   这一条序列导出」),与上一条同族。
2. `online/mod.rs` 模块表里 `[complete]` 的职责改成「按摘要认文件(`identity_of`)」,
   与「补全循环已删、生产在 `import::complete`」一致;批量 POST 那段也点明循环位置。
3. 补两条 pack 用例走不到的覆盖(`import/complete.rs` 的 `#[cfg(test)] mod tests`):
   - `an_entry_without_sha512_is_counted_not_guessed`:有 path、有 downloads、无 sha512 ⇒
     `unfilled += 1` **且一次请求都不发**(mrpack 读者强制 sha512,这条是防御分支);
   - `an_existing_download_list_is_never_extended`:已有直链时 `downloads` **逐字相等**
     (长度 + 内容),不再用「包含」这种测不出重复追加的断言。
   两条都验过能红:把「缺 sha512 不计数」与「总是追加直链」同时变异 ⇒ 两条 **FAILED**;
   恢复后 **ok**。

登记项(r3 指出的 scan 注记)也顺手收了:`Completion::note` 在 `filled == 0` 时改说
「按 sha512 从 Modrinth 补全 sha1:一条也没补到(补不出 N 条)」,并且不再带
「其余条目照旧按『缺省保留』处置」(那是导入场景的尾缀,预检里没有这回事)。用例
`offline_with_nothing_filled_does_not_say_zero_items_were_filled` 与
`import_online::only_a_real_offline_stops_the_completion_round` 都钉住「真断网 + 一条没补到」
既不说「补全了 0 条」也不说「缺省保留」。

全仓行数(guards.yml::file-size 同口径):**0 个超限**。
This commit is contained in:
AskaEth committed 2026-11-07 17:37:13 +08:00
1 parent ecd24f0608
commit 47ed270293
4 files changed
+216 -10

No files matched your search

+10 -3
View File
@@ -61,10 +61,12 @@ pub(super) const GOLDEN: &[(&str, &str, &str)] = &[
("InstancesLaunchReset", "Reset to global", "恢复跟随全局"),
];
/// 金表的**全量**行(三段:本文件 + [`tail`] + [`tail2`],顺序即 `Key::ALL`)。
/// 金表的**全量**行(本文件 → [`tail`] → [`tail2`],顺序即 `Key::ALL`)。
///
/// 拆成两段只为守 400 行硬线(M157 加了 19 行启动参数文案后越线);对调用方是**一条**序列,
/// 拆成三段只为守 400 行硬线(M157/M159 往金表追加文案后越线);对调用方是**一条**序列,
/// `catalog/tests.rs` 的逐字节断言不用关心分段。
///
/// ⚠️ 加段时**必须**在这里也 chain 上:条数与内容都只能从这一条序列导出(见 [`len`])。
pub(super) fn rows() -> impl Iterator<Item = &'static (&'static str, &'static str, &'static str)> {
GOLDEN
.iter()
@@ -73,8 +75,13 @@ pub(super) fn rows() -> impl Iterator<Item = &'static (&'static str, &'static st
}
/// 金表总行数(`Key::ALL` 的条数)。
///
/// **定义成 `rows().count()`,不是各段 `len()` 相加**:r3 复审实测过一条假绿——把
/// [`rows`] 里的 `chain(tail2::ROWS)` 删掉,`catalog/tests.rs` 仍全绿,因为条数来自一处手工
/// 聚合(仍有 tail2)而内容只遍历 `rows()`(少了 tail2),于是 213/459 行无人看守。
/// 现在条数与内容同源:漏挂一段 ⇒ 条数当场对不上 ⇒ 用例必红。
pub(super) fn len() -> usize {
GOLDEN.len() + tail::ROWS.len() + tail2::ROWS.len()
rows().count()
}
mod tail;