Skip to content

Commit eae824e

Browse files
os-trumpclaude
andauthored
docs(spec): anchor the BatchOptions.validateOnly tombstone to the release that removed it (#13127)
The tombstone read "... was removed from BatchOptions in @objectstack/spec." — a removal citing nothing durable. Of the 132 audited tombstone prescriptions it was the only one left with no reference at all: no ADR id, no `os migrate` command, and — uniquely — no version anchor either. `retiredKey`'s own contract asks for one ("State what replaced the key, the version that removed it, and the one-line fix"), and 128 siblings carry it. The version is READ, never recalled. Three independent sources agree on 17.0.0: * packages/spec/CHANGELOG.md — "ec796d5: feat(spec)!: retire `BatchOptions.validateOnly` ..." sits under the `## 17.0.0` Major Changes heading. The nearest-heading method was validated first against two positive controls in the same population (`global_nav` from `ACTION_LOCATIONS`; `IDataDriver.findStream`), both of which resolve to 17.0.0 and match the anchors already written in their own tombstones. * git log --follow -- packages/spec/src/api/batch.zod.ts — commit ec796d5; the earliest GA tag containing it is @objectstack/spec@17.0.0, and no pre-17 spec tag carries it. * packages/spec/spec-changes.json — batch-options-validate-only-retired, toMajor: 17. Anchor spelling byte-matches the sibling convention in the same api/ family (analytics.zod.ts: "`query` was removed from AnalyticsQueryRequest in @objectstack/spec 17.0.0."). Guidance text only: the key stays retired, stays typed `never`, and is still rejected with the same prescription. The generated API reference pages under content/docs/references/ carry the prescription verbatim and were regenerated by tooling (`gen:docs`), moving exactly the 7 lines that spell it. Claude-Session: https://claude.ai/code/session_01LpRNHxWZgSUgVnFT9mQQo4 Co-authored-by: Claude <noreply@anthropic.com>
1 parent 901355c commit eae824e

4 files changed

Lines changed: 45 additions & 8 deletions

File tree

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
---
2+
"@objectstack/spec": patch
3+
---
4+
5+
docs(spec): anchor the `BatchOptions.validateOnly` tombstone to the release that removed it (#13020)
6+
7+
Published guidance text only — no accept-set movement. `options.validateOnly`
8+
is still retired, still typed `never`, and still rejected with the same
9+
prescription; the prescription now cites **which release removed it**.
10+
11+
The tombstone read `… was removed from BatchOptions in @objectstack/spec.`
12+
a removal with no durable citation. Of the 132 audited tombstone prescriptions
13+
it was the only one left without any: no ADR id, no `os migrate` command, and —
14+
uniquely — no version anchor either. `retiredKey`'s own contract asks for one
15+
("State what replaced the key, **the version that removed it**, and the
16+
one-line fix"), and 128 siblings carry it.
17+
18+
The version is READ, never recalled — three independent sources agree on
19+
**17.0.0**:
20+
21+
| source | reading |
22+
|---|---|
23+
| `packages/spec/CHANGELOG.md` | `ec796d5: feat(spec)!: retire \`BatchOptions.validateOnly\`` under the `## 17.0.0` Major Changes heading |
24+
| `git log --follow -- packages/spec/src/api/batch.zod.ts` | commit `ec796d5fd`; earliest GA tag containing it is `@objectstack/spec@17.0.0` (no pre-17 spec tag carries it) |
25+
| `packages/spec/spec-changes.json` | `batch-options-validate-only-retired``toMajor: 17` |
26+
27+
The nearest-heading method that produced the changelog reading was run against
28+
two positive controls in the same population first (`global_nav` from
29+
`ACTION_LOCATIONS`, `IDataDriver.findStream`) — both resolve to `17.0.0`, and
30+
both match the version anchor already written in their own source tombstones.
31+
32+
Anchor spelling byte-matches the sibling convention in the same `api/` family
33+
(`analytics.zod.ts`: `` `query` was removed from AnalyticsQueryRequest in
34+
@objectstack/spec 17.0.0. ``).
35+
36+
The generated API reference pages under `content/docs/references/` carry the
37+
prescription verbatim and are regenerated by tooling, not by hand.

content/docs/references/api/batch.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const result = BatchConfigSchema.parse(data);
5151
| **atomic** | `boolean` | optional (default: `false`) | Opt-in all-or-nothing. When explicitly true the whole batch runs inside ONE engine transaction: the first failure rolls back every prior write, and the response reports zero successes — each row carries `errors[0].code` ROLLED_BACK (written, then undone), the causal row its own error, and rows never reached NOT_ATTEMPTED. A runtime that cannot roll back REFUSES the request (501 NOT_IMPLEMENTED) rather than silently degrading to best-effort — probe `capabilities.transactionalBatch` on /discovery first. Takes precedence over continueOnError. Default false: sequential best-effort. |
5252
| **returnRecords** | `boolean` | optional (default: `false`) | If true, return full record data in response |
5353
| **continueOnError** | `boolean` | optional (default: `false`) | If true (and atomic=false), continue processing remaining records after errors. Default false: the first failure ENDS the run — records before it stay written (nothing is rolled back on this arm), and every record after it is reported `errors[0].code` NOT_ATTEMPTED rather than omitted, so `results` always covers all `total` records and `succeeded + failed === total`. |
54-
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
54+
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
5555

5656

5757
---
@@ -116,7 +116,7 @@ A write-path strip event: caller-supplied fields legally dropped from the payloa
116116
| **atomic** | `boolean` | optional (default: `false`) | Opt-in all-or-nothing. When explicitly true the whole batch runs inside ONE engine transaction: the first failure rolls back every prior write, and the response reports zero successes — each row carries `errors[0].code` ROLLED_BACK (written, then undone), the causal row its own error, and rows never reached NOT_ATTEMPTED. A runtime that cannot roll back REFUSES the request (501 NOT_IMPLEMENTED) rather than silently degrading to best-effort — probe `capabilities.transactionalBatch` on /discovery first. Takes precedence over continueOnError. Default false: sequential best-effort. |
117117
| **returnRecords** | `boolean` | optional (default: `false`) | If true, return full record data in response |
118118
| **continueOnError** | `boolean` | optional (default: `false`) | If true (and atomic=false), continue processing remaining records after errors. Default false: the first failure ENDS the run — records before it stay written (nothing is rolled back on this arm), and every record after it is reported `errors[0].code` NOT_ATTEMPTED rather than omitted, so `results` always covers all `total` records and `succeeded + failed === total`. |
119-
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
119+
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
120120

121121

122122
---
@@ -159,7 +159,7 @@ A write-path strip event: caller-supplied fields legally dropped from the payloa
159159
| **atomic** | `boolean` | optional (default: `false`) | Opt-in all-or-nothing. When explicitly true the whole batch runs inside ONE engine transaction: the first failure rolls back every prior write, and the response reports zero successes — each row carries `errors[0].code` ROLLED_BACK (written, then undone), the causal row its own error, and rows never reached NOT_ATTEMPTED. A runtime that cannot roll back REFUSES the request (501 NOT_IMPLEMENTED) rather than silently degrading to best-effort — probe `capabilities.transactionalBatch` on /discovery first. Takes precedence over continueOnError. Default false: sequential best-effort. |
160160
| **returnRecords** | `boolean` | optional (default: `false`) | If true, return full record data in response |
161161
| **continueOnError** | `boolean` | optional (default: `false`) | If true (and atomic=false), continue processing remaining records after errors. Default false: the first failure ENDS the run — records before it stay written (nothing is rolled back on this arm), and every record after it is reported `errors[0].code` NOT_ATTEMPTED rather than omitted, so `results` always covers all `total` records and `succeeded + failed === total`. |
162-
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
162+
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
163163

164164

165165
---
@@ -296,7 +296,7 @@ A cross-object batch strip event: dropped fields plus the operation index
296296
| **atomic** | `boolean` | optional (default: `false`) | Opt-in all-or-nothing. When explicitly true the whole batch runs inside ONE engine transaction: the first failure rolls back every prior write, and the response reports zero successes — each row carries `errors[0].code` ROLLED_BACK (written, then undone), the causal row its own error, and rows never reached NOT_ATTEMPTED. A runtime that cannot roll back REFUSES the request (501 NOT_IMPLEMENTED) rather than silently degrading to best-effort — probe `capabilities.transactionalBatch` on /discovery first. Takes precedence over continueOnError. Default false: sequential best-effort. |
297297
| **returnRecords** | `boolean` | optional (default: `false`) | If true, return full record data in response |
298298
| **continueOnError** | `boolean` | optional (default: `false`) | If true (and atomic=false), continue processing remaining records after errors. Default false: the first failure ENDS the run — records before it stay written (nothing is rolled back on this arm), and every record after it is reported `errors[0].code` NOT_ATTEMPTED rather than omitted, so `results` always covers all `total` records and `succeeded + failed === total`. |
299-
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
299+
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
300300

301301

302302
---
@@ -336,7 +336,7 @@ A cross-object batch strip event: dropped fields plus the operation index
336336
| **atomic** | `boolean` | optional (default: `false`) | Opt-in all-or-nothing. When explicitly true the whole batch runs inside ONE engine transaction: the first failure rolls back every prior write, and the response reports zero successes — each row carries `errors[0].code` ROLLED_BACK (written, then undone), the causal row its own error, and rows never reached NOT_ATTEMPTED. A runtime that cannot roll back REFUSES the request (501 NOT_IMPLEMENTED) rather than silently degrading to best-effort — probe `capabilities.transactionalBatch` on /discovery first. Takes precedence over continueOnError. Default false: sequential best-effort. |
337337
| **returnRecords** | `boolean` | optional (default: `false`) | If true, return full record data in response |
338338
| **continueOnError** | `boolean` | optional (default: `false`) | If true (and atomic=false), continue processing remaining records after errors. Default false: the first failure ENDS the run — records before it stay written (nothing is rolled back on this arm), and every record after it is reported `errors[0].code` NOT_ATTEMPTED rather than omitted, so `results` always covers all `total` records and `succeeded + failed === total`. |
339-
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
339+
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
340340

341341

342342
---

content/docs/references/api/protocol.mdx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ A write-path strip event: caller-supplied fields legally dropped from the payloa
616616
| **atomic** | `boolean` | optional (default: `false`) | Opt-in all-or-nothing. When explicitly true the whole batch runs inside ONE engine transaction: the first failure rolls back every prior write, and the response reports zero successes — each row carries `errors[0].code` ROLLED_BACK (written, then undone), the causal row its own error, and rows never reached NOT_ATTEMPTED. A runtime that cannot roll back REFUSES the request (501 NOT_IMPLEMENTED) rather than silently degrading to best-effort — probe `capabilities.transactionalBatch` on /discovery first. Takes precedence over continueOnError. Default false: sequential best-effort. |
617617
| **returnRecords** | `boolean` | optional (default: `false`) | If true, return full record data in response |
618618
| **continueOnError** | `boolean` | optional (default: `false`) | If true (and atomic=false), continue processing remaining records after errors. Default false: the first failure ENDS the run — records before it stay written (nothing is rolled back on this arm), and every record after it is reported `errors[0].code` NOT_ATTEMPTED rather than omitted, so `results` always covers all `total` records and `succeeded + failed === total`. |
619-
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
619+
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
620620

621621

622622
---
@@ -2705,7 +2705,7 @@ A write-path strip event: caller-supplied fields legally dropped from the payloa
27052705
| **atomic** | `boolean` | optional (default: `false`) | Opt-in all-or-nothing. When explicitly true the whole batch runs inside ONE engine transaction: the first failure rolls back every prior write, and the response reports zero successes — each row carries `errors[0].code` ROLLED_BACK (written, then undone), the causal row its own error, and rows never reached NOT_ATTEMPTED. A runtime that cannot roll back REFUSES the request (501 NOT_IMPLEMENTED) rather than silently degrading to best-effort — probe `capabilities.transactionalBatch` on /discovery first. Takes precedence over continueOnError. Default false: sequential best-effort. |
27062706
| **returnRecords** | `boolean` | optional (default: `false`) | If true, return full record data in response |
27072707
| **continueOnError** | `boolean` | optional (default: `false`) | If true (and atomic=false), continue processing remaining records after errors. Default false: the first failure ENDS the run — records before it stay written (nothing is rolled back on this arm), and every record after it is reported `errors[0].code` NOT_ATTEMPTED rather than omitted, so `results` always covers all `total` records and `succeeded + failed === total`. |
2708-
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
2708+
| **validateOnly** | `never` | optional | [REMOVED] `options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have silently executed. There is no dry-run today — drop the key. If you need to preview a batch without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) and reintroduced as a flag that actually holds. |
27092709

27102710

27112711
---

packages/spec/src/api/batch.zod.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export const BatchOptionsSchema = lazySchema(() => z.object({
9393
// and should be reintroduced deliberately, not back-filled to match a promise
9494
// nothing kept. Tombstoned so writing it is audible, not silently stripped.
9595
validateOnly: retiredKey(
96-
'`options.validateOnly` was removed from BatchOptions in @objectstack/spec. '
96+
'`options.validateOnly` was removed from BatchOptions in @objectstack/spec 17.0.0. '
9797
+ 'It was never implemented: the batch surfaces persisted regardless, so a "dry-run" would have '
9898
+ 'silently executed. There is no dry-run today — drop the key. If you need to preview a batch '
9999
+ 'without writing, open an issue so it can be designed (no-commit cascade / constraint semantics) '

0 commit comments

Comments
 (0)