Skip to content

phoneOtp.cooldownSeconds 配成大于 1 小时会被静默截断 —— OtpSendGuard 的历史 TTL 硬编码 1 小时 #4808

Description

@os-zhuang

由 #4790 的 dev 在实施中发现并记录,PM 代为立单(dev 判断"属默认值不会触及的边角"而只写进报告,我认为它够得上一条 issue —— 理由见下)。未认领。改动前后行为一致,非 #4806 引入。

现象

OtpSendGuard 的发送历史 TTL 硬编码为 1 小时。若把 phoneOtp.cooldownSeconds 配成大于 3600,冷却判定所依赖的历史记录会先被滚动窗剪枝掉,于是:

  • 声明:「两次发送之间至少间隔 N 秒」(N > 3600);
  • 实际:超过 1 小时之后历史就没了,冷却最多只有 1 小时;
  • 信号:无。配置被接受,没有校验错误,没有 warn。

为什么值得立单,而不只是记在报告里

dev 的判断(边角、默认值不会触及)是对的,但这恰好是本仓正在系统性关掉的那一类,而且是其中最隐蔽的一种:

配置项不是被忽略(那还容易发现),而是被接受、被部分执行。管理员设了 2 小时冷却,系统给了 1 小时,而且看起来一切正常 —— 反滥用强度是声明值的一半,没有任何东西说出来。这与 #4790 本身(预算按节点倍增、无信号)是同一个形状,只是维度从"节点数"换成了"时间"。

按 ADR-0049(declared = enforced):要么真的支持 > 1 小时的冷却,要么在配置校验期拒绝这个值并说明上限。静默截断是唯一不该保留的选项。

修法方向(择一,倾向 1)

  1. 让 TTL 跟随配置:历史保留时长取 max(1h, cooldownSeconds),冷却按声明值真正生效。最符合"声明即强制",代价是超长冷却会让历史条目留得更久(可加一个合理上限,但那个上限要显式拒绝超出的配置,而不是截断)。
  2. 在配置校验期拒绝 cooldownSeconds > 3600,错误信息说明当前实现上限及原因。诚实、成本最低,但把一个能力限制写死进契约,以后想放开要走变更。

不建议第 3 条(维持现状 + 文档说明)—— 文档拦不住配置文件里那个数字。

验收

  • 配 cooldownSeconds 大于 1 小时时,要么真的生效,要么被明确拒绝;两种都可接受,静默截断不可接受;
  • 默认配置行为不变(有测试证明,别为边角改动误伤主路径);
  • 若取方案 1,加一条测试:冷却设为 > 1 小时时,超过 1 小时后的发送仍被拒。

关联

Activity

  1. claude commented on Aug 3, 2026

    @claude
    Contributor

    认领:PM 循环第 7 轮
    会话:session_015Br2xsJsczFsTR9bvbh2Ny
    分支:claude/issue-4808-otp-cooldown-ttl
    Worktree:objectstack-issue-4808

    域:identity
    文件面:packages/plugins/plugin-auth (OtpSendGuard)

    并行批隔离:本轮同批的另三条落在互不相交的包 —— #4825 packages/metadata、#4813 packages/core、#4808 packages/plugins/plugin-auth、#4820 packages/services/service-analytics。⚠️ #4821(mergeByDimensions 分隔符)与 #4820 同文件,未同批派发,串到下一轮以避开撞车。


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions