Skip to content

Commit 18cc3b1

Browse files
docs(changelog): correct the falsified batch-cap claim in the published 17.0.0 and 17.0.0-rc.1 entries (#18852)
Part of #18740 > ⚠️ **Changed from `Fixes` to `Part of` by the dispatching `domain:devx` seat.** Eight of the card's nine sites are corrected here. The ninth — `content/docs/releases/v17/17-0.mdx:1734` — is still a live carrier, and the delivering agent correctly declined it: its standing operating rules prohibit editing `content/docs/releases/**` unconditionally, and **a permission in AGENTS.md does not lift a prohibition**. A closing keyword here would silently close a card that still has an open half, so it is withdrawn. The ninth site is routed as its own card; this PR stays a clean two-file CHANGELOG amendment. A **dedicated docs-only PR**, which `AGENTS.md`'s Documentation Guardrails row for `packages/*/CHANGELOG.md` requires: a factual error in a released entry is amended *in that entry*, ⛔ never as an erratum in a later entry and ⛔ never as a rider on code changes — "the reader greps the tombstoned symbol and lands on the old entry, so a correction anywhere else is one it never reaches". The diff is exactly two files. No source, no schema, no export, no test, and **no changeset** (see below). ## What was false The 2026-09-07 ruling found that no reader of a published surface can configure `batch.maxBatchSize`. The cap is **embedder policy**: `RestServerConfig.batch.maxBatchSize` is the argument a host passes when it constructs the server, through the one door `createRestApiPlugin({ api })`. Neither shipped boot path passes it — `os serve` forwards exactly two keys out of the stack config's `api:` block (`api.enableProjectScoping`, `api.projectResolution`), and the dev plugin calls `createRestApiPlugin()` with no config at all. A CLI-started deployment therefore always gets the 200 default, and no flag, config file or CLI option moves it. The `789ad63` entry carries that falsified claim in **two wordings**, and it is duplicated under two published version headings, so there are **eight** carriers, not four. ## The eight sites corrected Located **by content, across lines** on this tree at `631dcbd4b` — ⛔ not by the line numbers carried on the card, and ⛔ not with a single-line match. The `Batch size is / deployment policy` sentence is **wrapped across two lines**: a single-line grep for it returns 0 and reads as a false absence. | file | heading | wording | |:--|:--|:--| | `packages/rest/CHANGELOG.md` | `## 17.0.0` (L4733) | `should raise` instruction + `deployment policy` | | `packages/rest/CHANGELOG.md` | `## 17.0.0-rc.1` (L14992) | both | | `packages/spec/CHANGELOG.md` | `## 17.0.0` (L15658) | both | | `packages/spec/CHANGELOG.md` | `## 17.0.0-rc.1` (L67924) | both | Per copy: - **The claim.** `Batch size is deployment policy` now reads `Batch size is embedder policy`, and the counterfactual beside it — `(a deployment raising the limit to 500 would still have been refused at 200)` — now says `a host`, since it presupposed the same unreachable knob. - **The instruction.** The behaviour bullet read `Deployments that were quietly relying on unbounded batches should raise` `batch.maxBatchSize` `(up to 1000) rather than discover the cap in production`. That told an operator to perform an action no shipped boot path can perform, so a reader who complied had no way to tell whether they had succeeded. It now states where the cap actually comes from and issues no instruction. ## Where this landed between "faithful to the record" and "no longer misleading" This is a CHANGELOG, so the job is to record what happened in that version — ⛔ not to rewrite history into "this is what we said at the time". I did not invent a shape for that: this repository has already settled it, in #18569 / #17849, and I copied it. **The published words are corrected in place, and the old words are kept as a marked quotation in a dated erratum line closing the entry** — the in-repo tail already used at `packages/spec/CHANGELOG.md` (three sites), `packages/lint/CHANGELOG.md` and `packages/metadata-protocol/CHANGELOG.md`. So the entry no longer instructs, and what shipped is still readable verbatim. The factual vocabulary is likewise copied, ⛔ not invented — from `ec5db7b` (`packages/rest/CHANGELOG.md:351`) and the pending `.changeset/18739-batch-cap-embedder-only.md`, which are the fourth and fifth landings of this same correction. ⛔ No new entry at the top, ⛔ no version heading added, ⛔ nothing this release published is changed: the 1..1000 range, the 200 default and the enforcement are all untouched. ## ⛔ Deliberately no changeset A changeset would compile this correction into a **new** release note — which is precisely the erratum-in-a-later-entry shape `AGENTS.md` forbids. Nothing published moves here either: the diff is prose inside already-shipped entries. ## ⚠️ The ninth site is NOT in this PR — a standing-rule conflict I am not resolving silently `content/docs/releases/v17/17-0.mdx:1734` carries the same claim (`stay under` `batch.maxBatchSize` `(default 200, raisable to 1000) or chunk`) and the dispatch listed it as the ninth site. I did not touch it. My standing operating rules carry an **unconditional** prohibition on editing `content/docs/releases/`, and they state that such a clause wins over the dispatch word. `AGENTS.md` *permits* a docs-only PR there; it does not *require* one — a permission does not override the prohibition, so there is no conflict with `AGENTS.md`, only with the dispatch. Flagging rather than choosing a side: that line is **still a live carrier** and needs either a separate actor or an explicit release of the prohibition. ## ⚠️ Report item, ⛔ not fixed here `packages/spec/CHANGELOG.md:3581` says the phrase "exists verbatim in the REST server ... at `packages/rest/src/rest-server.ts:2071` ... it is owed to a follow-up in `packages/rest`". Re-measured on `631dcbd4b`: `grep -c "deployment policy" packages/rest/src/rest-server.ts` = **0**, and `packages/rest/CHANGELOG.md:351` records `ec5db7b` retiring exactly that phrase. **That follow-up is done and the note is now stale** — a debt recorded as outstanding that has been paid. It is a different error from the one this card names, so it is reported, ⛔ not ridden. `#18740` does not cover it. ## Firing controls Computed from `git diff -U0` hunk headers so that context lines cannot contaminate the reading, and taken from the probed files themselves. - **C1** — `should raise` + `batch.maxBatchSize`: **0 outside the diff**. Its only four hits are the verbatim quotations inside the new erratum lines. - **C2** — the batch-cap `deployment policy` claim, multiline-aware: 4 hits outside the diff, each classified and none a live carrier — `packages/rest/CHANGELOG.md:351` (records the phrase's retirement), `packages/spec/CHANGELOG.md:3581` (the stale note above), `.changeset/18739-batch-cap-embedder-only.md` (the sibling correction), `docs/qa/platform-checklist/FOLLOW-UPS.md:575` (states the correct embedder-only fact). - **C3** — the wrapped `Batch size is` / `deployment policy` sentence: **0 hits anywhere in the tree**. - Control bytes: `grep -naP` over both changed files exits 1 (no match). A bare `deployment policy` string is ⛔ not a usable control — it matches unrelated scheduling prose in about 30 files. --- _Generated by [Claude Code](https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk)_ --- _Generated by [Claude Code](https://claude.ai/code)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 62b114f commit 18cc3b1

2 files changed

Lines changed: 32 additions & 20 deletions

File tree

‎packages/rest/CHANGELOG.md‎

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5262,9 +5262,9 @@ export`) are DERIVED from the primitives, never declared standalone. (This
52625262
request, where before it was one statement that mostly failed anyway.
52635263

52645264
**The cap moved to the routes, and the schemas gave it up.** Batch size is
5265-
deployment policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
5265+
embedder policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
52665266
— so a hardcoded bound in the spec could only ever be a second, wrong answer
5267-
(a deployment raising the limit to 500 would still have been refused at 200).
5267+
(a host raising the limit to 500 would still have been refused at 200).
52685268
All five bulk routes now call one `enforceBatchSize` helper with the configured
52695269
value and answer with one envelope:
52705270

@@ -5300,9 +5300,10 @@ export`) are DERIVED from the primitives, never declared standalone. (This
53005300
**Behaviour changes.**
53015301

53025302
- A bulk request over the configured cap is `400 BATCH_TOO_LARGE` instead of
5303-
being executed. Deployments that were quietly relying on unbounded batches
5304-
should raise `batch.maxBatchSize` (up to 1000) rather than discover the cap in
5305-
production.
5303+
being executed. A deployment that was quietly relying on unbounded batches
5304+
meets the cap at whatever value the host embedding the server passed for
5305+
`batch.maxBatchSize` — 200 unless it passed one, which no shipped boot path
5306+
does.
53065307
- `.min(1)` is gone with `.max(200)`: an empty batch is a no-op returning
53075308
`total: 0`, which is what these routes already did, rather than a validation
53085309
error the schema claimed but nothing raised.
@@ -5312,6 +5313,8 @@ export`) are DERIVED from the primitives, never declared standalone. (This
53125313
type was looser.
53135314
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
53145315

5316+
*Erratum, 2026-09-18 — this entry called the batch cap "deployment policy" and told operators that deployments relying on unbounded batches "should raise `batch.maxBatchSize` (up to 1000)". The cap is embedder policy: `RestServerConfig.batch.maxBatchSize` is the argument a host passes when it constructs the server, and neither shipped boot path passes it — `os serve` forwards exactly two keys out of the stack config's `api:` block (`api.enableProjectScoping`, `api.projectResolution`) and the dev plugin calls `createRestApiPlugin()` with no config at all — so a CLI-started deployment always gets the 200 default and no flag, config file or CLI option moves it. Two passages above are corrected in place; the 1..1000 range, the 200 default and the enforcement this release shipped are unchanged. (Corrected after publication, #18740.)*
5317+
53155318
- fccec22: fix(rest): bulk writes bind to the object in the path, not the one in the body (#3933)
53165319

53175320
`POST /data/:object/updateMany` spread the request body over the value it had
@@ -15189,9 +15192,9 @@ IEmailService`, `ExternalDatasourceService implements IExternalDatasourceService
1518915192
request, where before it was one statement that mostly failed anyway.
1519015193

1519115194
**The cap moved to the routes, and the schemas gave it up.** Batch size is
15192-
deployment policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
15195+
embedder policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
1519315196
— so a hardcoded bound in the spec could only ever be a second, wrong answer
15194-
(a deployment raising the limit to 500 would still have been refused at 200).
15197+
(a host raising the limit to 500 would still have been refused at 200).
1519515198
All five bulk routes now call one `enforceBatchSize` helper with the configured
1519615199
value and answer with one envelope:
1519715200

@@ -15227,9 +15230,10 @@ IEmailService`, `ExternalDatasourceService implements IExternalDatasourceService
1522715230
**Behaviour changes.**
1522815231

1522915232
- A bulk request over the configured cap is `400 BATCH_TOO_LARGE` instead of
15230-
being executed. Deployments that were quietly relying on unbounded batches
15231-
should raise `batch.maxBatchSize` (up to 1000) rather than discover the cap in
15232-
production.
15233+
being executed. A deployment that was quietly relying on unbounded batches
15234+
meets the cap at whatever value the host embedding the server passed for
15235+
`batch.maxBatchSize` — 200 unless it passed one, which no shipped boot path
15236+
does.
1523315237
- `.min(1)` is gone with `.max(200)`: an empty batch is a no-op returning
1523415238
`total: 0`, which is what these routes already did, rather than a validation
1523515239
error the schema claimed but nothing raised.
@@ -15239,6 +15243,8 @@ IEmailService`, `ExternalDatasourceService implements IExternalDatasourceService
1523915243
type was looser.
1524015244
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
1524115245

15246+
*Erratum, 2026-09-18 — this entry called the batch cap "deployment policy" and told operators that deployments relying on unbounded batches "should raise `batch.maxBatchSize` (up to 1000)". The cap is embedder policy: `RestServerConfig.batch.maxBatchSize` is the argument a host passes when it constructs the server, and neither shipped boot path passes it — `os serve` forwards exactly two keys out of the stack config's `api:` block (`api.enableProjectScoping`, `api.projectResolution`) and the dev plugin calls `createRestApiPlugin()` with no config at all — so a CLI-started deployment always gets the 200 default and no flag, config file or CLI option moves it. Two passages above are corrected in place; the 1..1000 range, the 200 default and the enforcement this release shipped are unchanged. (Corrected after publication, #18740.)*
15247+
1524215248
- fccec22: fix(rest): bulk writes bind to the object in the path, not the one in the body (#3933)
1524315249

1524415250
`POST /data/:object/updateMany` spread the request body over the value it had

‎packages/spec/CHANGELOG.md‎

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27471,9 +27471,9 @@ object:'task', function:'count', filter:{ status:'completed' } } }` lost that
2747127471
request, where before it was one statement that mostly failed anyway.
2747227472

2747327473
**The cap moved to the routes, and the schemas gave it up.** Batch size is
27474-
deployment policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
27474+
embedder policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
2747527475
— so a hardcoded bound in the spec could only ever be a second, wrong answer
27476-
(a deployment raising the limit to 500 would still have been refused at 200).
27476+
(a host raising the limit to 500 would still have been refused at 200).
2747727477
All five bulk routes now call one `enforceBatchSize` helper with the configured
2747827478
value and answer with one envelope:
2747927479

@@ -27509,9 +27509,10 @@ object:'task', function:'count', filter:{ status:'completed' } } }` lost that
2750927509
**Behaviour changes.**
2751027510

2751127511
- A bulk request over the configured cap is `400 BATCH_TOO_LARGE` instead of
27512-
being executed. Deployments that were quietly relying on unbounded batches
27513-
should raise `batch.maxBatchSize` (up to 1000) rather than discover the cap in
27514-
production.
27512+
being executed. A deployment that was quietly relying on unbounded batches
27513+
meets the cap at whatever value the host embedding the server passed for
27514+
`batch.maxBatchSize` — 200 unless it passed one, which no shipped boot path
27515+
does.
2751527516
- `.min(1)` is gone with `.max(200)`: an empty batch is a no-op returning
2751627517
`total: 0`, which is what these routes already did, rather than a validation
2751727518
error the schema claimed but nothing raised.
@@ -27521,6 +27522,8 @@ object:'task', function:'count', filter:{ status:'completed' } } }` lost that
2752127522
type was looser.
2752227523
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
2752327524

27525+
*Erratum, 2026-09-18 — this entry called the batch cap "deployment policy" and told operators that deployments relying on unbounded batches "should raise `batch.maxBatchSize` (up to 1000)". The cap is embedder policy: `RestServerConfig.batch.maxBatchSize` is the argument a host passes when it constructs the server, and neither shipped boot path passes it — `os serve` forwards exactly two keys out of the stack config's `api:` block (`api.enableProjectScoping`, `api.projectResolution`) and the dev plugin calls `createRestApiPlugin()` with no config at all — so a CLI-started deployment always gets the 200 default and no flag, config file or CLI option moves it. Two passages above are corrected in place; the 1..1000 range, the 200 default and the enforcement this release shipped are unchanged. (Corrected after publication, #18740.)*
27526+
2752427527
- f2445c9: feat(spec,objectql,client,plugin-webhooks): predicate writes get an honest bulk event contract (#4639)
2752527528

2752627529
A `multi: true` update/delete reaches `IDataDriver.updateMany` / `deleteMany`,
@@ -69646,9 +69649,9 @@ schedule }`), not on the flow.
6964669649
request, where before it was one statement that mostly failed anyway.
6964769650

6964869651
**The cap moved to the routes, and the schemas gave it up.** Batch size is
69649-
deployment policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
69652+
embedder policy — `RestServerConfig.batch.maxBatchSize`, 1..1000, default 200
6965069653
— so a hardcoded bound in the spec could only ever be a second, wrong answer
69651-
(a deployment raising the limit to 500 would still have been refused at 200).
69654+
(a host raising the limit to 500 would still have been refused at 200).
6965269655
All five bulk routes now call one `enforceBatchSize` helper with the configured
6965369656
value and answer with one envelope:
6965469657

@@ -69684,9 +69687,10 @@ schedule }`), not on the flow.
6968469687
**Behaviour changes.**
6968569688

6968669689
- A bulk request over the configured cap is `400 BATCH_TOO_LARGE` instead of
69687-
being executed. Deployments that were quietly relying on unbounded batches
69688-
should raise `batch.maxBatchSize` (up to 1000) rather than discover the cap in
69689-
production.
69690+
being executed. A deployment that was quietly relying on unbounded batches
69691+
meets the cap at whatever value the host embedding the server passed for
69692+
`batch.maxBatchSize` — 200 unless it passed one, which no shipped boot path
69693+
does.
6969069694
- `.min(1)` is gone with `.max(200)`: an empty batch is a no-op returning
6969169695
`total: 0`, which is what these routes already did, rather than a validation
6969269696
error the schema claimed but nothing raised.
@@ -69696,6 +69700,8 @@ schedule }`), not on the flow.
6969669700
type was looser.
6969769701
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
6969869702

69703+
*Erratum, 2026-09-18 — this entry called the batch cap "deployment policy" and told operators that deployments relying on unbounded batches "should raise `batch.maxBatchSize` (up to 1000)". The cap is embedder policy: `RestServerConfig.batch.maxBatchSize` is the argument a host passes when it constructs the server, and neither shipped boot path passes it — `os serve` forwards exactly two keys out of the stack config's `api:` block (`api.enableProjectScoping`, `api.projectResolution`) and the dev plugin calls `createRestApiPlugin()` with no config at all — so a CLI-started deployment always gets the 200 default and no flag, config file or CLI option moves it. Two passages above are corrected in place; the 1..1000 range, the 200 default and the enforcement this release shipped are unchanged. (Corrected after publication, #18740.)*
69704+
6969969705
- 2af1988: fix(formula,spec,core): the RLS write-side `check` evaluator honours calendar-day upper bounds (ADR-0053 D-D)
6970069706

6970169707
`@objectstack/formula`'s `matchesFilterCondition` — the evaluator behind RLS

0 commit comments

Comments
 (0)