Uh oh!
There was an error while loading. Please reload this page.
docs(objectql): reword the #9625 cascade escalation justification after #9476 landed - #9818
Conversation
#9476 landed Two comments justified the required-FK set_null -> restrict escalation partly by the then-true clause that an empty array still satisfied `required` in the record validator. #9476's enforcement landed, so that clause is false: `[]` on a required multi-value field is rejected today. Prose only -- no executable line changes, the escalation stays exactly as ruled, and the test pin's assertions are untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019yDEhPBC3tcGkW9bkce1HM
📓 Docs Drift Check1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them. ✅ What this run could not seeCoarse fallback — 14 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 3957fbcc88fca75ebecb10bdcb936679e13b65d8 && git checkout 3957fbcc88fca75ebecb10bdcb936679e13b65d8
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin e124e58f9525e278bba7583cd9a505ab5681d92c 493cebfa4fc24ecf9a46d3718bd0f96e5c704e0e && git checkout -B drift-repro e124e58f9525e278bba7583cd9a505ab5681d92c && git merge --no-ff 493cebfa4fc24ecf9a46d3718bd0f96e5c704e0e
node scripts/docs-audit/affected-docs.mjs --json e124e58f9525e278bba7583cd9a505ab5681d92c |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#9781
Two comments justified the #9625 escalation —
set_nullon a required FK escalating torestrict— partly by a clause that is now false:The #9476 enforcement landed as
6a5e6adf1, so[]on a required multi-value field is rejected today.isEmptyForRequiredinpackages/objectql/src/validation/record-validator.tsis that judgment, and bothrequiredread sites call it.What changed
Prose only, at the two sites the card names:
packages/objectql/src/engine.ts— the cascade-delete comment above theset_null+requiredescalation.packages/objectql/src/engine-cascade-delete.test.ts— the comment inside the[#9625] refuses a required MULTI-VALUE lookup ...pin.The escalation itself is untouched, and so are the pin's assertions.
The justification survives — and it never rested on the validator's tolerance
Checked rather than assumed, because a replacement clause that is subtly false would be worse than the stale one:
engine.ts— a required FK cannot be nulled, soset_nullwould issue an UPDATE the child's required-field validator rejects, naming a field that is not even on the object being deleted. That paragraph is independent of array emptiness and is still true.Two things I deliberately did NOT write, having measured them false or unsupportable:
cascadeDeleteRelationswalks relations sequentially and writes per relation, andplanCascadeAtomicityreturnssplitfor a cross-datasource cascade, where earlier relations commit before a laterrestrictthrows. Both comments now say the refusal fires before THIS relation's ownset_nullwrite, which is what actually holds.__referentialFieldClearmarker on that write exempts only plugin-security's ownership-anchor guard (security-plugin.ts:2057), it does not skip record validation.Verification at
493cebfa4The diff is comment-only, proven mechanically rather than by eye — every changed line is a comment line:
Gates re-derived with
node scripts/pm/dispatch-gates.mjs(no paths passed, so the script takes its own change set from the merge base), all run at493cebfa4:pnpm check:durability-log-levelpnpm check:stack-collection-mapsnode scripts/check-engine-split-ratio.mjsnode scripts/docs-audit/check-affected-docs.mjspnpm check:query-options-erasurepnpm check:engine-double-contractpnpm check:where-matcherpnpm check:type-check-coveragePackage level, after
pnpm --filter "@objectstack/objectql^..." build:vitest run src/engine-cascade-delete.test.ts— 1 file, 9 tests passedtsc --noEmitinpackages/objectql— exit 0, zero errorspnpm check:type-check-debt(the--re-measureratchet half) is left to CI: it needs the whole workspace closure built and re-runs tsc across every ledger entry. The reading taken in its place is direct and covers the entry these paths touch — objectql's owntsc --noEmitis clean, the structural half of that gate is green above, and the diff neither adds nor removes an@ts-expect-error/@ts-ignore/@ts-nocheck, which is the only comment-borne construct that can move a tsc count.Changeset
No changeset; the
skip-changesetlabel instead — taken from the repo's own gate rather than assumed.changeset-checkinpr-automation.ymlrecognises exactly two exemptions, and the label is the one that applies here. The empty-frontmatter route is shut in this repo: the step below the counter rejects an empty changeset a PR newly introduces (#5471), so choosing it would trade one red for another. Nothing user-visible changes — comments never reachdist.Generated by Claude Code