fix(欠账): Skip 进余额且条件必须是测量;豁免按文件+次数;三笔欠账合成一处可读余额
pi 2026-09-14 三条(他接受了我对"恒红=相位错"的反驳,但指出 Skip 带来的两处漏洞)。
1. **Skip 必须进余额、条件必须是测量**:
- **条件**:跳过与否由 `measureMailStatusDebt` **实测**(详情路径的 status 是否真的
等于按读者派生),不是常量、不是"我们还没迁完"这种没人会更新的事实;
- **余额**:`docs/DEBTS.json` 是**唯一登记**,Go 侧判据 `TestDebtLedgerMatchesMeasurement`
**自己测量**后与登记比对(第一版我让余额由另一条判据写入 ⇒ **排序依赖**,
Go 同包内按源文件顺序跑,登记那条先跑就读到 0 —— 排序依赖是隐蔽的假绿,已抽成自足函数);
- **可见性**:`go test` 跑通时**不打印包的输出**,我第一版把余额打在 TestMain 里,
常态运行一个字都看不见 —— 正是 pi 说的"不显形"。所以常态可见的那份打在
electron 套件的 RESULT 行:`RESULT phase=install static=5 debts=7
(static-criteria:5,mails-status-derived:1,gesture-semantics:1) probe=ok`。
2. **豁免从"按文件"改成"按文件 + 次数"**:`migrate.go` 这类比较**上限 2 处**(附理由),
多一处即红。我在读侧清册上自己修过这个洞,豁免那格却退了一格 —— pi 指出得对。
3. **三笔欠账合成一处**:原先各自表达(`RESULT static=5` / `t.Skip` 无余额 /
文档里的到期前提无余额),**没有一处能一眼看全**。现在统一登记在 `docs/DEBTS.json`
(id / 余额 / 到期前提 / 判据位置),两端读同一份:Go 侧比对实测,electron 侧打进 RESULT 行。
还清那天:登记要跟着清 —— 不清则由 `TestDebtLedgerMatchesMeasurement` 报
"**欠账已还清**,但登记还记着 N"(还清是可测事件,这正是那条判据存在的意义)。
This commit is contained in:
@ -59,10 +59,21 @@ func TestMailsStatusReadersAreRegistered(t *testing.T) {
|
||||
*/
|
||||
compareRe := regexp.MustCompile(`\bm\.status\s*(?:=|<>|!=)\s*'([a-z_]+)'`)
|
||||
allowedLiteral := "archived"
|
||||
// 按文件登记的豁免(带理由);不在这张表里的文件与 'archived' 之外的字面量比较 ⇒ 红
|
||||
allowedCompareExempt := map[string]string{
|
||||
"migrate.go": "迁移回填:把历史 'read' 折进 mail_reads —— 它**必须**读那个遗留值,这是它的职责",
|
||||
/*
|
||||
* 豁免必须**按文件 + 次数**(pi 2026-09-14 裁定 §2)。
|
||||
*
|
||||
* 我在读侧清册上自己发现并修过这个洞("文件里有没有"挡不住"在已允许的文件里再新增一处"),
|
||||
* 但豁免这一格又退了一格:只按文件放行 ⇒ 明天有人在同一个迁移文件里新加一处
|
||||
* `WHERE m.status='read'`,豁免直接吞掉它、没有任何东西会红。
|
||||
* 所以豁免也记**上限次数**,多一处即红 —— 与读侧清册同形,理由字段照留。
|
||||
*/
|
||||
allowedCompareExempt := map[string]struct {
|
||||
max int
|
||||
why string
|
||||
}{
|
||||
"migrate.go": {2, "迁移回填:把历史 'read' 折进 mail_reads —— 它**必须**读那个遗留值(全新安装/空库路径也要有)。上限 2 处,多一处即红"},
|
||||
}
|
||||
exemptSeen := map[string]int{}
|
||||
|
||||
writeRe := regexp.MustCompile(`UPDATE\s+mails\s+SET\s+status`)
|
||||
readRe := regexp.MustCompile(`\bm\.status\b|mails\.status`)
|
||||
@ -96,8 +107,14 @@ func TestMailsStatusReadersAreRegistered(t *testing.T) {
|
||||
* mail_reads),所以这里比 'read' 不但正当,而且是必须的。
|
||||
* 豁免也做成**可判的**:按文件登记 + 写明理由(不是"凡是迁移都放行")。
|
||||
*/
|
||||
if why, ok := allowedCompareExempt[base]; ok {
|
||||
_ = why
|
||||
if ex, ok := allowedCompareExempt[base]; ok {
|
||||
exemptSeen[base]++
|
||||
if exemptSeen[base] <= ex.max {
|
||||
continue
|
||||
}
|
||||
badCompare = append(badCompare,
|
||||
fmt.Sprintf("%s:%d **超出豁免上限**(%s 这类比较上限 %d 处,理由:%s)—— %s",
|
||||
base, i+1, base, ex.max, ex.why, strings.TrimSpace(line)))
|
||||
continue
|
||||
}
|
||||
badCompare = append(badCompare,
|
||||
|
||||
Reference in New Issue
Block a user