在 #4684(双源清账 C9)的调研中发现,记录备查,未认领。
事实
packages/spec 声明了两份 RateLimitConfig,两份都没有任何运行时读者:
$ grep -rn "RateLimitConfig" --include=*.ts packages/ core/ examples/ apps/ \
| grep -v node_modules | grep -v /dist/ | grep -v "packages/spec/"
(无输出)
对具体键做同样的扫描(windowMs / windowSeconds / maxRequests / burstCapacity / respectUpstreamLimits),packages/spec/src/** 自己的测试之外同样零命中。
四个嵌入点因此全部是「声明了但没人执行」:
| 嵌入点 |
声明来源 |
ApiEndpointSchema.rateLimit(api/endpoint.zod.ts:47) |
shared/http.zod.ts |
ApiEndpointRegistrationSchema.rateLimit(api/registry.zod.ts:379) |
shared/http.zod.ts |
HttpServerConfigSchema.security.rateLimit(system/http-server.zod.ts:71) |
shared/http.zod.ts |
ConnectorSchema.rateLimitConfig(integration/connector.zod.ts:674) |
integration/connector.zod.ts |
前三个从 stack.zod.ts 的 apis: 可达,第四个从 connectors: 可达 —— 都是真实的作者面,作者写下去解析通过,然后什么也不发生。
更值得注意的:真正干活的是第三份形状
packages/runtime/src/security/rate-limit.ts 有一个手写的 in-memory token bucket,它不 import spec,自带一套接口:
export interface RateLimitBucketConfig {
capacity: number; // 对应不上 maxRequests
refillPerSec: number; // 对应不上 windowMs / windowSeconds
defaultCost?: number; // 两侧 spec 都没有
}
所以现状是 三份 rate-limit 形状、零条从作者面到执行面的通路:两份在 spec 里给作者写,一份在 runtime 里真正限流,互不相识。这正是 Prime Directive #10 的「declared ≠ enforced」与 ADR-0049 的 enforce-or-remove 场景。
建议(留给维护者裁决,不要顺手做)
三选一,都是协议级决定:
- 接上执行 —— 让 dispatcher 从
ApiEndpoint.rateLimit / HttpServerConfig.security.rateLimit 推导出 RateLimitBucketConfig(capacity = maxRequests,refillPerSec = maxRequests / (windowMs / 1000)),connector 侧同理接到出站调用上。
- 按 ADR-0049 摘掉 —— 走完整退休套件(tombstone + D2/D3 + changeset)。
- 先只修 connector 侧,API 侧接执行 —— 出站/入站两个方向的执行者本来就不是同一个。
⚠️ 与 #4684 / #4535 的关系:C9 簇正在裁决这两份声明的命名/收敛路线。本单是执行面的问题,与命名路线正交,但两者的答案会互相影响 —— 如果结论是 2(摘掉一侧),C9 的双源就自动消失了。建议一起排期看。
关联:#4684、#4535、ADR-0049、Prime Directive #10
在 #4684(双源清账 C9)的调研中发现,记录备查,未认领。
事实
packages/spec声明了两份RateLimitConfig,两份都没有任何运行时读者:对具体键做同样的扫描(
windowMs/windowSeconds/maxRequests/burstCapacity/respectUpstreamLimits),packages/spec/src/**自己的测试之外同样零命中。四个嵌入点因此全部是「声明了但没人执行」:
ApiEndpointSchema.rateLimit(api/endpoint.zod.ts:47)shared/http.zod.tsApiEndpointRegistrationSchema.rateLimit(api/registry.zod.ts:379)shared/http.zod.tsHttpServerConfigSchema.security.rateLimit(system/http-server.zod.ts:71)shared/http.zod.tsConnectorSchema.rateLimitConfig(integration/connector.zod.ts:674)integration/connector.zod.ts前三个从
stack.zod.ts的apis:可达,第四个从connectors:可达 —— 都是真实的作者面,作者写下去解析通过,然后什么也不发生。更值得注意的:真正干活的是第三份形状
packages/runtime/src/security/rate-limit.ts有一个手写的 in-memory token bucket,它不 import spec,自带一套接口:所以现状是 三份 rate-limit 形状、零条从作者面到执行面的通路:两份在 spec 里给作者写,一份在 runtime 里真正限流,互不相识。这正是 Prime Directive #10 的「declared ≠ enforced」与 ADR-0049 的 enforce-or-remove 场景。
建议(留给维护者裁决,不要顺手做)
三选一,都是协议级决定:
ApiEndpoint.rateLimit/HttpServerConfig.security.rateLimit推导出RateLimitBucketConfig(capacity = maxRequests,refillPerSec = maxRequests / (windowMs / 1000)),connector 侧同理接到出站调用上。关联:#4684、#4535、ADR-0049、Prime Directive #10