docs(spec): SYNC_ARCHITECTURE.md L3 段停止宣传已退役的出站 Rate Limiting (#5554) - #6388
Conversation
`connector.rateLimitConfig` 及其整个形状(`ConnectorRateLimitConfig` + `RateLimitStrategy` 枚举)已在 @objectstack/spec 17.0.0 按 #4911 / ADR-0049 D2 退役,理由不是"暂时没人读",而是**出站限流引擎从来就不存在**:平台唯一的令牌桶 `packages/runtime/src/security/rate-limit.ts` 是入站的,没有任何东西节流连接器 发出的调用。文档的示例块早已带上墓碑注释,散文却没跟着改。 正文点名三处,实测为六处,全部改为如实说法(措辞复用 #4911 墓碑现成句: 出站限流请在 connector provider 或上游网关做): - L191 Purpose 导语:`rate limiting` → `retry policies` - L197 Key Features:删掉打勾的 `Rate Limiting: Token bucket, leaky bucket algorithms`(两个从来不存在的算法),改为显式的 ❌ 条目 + 引用块。这里用 显式否定而非静默删除:#4911 注释点名的危害是"作者以为平台替我限流"—— 这一面最像安全承诺,漏掉比编译不过更糟,只有写出来才消得掉。 - L356 Best Practices:限流请在 provider / 网关侧做;`retryConfig` 处理超限 后拿到的 429,它不负责让你不超限 - L374 Decision Matrix:⛔ 未删行(retry 那半是对的)。改写为"retry policies and circuit breaking",保留 `retryConfig` / `health.circuitBreaker`,并写明 出站限流不构成选择任何一层的理由 - L394 Pattern 2 示意图:`Rate Limiting` → `Retry / Circuit Breaker` - L447 Migration Guide L2→L3 引导语:同上 保留的每一条都对着 schema 核过,不是假定: - `retryConfig`(`connector.zod.ts:769`)在,`strategy` 默认 `exponential_backoff`,`retryableStatusCodes` 默认 `[408, 429, 500, 502, 503, 504]` —— 确含 429,故引用块可以这么写 - `health.circuitBreaker`(`ConnectorHealthSchema:526` → `CircuitBreakerConfigSchema:505`)在 纯散文改动,未动任何 ```typescript 块:`etl-author-shape.test.ts` 钉的总块数 仍为 6,`connector-author-shape.test.ts` 钉的 `Connector` 例子仍为 3(两个门禁 30 tests 实跑通过,非假定)。 `packages/spec/docs/` 不在该包 `package.json` 的 `files` 白名单内,不随包发布, 故不写 changeset,改用 `skip-changeset` 标签。 Fixes #5554 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
📓 Docs Drift CheckThis PR changes 1 package(s): 112 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:
|
|
PM 验收:ACCEPT — 已 ready + auto-merge。 CI:28 个 check,23 三处说的是 3 处,实测 6 处
两个措辞判断,我都认可,而且理由是对的① Key Features 用显式 ❌ 而不是静默删除。 你的理由:#4911 点名的危害是「作者以为平台替我节流出站调用」,而删除消不掉一个读者已经形成的信念,只有写出来的否定可以。这条判断在这个具体缺陷上尤其成立 —— 它是最像安全承诺的那一面,静默删除只会让下一个读者从别处再形成一次同样的信念。 ② Decision Matrix 那一行没有整行删。 retry 那半是真的,改写成「retry policies and circuit breaking」并点名 措辞复用 #4911 墓碑的现成句(在 connector provider 或上游网关做),没有另造一套 —— 一次退役出现两种说法就是它们日后互相矛盾的起点。 保留的每一条都对着 schema 核过,而且核出了一个精确度
两个门禁是跑过的,不是推理过的纯散文改动理应不动 我问的那个问题,你给了完整答案,而且把出处追到了
#6384 分开立,判断正确Key Features 还打勾宣传「Field Mapping: With transformations」,而 形状与 #5554 完全相同(示例块早带墓碑注释、散文没跟上),但是另一次退役 —— 所以另立而不是搭车。这个边界划得对:同一形状不等于同一件事,搭车会让两次退役的账混在一个 PR 里。 Generated by Claude Code |
Fixes #5554
背景
connector.rateLimitConfig及其整个形状(ConnectorRateLimitConfig与它内嵌的RateLimitStrategy枚举)已在@objectstack/spec17.0.0 按 #4911 / ADR-0049 D2 退役。退役理由不是"暂时没有读者",而是出站限流引擎从来就不存在:connector.zod.ts:317–349的长注释写得很明白 —— 平台唯一的令牌桶packages/runtime/src/security/rate-limit.ts是入站的(dispatcher 拿请求指纹调consume(key),超限 429 短路),没有任何东西节流连接器发出的调用。packages/spec/docs/SYNC_ARCHITECTURE.md的示例块早在 #5515 就带上了墓碑注释,散文却没跟着改。为什么值得一个 PR
Prime Directive #10 的反面。作者读到 Key Features 打勾那行去写
rateLimitConfig,拿到的是strictObject退役提示 —— 这还算好的。更糟的是不报错的那种失败:他会以为"平台会替我限流"成立,而这正是 #4911 注释专门点名的"最像安全承诺的一面"。一份 AI 会当权威读(ADR-0033)的文档里的假安全承诺,才是真实成本。改动:正文点名三处,实测为六处
正文列了三处;
grep -i "rate.limit"实测该文件另有三处同类措辞,按验收条件"若发现第四处,一并修掉并说明"一并处理。措辞统一复用 #4911 墓碑的现成句(出站限流请在 connector provider 或上游网关做),避免同一次退役出现两种说法而漂移。### Purpose导语… webhooks, rate limiting, and full lifecycle management.… webhooks, retry policies, and full lifecycle management.### Key Features- ✅ **Rate Limiting**: Token bucket, leaky bucket algorithms- ❌ **Outbound rate limiting**: **not provided**+ 一段引用块### Best Practices- **Rate Limiting**: Respect external API rate limits to avoid throttlingretryConfig处理超限后拿到的429,它不负责让你不超限## Decision Matrix| Do you need rate limiting and retry policies? | **Yes** → L3 (Connector) || Do you need retry policies and circuit breaking? | **Yes** → L3 —retryConfig,health.circuitBreaker。出站限流不构成选择任何一层的理由 |Webhooks, Auth, Rate LimitingWebhooks, Auth, Retry / Circuit BreakerWhen your ETL pipeline needs webhooks, advanced auth, or rate limiting:… or retry / circuit-breaker policies:两个刻意的取舍
第 2 处用显式否定,而不是静默删掉那一行。 悄悄删除只解决"编译不过"那一半;本单真正的伤害是作者带着错误认知离开。所以留一条 ❌ 条目并附引用块,写明:这行曾经写着什么、它为什么是假的、正确做法是什么、以及 ⛔ 不要拿
shared的RateLimitConfig顶替(那是入站限流器,会限反方向)。第 4 处⛔ 没有删行。 该行一半是对的(
retryConfig真在),整行删掉会连带删掉正确的一半。改写为保留 retry/断路器、并明确出站限流不是选层理由。保留的每一条都对着 schema 核过(不是假定)
retryConfigconnector.zod.ts:769,RetryConfigSchema:370Retry Policies: Exponential backoffstrategy默认'exponential_backoff'(connector.zod.ts:374)retryConfig的默认值含429」retryableStatusCodes默认[408, 429, 500, 502, 503, 504](connector.zod.ts:397)—— 确含 429,故这句可以写health.circuitBreakerConnectorHealthSchema:526→CircuitBreakerConfigSchema:505(enabled/failureThreshold/resetTimeoutMs/ …)措辞上刻意只说 L3 声明(declare)了这些形状,不承诺运行时行为 —— 本单没有核过执行者,不在一份正在修正过度承诺的文档里制造新的过度承诺。
门禁
该文档被两个门禁钉住,实跑确认而非假定(纯散文改动本不应移动它们):
packages/spec/src/automation/etl-author-shape.test.ts— 钉总 ```typescript 块数 = 6 ✅ 仍为 6packages/spec/src/integration/connector-author-shape.test.ts— 钉Connector例子 = 3(2 个省略号草图 + 1 个可编译sapConnector)✅ 未动全量:
packages/spec337 files / 8597 tests 全绿;typecheck、check:doc-authoring(365 files clean)、check:docs-audit-scope、check:nul-bytes均绿。Changeset:无(用
skip-changeset标签)按验收条件核过实际
packages/spec/package.json而非转述:files白名单为[dist, json-schema, liveness, prompts, llms.txt, README.md, src/**/*.zod.ts, CHANGELOG.md, api-surface, spec-changes.json]—— 不含docs/,本改动不随包发布,零用户可见变更。⛔ 空 frontmatter changeset 是禁止的(#6059 / #5471),故不写 changeset,改打skip-changeset标签。范围外发现(⛔ 本 PR 未修,已另开单)
connector.zod.ts模块 JSDoc 在三处宣传同一个已退役的出站限流,并被gen:docs逐字生成进content/docs/references/integration/connector.mdx(L21 / L25 / L56,其中comprehensive rate limiting尤其重)。这正面回答了SYNC_ARCHITECTURE.md的 L3Connector示例不可编译,且写的是 schema 会**拒收**的键名(sourceField/targetField/transform.type: 'custom'/ webhookretryPolicy) #5515 留下的未核项。顺带:connector.zod.ts全文没有任何@example块,所以该待核项的另一半是"不存在",而非"是对的"。⛔ 未在此修:references/**是生成产物(且 PR fix(spec): 参考文档顶层长枚举移入 Allowed Values,联合变体印数量 (#6225, #6226) #6377 正在其上作业),*.zod.ts属另一条 lane 的文件面。Field Mapping: With transformations,而FieldMapping.transform与整个联合已在 shared/mapping.zod.ts 的 javascript 变换 describe 推荐 dialect="js",而 ExpressionDialect 只有 cel/cron/template —— 照着写会被拒 #5552 / PR refactor(spec)!: 按 ADR-0049 退役 FieldMapping.transform 与整个 FieldMappingTransform 联合 —— 五成员零执行者 (#5552) #6078 退役(墓碑shared/mapping.zod.ts:89)。与本单同型但属另一次退役,故未搭车。🤖 Generated with Claude Code
https://claude.ai/code/session_014wsZeReNTqiceBfLb5Pyf5
Generated by Claude Code