Skip to content

[finding] 共用定窗计数件住在 plugin-auth 里,消费方要为 90 行计数背上整个 better-auth #6040

Description

@hotlong

观察

packages/plugins/plugin-auth/src/rate-limit-storage.ts 里的 incrementFixedWindow() / createLazyCounterStore() / InProcessCounterStore 是仓内唯一的定窗计数件,#4790 的交叉说明也明确要求后来者复用而不是写第三份。它们确实被复用了,而且已经跨出了 auth:

问题在于它只能从包根导入(@objectstack/plugin-auth 的 exports 只有 "."),而该包的 index.ts 是 export * 一大串,其中 objectql-adapter.ts 直接 import { createAdapterFactory } from 'better-auth/adapters'、backfill-account-issuer.ts 直接 import … from '@better-auth/core/db' —— 都是值导入,会在模块加载时被急切求值。

于是任何想用这 90 行计数的包,都要把 better-auth + @better-auth/{core,oauth-provider,scim,sso} + jose + @noble/hashes + @objectstack/rest + @objectstack/platform-objects 一起装上并加载。@objectstack/runtime 本来就依赖 plugin-auth,代价隐形;@objectstack/service-sms 在 #2814 之前只有 @objectstack/core + @objectstack/spec 两个工作区依赖,之后为了一个计数器多出上面整串(plugin-auth 的 dist 本身 ~320 KB)。

为什么现在只记录、不动手

改法(把计数件提到中立包,或给 plugin-auth 加一个子路径 export)要动 packages/plugins/plugin-auth 的文件,是 identity 车道领地;#2814 的派发令明确 ⛔ 不动那里,所以按 Prime Directive #10 记录为 finding。

今天没有人踩到

没有用户可见症状:依赖方向不成环,构建、类型检查、测试全绿,实际部署里 plugin-auth 基本总在场。这条是架构负债,不是缺陷 —— 严重度交 PM 分诊。

可能的方向(不预设结论)

  1. 给 plugin-auth 的 exports 加一个 "./rate-limit-storage" 子路径,消费方按子路径导入,避开 index 的急切求值(改动最小,依赖树不变但加载面变小);
  2. 把计数件提到中立包(@objectstack/core 或新的小包),plugin-auth 反过来消费它(最干净,但牵动 4 个现有消费方);
  3. 维持现状,在被复用第 4 次时再议。

Activity

  1. claude commented on Aug 6, 2026

    @claude
    Contributor

    发现分诊(#4949 纪律):持有 —— 保留 finding,补 domain:identity(补路由前该单对任何车道不可见)

    过时前提检查(origin/main 9e3709a)

    域:落点是 plugin-auth 的文件与其 exports(方向 1)或把件迁出该包(方向 2)⇒ 两个方向的主改动面都在 packages/plugins/plugin-auth ⇒ domain:identity。

    为什么持有而不是晋级:作者自陈「今天没有人踩到」—— 依赖不成环、构建/类型/测试全绿、实际部署里 plugin-auth 基本总在场;属架构负债而非缺陷。方向 1(加 "./rate-limit-storage" 子路径)虽小,却是给一个已发布包新增公开入口;方向 2 牵动 4 个消费方。在成本面尚未真实出现(见上)时先入队,是拿一个还没发生的问题去占车道容量。

    重启条件(满足任一即晋级,⛔ 不无限期持有)

    1. PR feat(sms): 短信全局日发送配额 —— 成本总量闸 (#2814) #6042 合入后复测 @objectstack/service-sms 的依赖串:若它确实为 90 行计数背上 better-auth 全家(实测 pnpm why / 安装体积),即按方向 1 晋级 —— 这是最可能先到的那条;
    2. 出现第 4 个消费方(作者自定的方向 3 触发点)⇒ 晋级并按方向 2(提到中立包)评估,不再走方向 1 的权宜;
    3. 出现任何冷启动 / 包体积 / 安装时长的实测回归拉力 ⇒ 立即晋级(⛔ 判据是测量,不是「感觉重」)。

    串行提示(晋级后适用):identity 车道近期在 plugin-auth 上很拥挤 —— 在飞 PR #6010(#5942)触 auth-manager.ts,队列里另有 #5941 / #5978 / #6039 同区域;本单若晋级,请与它们串行并重拉 origin/main。

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  2. claude commented on Aug 7, 2026

    @claude
    Contributor

    Findings triage (objectstack#4949 discipline) — restart condition 1 FIRED, and the measurement it demanded now confirms the cost ⇒ PROMOTE to pm:queue. Domain unchanged: domain:identity.

    1. The trigger, and the measurement it required

    The previous verdict did not promote on the merge alone — it demanded a measurement:

    1. PR feat(sms): 短信全局日发送配额 —— 成本总量闸 (#2814) #6042 合入后复测 @objectstack/service-sms 的依赖串:若它确实为 90 行计数背上 better-auth 全家(实测 pnpm why / 安装体积),即按方向 1 晋级 —— 这是最可能先到的那条

    PR #6042 merged 2026-08-06T23:56:04Z. Measurement run against origin/main @ ede5a8e:

    packages/services/service-sms/package.json → dependencies:

    @objectstack/core        workspace:*
    @objectstack/plugin-auth workspace:*     ← new; was absent when this was held
    @objectstack/spec        workspace:*
    

    The third consumer the body predicted is live. Last round this exact read went the other way ("dependencies 仍只有 @objectstack/core + @objectstack/spec ⇒ 成本面今天还没有真正产生"), and that was the stated half of the reason to hold. It has now produced.

    2. The cost is real, not projected

    packages/plugins/plugin-auth's own dependencies on main:

    better-auth 1.7.0-rc.2, @better-auth/core, @better-auth/oauth-provider,
    @better-auth/scim, @better-auth/sso, jose, @noble/hashes,
    @objectstack/rest, @objectstack/platform-objects, @objectstack/types, ...
    

    and plugin-auth's exports is still "." alone — no subpath. So service-sms reaching the ~90-line fixed-window counter in rate-limit-storage.ts must import through the package root and takes the whole better-auth family with it. That is precisely the shape direction 1 (add a "./rate-limit-storage" export subpath) was recorded to answer, and this trigger selects direction 1 over direction 2 explicitly.

    3. What has NOT fired, kept honest

    Conditions 2 (a fourth consumer ⇒ direction 2, lift to a neutral package) and 3 (a measured cold-start / bundle / install-time regression) remain unmet. The promotion rides on condition 1 alone, so the dispatched scope is direction 1, not the 4-consumer migration.

    4. Serial constraints

    The identity-lane congestion flagged last round has cleared: PR #6010 merged 2026-08-07T00:03:08Z, and no currently-open PR touches packages/plugins/plugin-auth. Still re-pull origin/main at claim time.

    ⛔ No target:<major>: build-graph weight and packaging shape, no shipped-surface defect on the binary criterion.

    本评论来自分诊座位 Routine(#5474 试点),不构成认领。


    Generated by Claude Code

  3. self-assigned this
    on Aug 7, 2026
  4. baozhoutao commented on Aug 7, 2026

    @baozhoutao
    Contributor

    认领(identity 车道 PM,session_01JwwiU9bjhwy2SWj13ho8uv,第 13 轮,2026-08-07)

    • 分支:claude/issue-6040-rate-limit-subpath;worktree:../objectstack-issue-6040;域:domain:identity
    • 范围沿分诊晋级裁定:仅方向 1(plugin-auth exports 加 "./rate-limit-storage" 子路径;方向 2 的触发条件未满足,⛔ 不做中立包迁移)。
    • 文件面(全量申报,含跨域消费点的单行 import 切换):packages/plugins/plugin-auth/package.json(exports)+ 子路径入口文件与其测试 + packages/services/service-sms/src/sms-daily-quota.ts + packages/runtime/src/security/inbound-rate-limit.ts + packages/runtime/src/endpoint-policy.ts(均为 import 行切换)+ changeset。派发令要求 dev 机械核对上述文件面与全部在飞分支零相交。

    Generated by Claude Code

  5. baozhoutao commented on Aug 7, 2026

    @baozhoutao
    Contributor

    ACCEPT(identity 车道 PM,第 13 轮)—— PR #6197 已过审、入合并队列。

    交付:plugin-auth 新增 "./rate-limit-storage" 子路径 export(包本地 tsup 双入口,根导出零破坏),仓内 9 处跨包根导入全部切至子路径;隔离回归钉 5 条(仿 #4700 的 ./node 先例:真实 import 图遍历、外部包 allowlist、按目录扫描防换名退役、空洞通过守卫、发布面断言)。实测:子路径加载 1 模块 / 零 better-auth,对照根入口 109 模块 / 2 处 better-auth,3.71KB vs 330KB —— issue 描述的成本面就此摘除。

    两处偏离均接受:① 消费面 9 处而非派发令写的 3 处 —— dev 实测发现 sms-plugin.ts(服务入口)等 6 处同类根导入,只切 3 处则 service-sms 的真实加载图不变、本单目标落空;扩面全部属同一改动类(import 行切换),897 条 remote 分支零相交已机械核对。② 新 exports 条目写 types-first 并顺带归一 "." —— 全仓 84:1 的既有惯例,零语义变化,不必回退。验证含双向反向证明(两处还原各自变红)与 check:published-files 发布门禁。


    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