Repository navigation
Commit b146102
docs(spec): the connector header no longer teaches retryConfig as the rate-limit remedy (#19040)
Fixes #18983
Clause-②: no
## What moves
One sentence of the connector header TSDoc in
`packages/spec/src/integration/connector.zod.ts`, plus the reference
page `gen:docs` renders from it. **Prose only.** No schema, declaration,
default or accept set moves, and the fate of these keys stays ADR-0049's
to rule on rather than being prejudged here.
The header ended its "no outbound rate limiting" paragraph by naming a
remedy: *"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`."* PR
#18979 retired that same claim from
`packages/spec/docs/SYNC_ARCHITECTURE.md`; this file is where it was
authored, and the generated page carried it downstream.
The replacement carries the wording #18979 landed: both keys are
**declared but currently unimplemented**, with a pointer to the liveness
ledger, and explicitly neither *retired* nor *left to the host*.
## Why the sentence was false — re-measured on this branch, not
inherited
`packages/spec/liveness/connector.json`, read at `ed63e0d39c`:
| ledger rows | status | verifiedAt |
|:---|:---|:---|
| `retryConfig.*` — all 8 sub-keys | `dead` | 2026-09-17 |
| `health.circuitBreaker.*` — all 7 rows | `dead` | 2026-09-17 |
| `health.healthCheck.*` — all 8 rows | `dead` | 2026-09-17 |
| **`providerConfig` — the must-answer live control, same read** |
**`live`** | 2026-09-17 |
A `dead` column with no live row beside it would only show the
instrument answering one way, so the control is part of the reading.
The "not left to the host" half is re-verified here too, at source
rather than cited: `ConnectorProviderContext`
(`packages/spec/src/integration/connector-provider.ts:57`) declares
exactly `name`, `label`, `description`, `icon`, `type`,
`providerConfig`, `auth` and `loadPackageFile` — eight members, none of
them `retryConfig` or `health`. A provider factory is never handed
either key, so it has no way to honour one.
## Regeneration leg
`pnpm --filter @objectstack/spec gen:docs` moved exactly one tracked
file, `content/docs/references/integration/connector.mdx` (sha256
`640ea9d5…` to `ef0d11fc…`), and `check:docs` is green on the merged
tree. The page is not hand-edited.
One prediction on the card did not hold, reported as measured: the
page's `retryableStatusCodes` occurrence count stays **4**, not lower.
One of the four is inside the historical sentence this change quotes;
the other three are the generated field tables for `RetryConfigSchema`,
which this change does not touch.
## Zero-hit reading, with its radius
The corrected sentence spans three comment lines, so a per-line `grep`
reads `0` for it while it is plainly there — that reading is blind, not
clean. The sweep here strips comment prefixes and collapses
newline-bearing whitespace before matching.
- **Claim.** The assertive adjacency `upstream gateway.** What L3 does
declare` occurs **0** times in the tree at `ed63e0d39c` (10,270 files
scanned).
- **Radius.** Content layer, over the working tree only; extensions `.ts
.tsx .mts .mjs .js .md .mdx .json`; `node_modules`, `dist`, `.git`,
`.turbo` and `.cache` pruned.
- **A known target that must be outside it.** The blob at `96cf32b075`
still holds that exact string. Extracted to a file *inside* the radius
the same instrument reads it (2 hits), so the probe is live; scanning
the tree it reads 0, because git objects are outside the radius by
construction.
## Published-surface reading — per file, which is why this is not
`skip-changeset`
| file in this diff | on a published `files[]`? | how measured |
|:---|:---|:---|
| `packages/spec/src/integration/connector.zod.ts` | **yes** |
`@objectstack/spec` ships `src/**/*.zod.ts`; `npm pack --dry-run` lists
the path among the tarball's 2,039 files |
| `content/docs/references/integration/connector.mdx` | no | 0 of the 70
published workspace packages can reach `content/docs/**`; same
instrument does see `@objectstack/spec`'s `src/**` entry, so it is not
blind |
| `.changeset/18983-connector-header-rate-limit-remedy.md` | no |
changeset input, consumed at release |
The edited file is itself shipped, so the corrected text reaches
consumers: this takes a **`patch`** changeset, not `skip-changeset`. The
header TSDoc does not reach `dist/`, so `src/**/*.zod.ts` is its only
published carrier.
## Verification
All of the below ran at `ed63e0d39c`, after `origin/main` was merged in
(`packages/spec` had moved on main, so §10's rebuild-and-recheck
applies).
- **Gates.** `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived **100** commands from a non-stale
tree. Each ran with its exit code written to disk before any pipe, then
reconciled with `--ran`: **100 derived, 99 run green, 0 findings, 1 NOT
MEASURED, 0 unrun.**
- **NOT MEASURED (1).** `pnpm check:dual-build-cjs-loads` exits **3** —
`PREREQUISITE NOT MET`, its own distinct code for "nothing was
measured". It reads built output for 26 packages still without a `dist/`
(apps, connectors), which needs a whole-workspace build; CI's required
`Lint & Repo Gates` job builds everything and runs it. Five other gates
refused the same way on first pass and were cleared by building the
closures they named, then re-run green: `check:doc-formula-expressions`,
`check:doc-security-posture`, `check:skill-examples`,
`check:docs-transcript-drift`, `check:lean-entry-closure`.
- **Tests.** `pnpm --filter @objectstack/spec test` — **489 files,
14,229 tests passed**.
- **Typecheck.** `pnpm --filter @objectstack/spec typecheck` green: `tsc
--noEmit`, `check:scripts-typecheck`, and `check:test-typecheck` (54
files / 259 errors / 144 pinned signatures held in the shrink-only
ledger, unchanged).
- **`check:generated`** — all 16 generated artifacts up to date,
`check:docs` among them.
- **Lint, full population, no narrowing.** `eslint . --no-inline-config`
over the whole repo: **6,861 files, 0 errors, 0 warnings**, exit 0. The
config enables no type-aware linting for any file (its own comment at
`eslint.config.mjs:326` records this with a positive control), so this
run is per-file parsing throughout.
## Acceptance notes — measured, deliberately not changed here
- The per-field `.describe()` strings on the same dead keys still read
as present-indicative behaviour: `'HTTP status codes to retry'`,
`'Enable circuit breaker'`, `'Failures before opening circuit'`, `'Add
jitter to retry delays'`, and about twenty more across
`RetryConfigSchema`, `HealthCheckConfigSchema` and
`CircuitBreakerConfigSchema`. They render into this same generated page
three times over and into the authorable-surface artifacts an authoring
agent reads. Correcting them edits the declaration surface and moves
`gen:schema` output, which is outside this card.
- The triage seat's escalation condition — a **third** prose source
still teaching this remedy — did **not** trigger. Sweeping the tree with
the fold-free instrument for `retryConfig` paired with `429` or with
`circuitBreaker` returns only: this file, its generated page, the
already-corrected `SYNC_ARCHITECTURE.md` passages, the liveness ledger's
own notes, a schema parse test, a generated defaults artifact, and an
ADR naming-convention list. No third source asserts the remedy.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 5ba2ec3 commit b146102
3 files changed
Lines changed: 74 additions & 6 deletions
File tree
- .changeset
- content/docs/references/integration
- packages/spec/src/integration
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
41 | | - | |
42 | | - | |
43 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
44 | 60 | | |
45 | 61 | | |
46 | 62 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
41 | 41 | | |
42 | 42 | | |
43 | 43 | | |
44 | | - | |
45 | | - | |
46 | | - | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
47 | 63 | | |
48 | 64 | | |
49 | 65 | | |
| |||
0 commit comments