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
Found while implementing #6437 (widening DroppedFieldsEvent.reason), in the TSDoc block that change edits for a different reason. Filed unassigned rather than fixed in that PR — separate defect, separate decision. Recording only, not claiming.
Fact
packages/spec/src/contracts/data-engine.ts, closing line of strictReadonlyWrites:
INSERT ignores it, for the same reason onFieldsDropped never fires there:
insert is exempt from both strips, so there is nothing to refuse.
packages/objectql/src/engine.ts disagrees, and has since #5503:
ReadonlyFieldRejectedError's own doc records the same thing from the other side — "Thrown by engine.update — and, since #5503, by engine.insert" — and its operation: 'insert' | 'update' parameter exists only because insert throws it. Both statements cannot be true; the contract's is the stale one.
Why it matters more than a typo
Both halves of the sentence are load-bearing and both are now false:
"INSERT ignores it" — a caller reading the contract concludes it is safe to pass strictReadonlyWrites: true on a create. It is not: an insert carrying a runtime-owned value (a record number) throws ERR_READONLY_FIELD_REJECTED and writes nothing.
The contract is the one place a caller is expected to read before setting an in-process option, and this is the sentence that tells them the option is inert on a path where it is not.
Landing site
packages/spec/src/contracts/data-engine.ts — the final paragraph of the strictReadonlyWrites TSDoc. Prose only; the .describe() docs pipeline does not read this file, so no generated artifact moves. Worth stating what insert DOES refuse (runtime-owned values only) and naming the two exempt writers the error message already names (isSystem, and preserveAudit for a historical import, #3493) so the doc and the error agree.
Found while implementing #6437 (widening
DroppedFieldsEvent.reason), in the TSDoc block that change edits for a different reason. Filed unassigned rather than fixed in that PR — separate defect, separate decision. Recording only, not claiming.Fact
packages/spec/src/contracts/data-engine.ts, closing line ofstrictReadonlyWrites:packages/objectql/src/engine.tsdisagrees, and has since #5503:ReadonlyFieldRejectedError's own doc records the same thing from the other side — "Thrown byengine.update— and, since #5503, byengine.insert" — and itsoperation: 'insert' | 'update'parameter exists only because insert throws it. Both statements cannot be true; the contract's is the stale one.Why it matters more than a typo
Both halves of the sentence are load-bearing and both are now false:
strictReadonlyWrites: trueon a create. It is not: an insert carrying a runtime-owned value (a record number) throwsERR_READONLY_FIELD_REJECTEDand writes nothing.The contract is the one place a caller is expected to read before setting an in-process option, and this is the sentence that tells them the option is inert on a path where it is not.
Landing site
packages/spec/src/contracts/data-engine.ts— the final paragraph of thestrictReadonlyWritesTSDoc. Prose only; the.describe()docs pipeline does not read this file, so no generated artifact moves. Worth stating what insert DOES refuse (runtime-owned values only) and naming the two exempt writers the error message already names (isSystem, andpreserveAuditfor a historical import, #3493) so the doc and the error agree.Related: #5503, #5126, #3413, #3493, #6437.
Generated by Claude Code