Skip to content

Commit 89c6ec5

Browse files
os-billclaude
andauthored
docs(spec): the batch cap config is embedder-only, not a deployment's — the sixth carrier (#18951)
Fixes #18763 Clause-②: no One comment changes. `packages/spec/src/api/batch.test.ts` told a reader that the one route that did cap a batch "read the deployment's configured `batch.maxBatchSize`". The claim that a *deployment* can configure that key was ruled false on 2026-09-07 (director seat, summon #17, decision batch #2, maintainer verbatim 「同意」): the key is **embedder-only**. Five carriers have been corrected under that ruling (#15543 · #16801 · #16940 · #17183 · #18739 / PR #18757); this is the sixth. No test body, no assertion, no schema key, no export moves. The diff is comment text above one `it(...)`, plus a merge of `main`. ## Why five sweeps read zero on this file The sentence **wraps across two comment lines** — `the deployment's` ends `:110`, `configured` begins `:111` — and every prior probe matched line by line. Measured here on the base commit `02bdeaaf23`, same tree, same phrase: | probe | hits | |---|---| | `git grep -c "the deployment's configured"`, whole tree | 3 files — and `batch.test.ts` is **not** one of them | | same phrase, fold-proof (strip comment leaders, collapse all whitespace incl. newlines to one space) | **1** — `packages/spec/src/api/batch.test.ts` | The wrap is the entire difference between the two readings. That is this card's durable half: **a line-scoped probe is blind to a wrapped claim exactly as a directory-scoped probe is blind to what sits outside the directory**, and it reports the shortfall as a clean zero. ## The two sentences, side by side Before (`:108-112`): > `[#3939]` The count bounds moved OUT of the schema. They were a second source of truth that never matched reality: the schema said 1..200 while the routes enforced nothing, and the one route that did cap read **the deployment's configured** `batch.maxBatchSize` (1..1000) instead. The cap is now enforced at the route from that config, and the schema carries shape only. After: > `[#3939]` The count bounds moved OUT of the schema. They were a second source of truth that never matched reality: the schema said 1..200 while the routes enforced nothing, and the one route that did cap read **the constructed** `RestServerConfig.batch.maxBatchSize` **(1..1000, default 200)** instead. The cap is now enforced at the route from that config, and the schema carries shape only. > > **Reachability: EMBEDDER-ONLY (#15543, #16801).** That config is NOT deployment policy: it is written only by a host that constructs the `RestServerConfig` itself, never by `os serve` or the dev plugin, so a CLI-started deployment always gets the default of 200 and no flag, config file or CLI option moves it. Same posture as the schema this file pins (`BatchUpdateRequestSchema` in `batch.zod.ts`) and `RestServer#enforceBatchSize`; the per-key record is the REACHABILITY row in `packages/spec/liveness/batch_endpoints.json`. Every fact the old paragraph carried survives: the bounds left the schema, why they left (a second source of truth that never matched), where today's cap comes from, and that the schema carries shape only. What changed is the attribution of the config — plus one paragraph stating the reachability outright, so the next reader does not have to re-derive it. **The wording is copied, not invented**: it follows `RestServer#enforceBatchSize` and the `BatchUpdateRequestSchema` paragraph sentence for sentence, which is what #18739 asked of whoever took the fifth carrier. Verified against `origin/main` rather than taken from the card: the route reads `const maxBatch = batch.maxBatchSize ?? 200` (`packages/rest/src/rest-server.ts:13358`) out of the constructed config; the schema is `z.number().int().min(1).max(1000).default(200)` (`rest-server.zod.ts:516`); and `BatchUpdateRequestSchema.records` carries no `.max()`. ## `batch.zod.ts` is NOT a seventh carrier — the question the dispatch asked, answered The dispatch flagged that the positive control's hit, `packages/spec/src/api/batch.zod.ts:128-133`, says the cap *is* `RestServerConfig.batch.maxBatchSize` — and that file **ships** (`src/**/*.zod.ts` is in `packages/spec`'s `files[]`, `.test.ts` is not). It asked for (a) a seventh, published carrier, or (b) still true today. **(b), and it is not close.** Those six lines are the **first half of the paragraph PR #18757 landed to correct the fifth carrier**. The paragraph runs `:128-144`; reading it whole is what settles it: ``` // [#3939] No `.max()` here: the batch-size cap is // `RestServerConfig.batch.maxBatchSize` (1..1000, default 200), enforced at // the route so one place decides it. … // // Reachability: EMBEDDER-ONLY (#15543, #16801). ⛔ The cap is NOT DEPLOYMENT // policy — this comment said exactly that until now, and no shipped boot path // makes it true. It is written only by a host that constructs the // `RestServerConfig` itself, never by `os serve` or the dev plugin, … ``` Two reasons, either sufficient: 1. **It is not the ruled-false claim.** The ruling falsified *who may write the key* — an operator deploying the platform — never *which key the route reads*. "The cap is `RestServerConfig.batch.maxBatchSize`, enforced at the route" is a true statement about the runtime, and it is the same statement the four landed carriers make. 2. **The very next sentence states the reachability**, in the ruling's own vocabulary, and names the two records that hold it. A reader cannot leave that comment believing a deployment can move the cap. The six-line window reads ambiguous only because it stops one sentence early. ⛔ The file is untouched by this PR, and it needs no card. ## Acceptance All readings re-taken on this branch, ⛔ none inherited. Population and legs at head `45c81f390b`, over `git ls-files` tracked text files excluding `CHANGELOG.md`, with comment leaders stripped and all whitespace (newlines included) collapsed to one space: ``` scanned 8808 tracked text file(s) [7 binary/undecodable, 80 CHANGELOG.md skipped] 0 SUBJECT "the deployment's configured `batch.maxBatchSize`" 1 LIT "the batch-size cap is" :: packages/spec/src/api/batch.zod.ts 0 DARK "the batch-size cap is DEPLOYMENT policy" ``` ⭐ SUBJECT and LIT are from **one run**: the 0 is a reading, not a dumb instrument. The same three legs read `1 / 1 / 0` on the base commit `02bdeaaf23` before the edit — so the SUBJECT leg moved, and the other two did not. The 8808 was re-measured here (the card says 8757: the tree grew, not a conflict). | check | result | |---|---| | `pnpm --filter @objectstack/spec exec vitest run src/api/batch.test.ts` | 29/29 pass | | `pnpm --filter @objectstack/spec test` | **488 files / 14182 tests pass**, exit 0 | | `pnpm --filter @objectstack/spec typecheck` | exit 0 — the test layer compiles under `tsconfig.test.json` | | `pnpm exec eslint . --no-inline-config --format json` | **6855 files** (eslint's own selection), 0 errors, 0 warnings, exit 0 — the whole repo union, not a narrowing | | `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` | 76 families derived, all 76 run, exit codes landed to disk first and reconciled with `--ran` | Of those 76: **73 exit 0**. The other three exit **3**, the code these gates use for *PREREQUISITE NOT MET — nothing was measured*: `check:dual-build-cjs-loads`, `check:lean-entry-closure` and `check:type-check-debt` each need the **whole monorepo built** on disk first — 87 unbuilt packages named by the first of them, 30 by the third — which CI does before the step and which this shared container OOM-killed once already (exit 137, kernel OOM on the spec DTS pass). ⛔ Not reds, and not passes — NOT MEASURED, and CI builds the closure before each of them. `skip-changeset`: nothing published moves. `packages/spec`'s `files[]` is `dist`, `json-schema`, `liveness`, `prompts`, `llms.txt`, `README.md`, `src/**/*.zod.ts`, `CHANGELOG.md`, `api-surface`, `spec-changes.json` — no test glob, so `src/api/batch.test.ts` is not in the tarball. `check:published-files` and `check:api-surface` both ran green. ## Acceptance notes - **#18740** (open, `domain:devx`) carries the same falsified claim in the **17.0.0 CHANGELOG entries** of `packages/rest` / `packages/spec`, in its strongest form. Untouched here: CHANGELOG is release-owned and is never amended from a code PR. Its card says the two probably want the same taker; ⛔ merging the cards is the maintainer's call, not this PR's. - Nothing else in `batch.test.ts` carries the claim. The two sibling titles — `does not cap the record count — that is the route's job (batch.maxBatchSize)` (`:122`, `:356`) — state where the cap lives and assert no reachability, so they are correct as they stand and are untouched. --- _Generated by [Claude Code](https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent e19ae67 commit 89c6ec5

1 file changed

Lines changed: 13 additions & 3 deletions

File tree

‎packages/spec/src/api/batch.test.ts‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,19 @@ describe('BatchUpdateRequestSchema', () => {
107107

108108
// [#3939] The count bounds moved OUT of the schema. They were a second source
109109
// of truth that never matched reality: the schema said 1..200 while the routes
110-
// enforced nothing, and the one route that did cap read the deployment's
111-
// configured `batch.maxBatchSize` (1..1000) instead. The cap is now enforced
112-
// at the route from that config, and the schema carries shape only.
110+
// enforced nothing, and the one route that did cap read the constructed
111+
// `RestServerConfig.batch.maxBatchSize` (1..1000, default 200) instead. The
112+
// cap is now enforced at the route from that config, and the schema carries
113+
// shape only.
114+
//
115+
// Reachability: EMBEDDER-ONLY (#15543, #16801). ⛔ That config is NOT
116+
// deployment policy: it is written only by a host that constructs the
117+
// `RestServerConfig` itself, never by `os serve` or the dev plugin, so a
118+
// CLI-started deployment always gets the default of 200 and no flag, config
119+
// file or CLI option moves it. Same posture as the schema this file pins
120+
// (`BatchUpdateRequestSchema` in `batch.zod.ts`) and
121+
// `RestServer#enforceBatchSize`; the per-key record is the REACHABILITY row
122+
// in `packages/spec/liveness/batch_endpoints.json`.
113123
it('accepts an empty record list — an empty batch is a no-op, not a client error', () => {
114124
expect(() =>
115125
BatchUpdateRequestSchema.parse({

0 commit comments

Comments
 (0)