Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .changeset/18983-connector-header-rate-limit-remedy.md
Original file line number Diff line number Diff line change
@@ -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.
22 changes: 19 additions & 3 deletions content/docs/references/integration/connector.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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`.

Expand Down
22 changes: 19 additions & 3 deletions packages/spec/src/integration/connector.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
*
Expand Down
Loading