Skip to content

Commit 6007a48

Browse files
committed
Merge remote-tracking branch 'origin/main' into claude/issue-18670-dependent-required-arm
2 parents cb2d486 + f347c79 commit 6007a48

1 file changed

Lines changed: 35 additions & 7 deletions

File tree

‎packages/spec/docs/SYNC_ARCHITECTURE.md‎

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,25 @@ Complete, production-grade integration with external systems. Includes authentic
153153
> nothing throttles the calls a connector makes *out*. Do **not** substitute
154154
> `shared`'s `RateLimitConfig` — that is the inbound limiter and would cap the
155155
> wrong direction. **Until an outbound throttle exists, rate-limit at the
156-
> connector provider or upstream gateway.** What L3 does declare for a
157-
> rate-limited upstream is `retryConfig` — whose `retryableStatusCodes` default
158-
> `[408, 429, 500, 502, 503, 504]` includes `429` — and `health.circuitBreaker`.
156+
> connector provider or upstream gateway.** **And do not reach for
157+
> `retryConfig` instead.** This paragraph used to end "what L3 does declare for
158+
> a rate-limited upstream is `retryConfig` — whose `retryableStatusCodes`
159+
> default `[408, 429, 500, 502, 503, 504]` includes `429` — and
160+
> `health.circuitBreaker`", which reads as a remedy. It is not one: both keys
161+
> are **declared but currently unimplemented**.
162+
> `packages/spec/liveness/connector.json` records every `retryConfig` sub-key
163+
> and every `health.circuitBreaker` sub-key as `dead`, and outside
164+
> `packages/spec` nothing reads either — no retry loop consumes a strategy, a
165+
> backoff, a jitter or that status-code list, so the `429` in it never causes a
166+
> retry, and no breaker ever opens. They are **not retired**: both are still
167+
> declared and still parse, so an author can write them and see no error. They
168+
> are **not left to the host** either — `ConnectorProviderContext`
169+
> (`src/integration/connector-provider.ts`) carries exactly `name`, `label`,
170+
> `description`, `icon`, `type`, `providerConfig`, `auth` and
171+
> `loadPackageFile`, so a provider factory is never handed either key and has
172+
> no way to honour it. ADR-0049 owes these keys a decision (retire / implement /
173+
> declare as a host contract); until it rules, the advice above is the whole
174+
> advice — retry and throttle **at the connector provider or upstream gateway**.
159175
160176
> **Field mapping does not transform values.** The ticked line above used to read
161177
> "With transformations and data type conversion". Only the second half was ever
@@ -297,7 +313,12 @@ const sapConnector: Connector = {
297313
// (`rateLimitConfig` sat here until #4911 retired it — no outbound
298314
// rate-limiting engine ever existed. Throttle at the provider/gateway.)
299315

300-
// Retry Configuration — for the connector's own outbound requests
316+
// Retry Configuration — DECLARED BUT CURRENTLY UNIMPLEMENTED. The block
317+
// below parses and is stored, and nothing reads it: no retry loop exists, so
318+
// the `retryableStatusCodes` list — 429 included — never causes a retry.
319+
// Every sub-key is recorded `dead` in `packages/spec/liveness/connector.json`,
320+
// and ADR-0049 owes it a decision. It is shown because this example is a tour
321+
// of the surface, not because authoring it buys behaviour.
301322
retryConfig: {
302323
strategy: 'exponential_backoff',
303324
maxAttempts: 5,
@@ -309,6 +330,10 @@ const sapConnector: Connector = {
309330
jitter: true
310331
},
311332

333+
// Also declared but currently unimplemented, and `dead` in the same
334+
// ledger (`packages/spec/liveness/connector.json`):
335+
// both timeouts parse and default, and no fetch, transport or handler reads
336+
// either, so a connector call is unbounded whatever is written here.
312337
connectionTimeoutMs: 30000,
313338
requestTimeoutMs: 60000,
314339
status: 'active',
@@ -333,8 +358,11 @@ const sapConnector: Connector = {
333358
- **Security First**: Always use encrypted credentials and secure storage
334359
- **Rate Limiting**: Respect the upstream API's limits — and enforce that at the
335360
connector provider or upstream gateway, since the connector shape declares no
336-
outbound throttle (#4911). `retryConfig` handles the `429` you get for exceeding a
337-
limit; it does not keep you under one
361+
outbound throttle (#4911). This bullet used to add that `retryConfig` handles
362+
the `429` you get for exceeding a limit. It does not: `retryConfig` is
363+
declared but currently unimplemented — every sub-key is `dead` in
364+
`packages/spec/liveness/connector.json` — so nothing retries that `429`
365+
either. Both the throttling and the retrying are the provider's to implement
338366
- **Error Handling**: Implement comprehensive retry logic with exponential backoff
339367
- **Monitoring**: Set up health checks and alerting for connector failures
340368
- **Testing**: Test authentication, sync, and webhook flows thoroughly
@@ -357,7 +385,7 @@ mostly answers "which surface", and — for the two questions that used to route
357385
| Do you need multi-source aggregation? | **Same answer**, and for the same reason — see [Retired: L2 ETL Pipeline](#retired-l2-etl-pipeline-v17) |
358386
| Do you need real-time webhooks? | **Yes** → L3 (Connector) |
359387
| Do you need advanced authentication (OAuth2, SAML)? | **Yes** → L3 (Connector) |
360-
| Do you need retry policies and circuit breaking? | **Yes** → L3 (Connector) — `retryConfig`, `health.circuitBreaker`. Outbound **rate limiting** is not a reason to pick any level: no level provides it (#4911); throttle at the provider or gateway |
388+
| Do you need retry policies and circuit breaking? | **Not a reason to pick a level.** L3 *declares* `retryConfig` and `health.circuitBreaker`, but both are **declared but currently unimplemented** — every sub-key of each is `dead` in `packages/spec/liveness/connector.json`, nothing outside `packages/spec` reads either, and ADR-0049 owes them a decision — so neither is a capability you can select for. Implement retry and circuit breaking in the connector provider. Outbound **rate limiting** is not a reason to pick any level: no level provides it (#4911); throttle at the provider or gateway |
361389
| Is it a simple point-to-point sync with an external system? | **Yes** → L3 (Connector) with `syncConfig` |
362390
| Are you building a data warehouse pipeline? | The extraction half is L3 (`syncConfig`); the warehouse-side transformation is the warehouse's own tooling. There is no ObjectStack pipeline protocol (#6414) |
363391
| Are you integrating with an enterprise system? | **Yes** → L3 (Connector) |

0 commit comments

Comments
 (0)