Uh oh!
There was an error while loading. Please reload this page.
docs: state the multi-value set_null semantics on the six pages that document it - #9627
Conversation
…t document it (#9521) `deleteBehavior: 'set_null'` on a `multiple: true` reference removes the deleted MEMBER and keeps the rest, and a set emptied that way is written as `[]`, never `null` — the representation `FieldSchema` pins (the `multiple` doc block in packages/spec/src/data/field.zod.ts, #9447 maintainer ruling 2026-08-18). Each page is judged on its own job rather than given one pasted block: - protocol/objectql/types.mdx — corrects "Set field to null", which was the only page stating the single-value behaviour as universal; adds the residual-shape guarantee at protocol precision. - data-modeling/fields.mdx — the `null`/`""`/`[]` sentence now says which one is written when, instead of leaving all three equivalent. - data-modeling/field-types.mdx — the two table cells an author reads when choosing `deleteBehavior` and `multiple`. - deployment/troubleshooting.mdx — in place, for the mid-incident reader: a cleanup query looking for `null` will not match an emptied set. - api/data-api.mdx — the read-back shape an integrator's client branches on. - data-modeling/validation-rules.mdx — the live representation guarantee, plus the ruled `required`-means-non-empty half marked DECLARED BUT NOT YET ENFORCED (#9476), so the page promises nothing the validator does not do today. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
✅ PM ACCEPT — #9521 / PR #9627Verified independently: 6 files The classification is the result, and it answers the assumption I flagged as untestedMy dispatch said I did not know whether all six pages were wrong in the same way, and told you not to paste one block six times. You measured it: one wrong (
Six pages, six different sentences, each answering the question its own reader arrived with. That is what "judge each page on its own job" was asking for, and it is rare to get it. ✅ Ruling on the judgment you flagged for meYou asked whether writing the not-yet-enforced Silence was the worse option here, and specifically because of your own survey finding: The precision matters and you got it: the warn is scoped to the The correction to the card is noted and appreciatedThe card's paraphrase put the member-removal half in The survey earns the "six is the right set" claimDerived, not inherited: On the verificationNo local gate parses MDX, so compiling all six through The out-of-scope finding#9625 — Verdict: ACCEPT. Arming for the merge queue once gates converge — surface is ungoverned. Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#9521
Six hand-written pages named
set_nullwhile saying nothing about what it does to amultiple: truereference. Each page is judged on its own job here rather than givenone pasted block — six copies of the same paragraph is the drift this lane has spent
the day collapsing.
The contract, quoted rather than paraphrased
packages/spec/src/data/field.zod.ts, themultipledoc block:the
requireddoc block:Member removal itself is stated where it is implemented,
cascadeDeleteRelationsinpackages/objectql/src/engine.ts:10206-10212: on amultiple: truefield "clear" meansremove the deleted MEMBER and keep the rest.
Every edited page cites the spec through the generated
Field reference, which renders those exact
describestrings — a pointer that cannot drift, rather than a seventh hand-written restatement.
Per page: what it was, and what it needed
protocol/objectql/types.mdxset_null: Set field to null when referenced record is deleted", the single-value behaviour stated as universal[], nevernull, binding on every writer — not a cascade convention)data-modeling/fields.mdxnull,""and[]mean 'no link' — exactly whatset_nullwrites", which is true of no one of themnullon a single-value lookup, member removal on a multi-value one,[]when the last member goesdata-modeling/field-types.mdxdeleteBehaviorandmultiplemultiplerowdeployment/troubleshooting.mdxnullwill not match an emptied setapi/data-api.mdxset_nullappeared once, as a passing enum in batch deleteDELETE /data/:object/:iddata-modeling/validation-rules.mdxrequired-means-non-empty half marked declared but not yet enforced (the validator'sisMissingtreats onlyundefined/null/ blank strings as missing, so[]passes today — tracked in #9476)Is six the real set? Surveyed independently
The card's six came from the drift check's
set_nullliteral. Re-derived here by grepover
content/docs/**rather than inherited:set_null— 8 files: the six, plusreferences/data/field.mdx(AUTO-GENERATEDfrom
field.zod.ts; it already carries both sentences verbatim, and the spec is itsfix site) and
releases/v15.mdx(release-owned, untouched).deleteBehaviorwithoutset_null— 2 further hand-written pages the literal keycannot see:
getting-started/common-patterns.mdx(master-detail cascade only) andprotocol/objectql/schema.mdx(amultipleproperty row and acascadeexample).Both are silent, neither states an empty representation, so neither needed an edit —
but the key would have missed them had they been wrong.
multiple: true/ "multi-value" language — 5 more pages(
field-type-decision-tree,schema-design,seed-data,queries,automation/approvals); grepped each for anull/ empty /[]claim on thoselines and found none.
So six is the right edit set, arrived at independently; it is not proof that the
literal key is a survey.
Out of scope, filed unassigned
types.mdxalso claims "An explicitset_nullorcascadeis always honored aswritten". The engine escalates on the resolved behaviour
(
engine.ts:10265-10281), so it cannot tell an explicitset_nullfrom a defaulted oneon a
requiredlookup — and no test pins either reading. That is a different defectclass and the correct form is a decision, not a mechanical edit, so it is filed as
#9625 and untouched here.
Verification
Union re-run after the final commit, at
496b3de13:pnpm check:nul-bytes— OK (6173 text files, no raw control bytes)pnpm check:docs-audit-scope— OK (179 hand-written docs in scope; releases read-only)pnpm check:docs-redirects— OK (92 entries resolved)pnpm check:role-word— OK (43 baselined files, no new occurrences)pnpm --filter @objectstack/spec run check:empty-state/check:liveness/check:strictness-ledger/check:variant-docs— all OK@mdx-js/mdx3.1.1directly — 6/6 OK, with a positive control (a deliberately unclosed component tag)
observed FAILING, so the harness is not silently green.
Docs-only; publishes no package, so
skip-changesetrather than a changeset file.Generated by Claude Code