From de3d669f4d8f3291fe6aa3f2e614d51e20658506 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 12:19:55 +0000 Subject: [PATCH 1/2] docs(spec): correct the connector header's rate-limit remedy sentence The `connector.zod.ts` L3 header still taught that `retryConfig` (with its `retryableStatusCodes` `429` default) and `health.circuitBreaker` are what L3 declares for a rate-limited upstream. Both keys parse and store, and nothing reads either: `packages/spec/liveness/connector.json` records every `retryConfig` sub-key and every `health.circuitBreaker` sub-key as `dead`. Replace that one sentence with the wording PR #18979 landed for the same claim in `packages/spec/docs/SYNC_ARCHITECTURE.md`: declared but currently unimplemented, pointing at the liveness ledger, and explicitly neither retired nor left to the host. Prose only; no schema, declaration or accept set moves. Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3 Co-authored-by: Claude --- .../spec/src/integration/connector.zod.ts | 22 ++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/spec/src/integration/connector.zod.ts b/packages/spec/src/integration/connector.zod.ts index c0e6eb6ccbe..1ff7f697507 100644 --- a/packages/spec/src/integration/connector.zod.ts +++ b/packages/spec/src/integration/connector.zod.ts @@ -41,9 +41,25 @@ import { retiredKey } from '../shared/retired-key'; * the calls a connector makes *out*. Do **not** substitute `shared`'s * `RateLimitConfig` — that is the inbound limiter and would cap the wrong direction. * **Until an outbound throttle exists, rate-limit at the connector provider or - * upstream gateway.** What L3 does declare for a rate-limited upstream is - * `retryConfig` — whose `retryableStatusCodes` default `[408, 429, 500, 502, 503, - * 504]` includes `429` — and `health.circuitBreaker`. The full removal reasoning is + * upstream gateway.** **And do not reach for `retryConfig` instead.** This + * paragraph used to end "what L3 does declare for a rate-limited upstream is + * `retryConfig` — whose `retryableStatusCodes` default `[408, 429, 500, 502, + * 503, 504]` includes `429` — and `health.circuitBreaker`", which reads as a + * remedy. It is not one: both keys are **declared but currently + * unimplemented**. `packages/spec/liveness/connector.json` records every + * `retryConfig` sub-key and every `health.circuitBreaker` sub-key as `dead`, + * and outside `packages/spec` nothing reads either — no retry loop consumes a + * strategy, a backoff, a jitter or that status-code list, so the `429` in it + * never causes a retry, and no breaker ever opens. They are **not retired**: + * both are still declared and still parse, so an author can write them and see + * no error. They are **not left to the host** either — + * `ConnectorProviderContext` (`integration/connector-provider.ts`) carries + * exactly `name`, `label`, `description`, `icon`, `type`, `providerConfig`, + * `auth` and `loadPackageFile`, so a provider factory is never handed either + * key and has no way to honour it. ADR-0049 owes these keys a decision + * (retire / implement / declare as a host contract); until it rules, the + * advice above is the whole advice — retry and throttle **at the connector + * provider or upstream gateway**. The full removal reasoning is * recorded at the removal site: the "REMOVED: outbound rate limiting" block in * `integration/connector.zod.ts`, and `packages/spec/docs/SYNC_ARCHITECTURE.md`. * From c16ab281fe85c2490c97cea626b6a994dbe8c241 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 12:27:27 +0000 Subject: [PATCH 2/2] docs(spec): regenerate the connector reference page and add the changeset `gen:docs` propagates the corrected header paragraph into `content/docs/references/integration/connector.mdx`; the generated page is not hand-edited. The changeset is a `patch` on `@objectstack/spec` because `src/**/*.zod.ts` is in that package's `files[]` and the edited file is present in the published tarball, so the corrected text reaches consumers. Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3 Co-authored-by: Claude --- ...8983-connector-header-rate-limit-remedy.md | 36 +++++++++++++++++++ .../docs/references/integration/connector.mdx | 22 ++++++++++-- 2 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 .changeset/18983-connector-header-rate-limit-remedy.md diff --git a/.changeset/18983-connector-header-rate-limit-remedy.md b/.changeset/18983-connector-header-rate-limit-remedy.md new file mode 100644 index 00000000000..3a929a8fd6d --- /dev/null +++ b/.changeset/18983-connector-header-rate-limit-remedy.md @@ -0,0 +1,36 @@ +--- +'@objectstack/spec': patch +--- + +docs(spec): the connector header no longer teaches `retryConfig` as the remedy for a rate-limited upstream (#18983) + +`packages/spec/src/integration/connector.zod.ts` ships inside this package — +`files[]` carries `src/**/*.zod.ts`, and the file is present in the published +tarball — so its header TSDoc is text consumers read, and the generated +reference page is rendered from it. That header ended its "no outbound rate +limiting" paragraph with "what L3 does declare for a rate-limited upstream is +`retryConfig` — whose `retryableStatusCodes` default `[408, 429, 500, 502, 503, +504]` includes `429` — and `health.circuitBreaker`", which reads as a remedy. + +It is not one. `packages/spec/liveness/connector.json` records all eight +`retryConfig` sub-keys and every `health.circuitBreaker` sub-key as `dead` +(verifiedAt 2026-09-17), and outside `packages/spec` nothing reads either: no +retry loop consumes the strategy, the backoff, the jitter or that status-code +list, so the `429` in it never causes a retry, and no breaker ever opens. An +author who followed that sentence wrote configuration that parses, stores, and +is then silently ignored. + +The sentence now carries the wording PR #18979 landed for the same claim in +`packages/spec/docs/SYNC_ARCHITECTURE.md`: both keys are **declared but +currently unimplemented**, with a pointer to the liveness ledger, and they are +explicitly neither retired — both are still declared and still parse, so an +author writing them sees no error — nor left to the host, since +`ConnectorProviderContext` carries exactly `name`, `label`, `description`, +`icon`, `type`, `providerConfig`, `auth` and `loadPackageFile`, and a provider +factory is therefore never handed either key. + +**Prose only — zero behaviour change.** No schema, declaration, default or +accept set moves, and the keys' fate stays ADR-0049's to rule on rather than +being prejudged here. The generated reference page +`content/docs/references/integration/connector.mdx` follows from `gen:docs`; it +is not published by any package in this workspace. diff --git a/content/docs/references/integration/connector.mdx b/content/docs/references/integration/connector.mdx index 23370d3bdc4..9e3029ab94b 100644 --- a/content/docs/references/integration/connector.mdx +++ b/content/docs/references/integration/connector.mdx @@ -38,9 +38,25 @@ rate-limiting engine ever existed**. The platform's only token bucket (runtime the calls a connector makes *out*. Do **not** substitute `shared`'s `RateLimitConfig` — that is the inbound limiter and would cap the wrong direction. **Until an outbound throttle exists, rate-limit at the connector provider or -upstream gateway.** What L3 does declare for a rate-limited upstream is -`retryConfig` — whose `retryableStatusCodes` default `[408, 429, 500, 502, 503, -504]` includes `429` — and `health.circuitBreaker`. The full removal reasoning is +upstream gateway.** **And do not reach for `retryConfig` instead.** This +paragraph used to end "what L3 does declare for a rate-limited upstream is +`retryConfig` — whose `retryableStatusCodes` default `[408, 429, 500, 502, +503, 504]` includes `429` — and `health.circuitBreaker`", which reads as a +remedy. It is not one: both keys are **declared but currently +unimplemented**. `packages/spec/liveness/connector.json` records every +`retryConfig` sub-key and every `health.circuitBreaker` sub-key as `dead`, +and outside `packages/spec` nothing reads either — no retry loop consumes a +strategy, a backoff, a jitter or that status-code list, so the `429` in it +never causes a retry, and no breaker ever opens. They are **not retired**: +both are still declared and still parse, so an author can write them and see +no error. They are **not left to the host** either — +`ConnectorProviderContext` (`integration/connector-provider.ts`) carries +exactly `name`, `label`, `description`, `icon`, `type`, `providerConfig`, +`auth` and `loadPackageFile`, so a provider factory is never handed either +key and has no way to honour it. ADR-0049 owes these keys a decision +(retire / implement / declare as a host contract); until it rules, the +advice above is the whole advice — retry and throttle **at the connector +provider or upstream gateway**. The full removal reasoning is recorded at the removal site: the "REMOVED: outbound rate limiting" block in `integration/connector.zod.ts`, and `packages/spec/docs/SYNC_ARCHITECTURE.md`.