You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 18cc3b1
Browse filesBrowse the repository at this point in the historyBrowse 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>
— 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).
5268
5268
All five bulk routes now call one `enforceBatchSize` helper with the configured
5269
5269
value and answer with one envelope:
5270
5270
@@ -5300,9 +5300,10 @@ export`) are DERIVED from the primitives, never declared standalone. (This
5300
5300
**Behaviour changes.**
5301
5301
5302
5302
- 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.
5306
5307
- `.min(1)` is gone with `.max(200)`: an empty batch is a no-op returning
5307
5308
`total: 0`, which is what these routes already did, rather than a validation
5308
5309
error the schema claimed but nothing raised.
@@ -5312,6 +5313,8 @@ export`) are DERIVED from the primitives, never declared standalone. (This
5312
5313
type was looser.
5313
5314
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
5314
5315
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
+
5315
5318
- fccec22: fix(rest): bulk writes bind to the object in the path, not the one in the body (#3933)
5316
5319
5317
5320
`POST /data/:object/updateMany` spread the request body over the value it had
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
15241
15245
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
+
15242
15248
- fccec22: fix(rest): bulk writes bind to the object in the path, not the one in the body (#3933)
15243
15249
15244
15250
`POST /data/:object/updateMany` spread the request body over the value it had
— 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).
27477
27477
All five bulk routes now call one `enforceBatchSize` helper with the configured
27478
27478
value and answer with one envelope:
27479
27479
@@ -27509,9 +27509,10 @@ object:'task', function:'count', filter:{ status:'completed' } } }` lost that
27509
27509
**Behaviour changes.**
27510
27510
27511
27511
- 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.
27515
27516
- `.min(1)` is gone with `.max(200)`: an empty batch is a no-op returning
27516
27517
`total: 0`, which is what these routes already did, rather than a validation
27517
27518
error the schema claimed but nothing raised.
@@ -27521,6 +27522,8 @@ object:'task', function:'count', filter:{ status:'completed' } } }` lost that
27521
27522
type was looser.
27522
27523
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
27523
27524
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
+
27524
27527
- f2445c9: feat(spec,objectql,client,plugin-webhooks): predicate writes get an honest bulk event contract (#4639)
27525
27528
27526
27529
A `multi: true` update/delete reaches `IDataDriver.updateMany` / `deleteMany`,
@@ -69646,9 +69649,9 @@ schedule }`), not on the flow.
69646
69649
request, where before it was one statement that mostly failed anyway.
69647
69650
69648
69651
**The cap moved to the routes, and the schemas gave it up.** Batch size is
— 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).
69652
69655
All five bulk routes now call one `enforceBatchSize` helper with the configured
69653
69656
value and answer with one envelope:
69654
69657
@@ -69684,9 +69687,10 @@ schedule }`), not on the flow.
69684
69687
**Behaviour changes.**
69685
69688
69686
69689
- 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.
69690
69694
- `.min(1)` is gone with `.max(200)`: an empty batch is a no-op returning
69691
69695
`total: 0`, which is what these routes already did, rather than a validation
69692
69696
error the schema claimed but nothing raised.
@@ -69696,6 +69700,8 @@ schedule }`), not on the flow.
69696
69700
type was looser.
69697
69701
- New export: `UpdateManyRecordSchema` / `UpdateManyRecord`.
69698
69702
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.)*
0 commit comments