Repository navigation
feat(spec): referenceDeletedWhen beside referenceVia marks a pointer's target as platform-deleted - #23759
Conversation
Claude-Session: https://claude.ai/code/session_01LSSHP4Yb97YuFXXzj85HMJ Co-authored-by: Claude <noreply@anthropic.com>
…orm row, generated artifacts, changeset Claude-Session: https://claude.ai/code/session_01LSSHP4Yb97YuFXXzj85HMJ Co-authored-by: Claude <noreply@anthropic.com>
…age tables; bump field census pins Claude-Session: https://claude.ai/code/session_01LSSHP4Yb97YuFXXzj85HMJ Co-authored-by: Claude <noreply@anthropic.com>
…n zh-CN, ja-JP and es-ES; bump catalog census pins Claude-Session: https://claude.ai/code/session_01LSSHP4Yb97YuFXXzj85HMJ Co-authored-by: Claude <noreply@anthropic.com>
…ference-deleted-when
…s for the referenceDeletedWhen classification Claude-Session: https://claude.ai/code/session_01LSSHP4Yb97YuFXXzj85HMJ Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 4 package(s): 11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 143 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 f4739bdc34be3247940a422881e90bd6f0e29ece && git checkout f4739bdc34be3247940a422881e90bd6f0e29ece
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 140238a47b892ef9234052e44267ec3739fa79c2 645116bef8e07c81784acad61568ac89b561d046 && git checkout -B drift-repro 140238a47b892ef9234052e44267ec3739fa79c2 && git merge --no-ff 645116bef8e07c81784acad61568ac89b561d046
node scripts/docs-audit/affected-docs.mjs --json 140238a47b892ef9234052e44267ec3739fa79c2
|
席位核对 · ACCEPT · PR #23759 @
|
Contract reviewServed-tier: Inputs: card #23735 (body and all 3 comments: triage 6204123641, the dispatch claim 6204194958, the os-dev-report 6205248708), the ruling 6203737086 on objectstack-ai/objectui#12489 (letter A), the PR body, its 23-file list, the merge-base diff against ① Derived judgments
② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
Fixes #23735
Clause-②: yes
The spec half of objectstack-ai/objectui#12489 ruling
6203737086, letter A (maintainer 「A (推荐)」):FieldSchemagainsreferenceDeletedWhen: { field, value }besidereferenceVia. On rows where the siblingselectfieldfieldholds the optionvalue, the record the pointer names was deleted by the platform's own assertion; a renderer draws the tombstone from that option's own label, reads nothing and links nothing.What changed
packages/spec/src/data/field.zod.ts: the key, directly afterreferenceVia, as a closedstrictObject(field: snake_case;value: string). Refusal 1 in theFieldSchemasuperRefine beside thereferenceViachecks: the key on a field that declares noreferenceVia. The message names the field and the option.packages/spec/src/data/object.zod.ts:refuseDishonestReferenceDeletedWhen, in theObjectSchemasuperRefine besiderefuseNonPictureImageField(the parse-time sibling door), not increate()only. One locatedcustomissue atfields.FIELD.referenceDeletedWhen.fieldor.valuewhenfieldis the declaring field itself, is undeclared, is not aselect, is amultiple: trueselect, or declares no inlineoptions(apicklist-backed select); or whenvalueis not one of the sibling's option values (the declared set is listed). Every door refuses it:ObjectSchema.create(),defineStack, raw.parse()and the save door (getMetadataTypeSchema('object')).packages/spec/src/data/field.form.ts: acompositeform row besidereferenceVia(thecurrencyConfigface), gateddata.type == 'text'.packages/spec/liveness/field.json: aplannedrow, drilled tofield/value. It names both carriers: the producer plugin-approvals: sys_approval_request.record_id declares referenceDeletedWhen on cancel_reason = record_deleted (objectui#12489 letter A) #23736 (sys_approval_request.record_idwith{ field: 'cancel_reason', value: 'record_deleted' }) and the consumer objectui#12489 step 4. There is noauthorWarn, following thefield.settledWhenprecedent.authorable-surface/data.json,content/docs/references/**(3 pages), the strictness-ledger counts, andliveness/state-counts/field.md..changeset/23735-reference-deleted-when.md:@objectstack/specminor;@objectstack/metadata-core,@objectstack/driver-sqland@objectstack/platform-objectspatch(commit645116bef; this line amended by the seat to match the changeset).Outside the claimed file surface (forced by the widening, measured)
A new
FieldSchemakey reaches every exhaustive per-key table and census pin. Each one below went red, or would have, without its line:packages/metadata-core/src/object-schema-fls-references.ts:FIELD_REFERENCE_POSITIONSis pinned against the liveFieldSchemashape. The key is classifieddeletedWhen: the predicate is deleted whole when itsfieldnames a field the caller cannot read (valueis an option, never a field). This has a new pin inobject-schema-fls-references.test.ts.packages/drivers/driver-sql/src/builtin-column-collision.ts:FIELD_KEY_STORAGE_CLASSclassifies itpresentation(no DDL reads it).packages/platform-objectstranslation catalogs: the form row's three labels and help texts, hand-translated in zh-CN, ja-JP and es-ES (check:i18ngreen, source-hash entries dropped). Two catalog census pins moved: 669 → 672 and 8 → 10.metadata-protocol/meta/typesfield property count 79 → 80, andlintshipped-form predicate counts 88 → 89 and 65 → 66.No
plugin-approvalsorplatform-objectsobject file was touched; that is #23736. No objectui file was touched.Verification (head
d13e56398, after mergingorigin/maina869ea636)@objectstack/spec: test 680 files / 20771 passed; typecheck exit 0;check:generated"All 14 generated artifacts are up to date" after a real (DTS) build;check:livenessexit 0.field-reference-deleted-when.test.ts: 15 passed. Ablation: thevaluecheck disabled throughscripts/ablation-replace.mjsgave 3 failed / 12 passed, and the file was restored with blob equal to HEAD (c7916c270c23) and an emptygit diff HEAD.@objectstack/objectql427 files / 8148 passed (pre-merge head);@objectstack/metadata-protocol236 files / 20577 passed;@objectstack/lint139 files / 6771 passed;@objectstack/metadata-core18 files / 728 passed plus typecheck;@objectstack/platform-objects70 files / 1091 passed plus typecheck;@objectstack/driver-sqlcollision pin 11 passed plus typecheck.dispatch-gates --commands: 113 families derived. 110 exited 0. 3 are NOT MEASURED locally:check:skill-examples(exit 3) andcheck:dual-build-cjs-loads(exit 3) refused a prerequisite, andcheck:dts-closure(exit 1) reported missing.d.tsin 48 packages that this container had built withOS_SKIP_DTS. That is local dist state, not a tree finding. CI builds fresh and runs all three.Acceptance notes
options. Apicklist-backedselectis refused, because its values are not declared on the object and the option cannot be checked at parse. Amultiple: trueselect is refused, because "holds that value" has no single reading on an array.ObjectExtensionSchema) are not judged: the check reads the authored object's own field map, asimageFielddoes.Generated by Claude Code