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:
@ -20,14 +20,14 @@ import (
|
||||
//
|
||||
// `agents` 表这边只剩两样东西:
|
||||
//
|
||||
// default_rounds —— 派给这个 Agent 的**新任务**默认多少个来回。
|
||||
// 不同 Agent 能力不同(跑测试的小工具 vs 重构整个模块),
|
||||
// 默认值分开设才合理。
|
||||
// default_rounds —— 派给这个 Agent 的**新任务**默认多少个来回。
|
||||
// 不同 Agent 能力不同(跑测试的小工具 vs 重构整个模块),
|
||||
// 默认值分开设才合理。
|
||||
//
|
||||
// used_rounds —— 纯统计,累计发信数。**不再拦任何请求。**
|
||||
// 它原本是「终身额度」:跑满就得管理员手工重置才能再干活,
|
||||
// 而 Agent 是长期在线的 —— 终身额度是错的工具。
|
||||
// 保留是因为「这个 Agent 一共发了多少信」本身有观测价值。
|
||||
// used_rounds —— 纯统计,累计发信数。**不再拦任何请求。**
|
||||
// 它原本是「终身额度」:跑满就得管理员手工重置才能再干活,
|
||||
// 而 Agent 是长期在线的 —— 终身额度是错的工具。
|
||||
// 保留是因为「这个 Agent 一共发了多少信」本身有观测价值。
|
||||
//
|
||||
// 防止 Agent 用 `.new` 开一串新会话绕过预算,靠的是**新建会话速率限制**
|
||||
// (见 sessionRateLimiter),而不是终身额度。
|
||||
@ -169,7 +169,7 @@ type ForwardSource struct {
|
||||
}
|
||||
|
||||
// LoadForwardSource 读取待转发的邮件,并校验转发者确实参与过该邮件
|
||||
//(收件人、发件人或被抄送方之一)。防止凭 mail_id 转发别人的邮件。
|
||||
// (收件人、发件人或被抄送方之一)。防止凭 mail_id 转发别人的邮件。
|
||||
func LoadForwardSource(ctx context.Context, mailID uuid.UUID, actor string) (*models.Mail, error) {
|
||||
m, err := GetMailByID(ctx, mailID)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user