Repository navigation
Commit 63f962f
domain:spec#2 · os-support-ai · session_01WGufzhJG3tKnksHVa1krBz
<!-- claude-projects-attribution: {"github_login":"os-support-ai"} -->
_Requested by **Yibo Wang** · [project
thread](https://claude.ai/code/project/chan_01BVUyyPie8gHwoPM18iABwB?thread=cmsg_01BVUyyPie8gHwoPM18iABwBTc1Gxk14k2PbeArtFLuL8a)_
Fixes #29415
Supersedes #29553 (same commits, resumed on a new branch; #29553 is
closed)
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:在 #29553 的三个提交之上(从 `59709cbb` 续做,两次合入
main),补上冻结期间欠下的两处文字:对象元数据读取的 `cascadeDeleteObjects` 说明现在把「声明了
`deleteBehavior: 'cascade'` 的 user 字段」列入会级联删除的关系;`FieldSchema` 的
deleteBehavior 注释把容易误读的「AUTHORS one」改成「declares a
`deleteBehavior`」。其余内容(语义迁移条目、hook/contract 文字、两个表单的可见性规则)与 #29553 相同。
- 为什么改:#29368 让 user 字段上声明的 deleteBehavior 在删除用户时生效,spec 文字还说 user
字段不参与删除联动;protocol.ts 冻结已解除(#28677 评论 6588593530),上一席的 Release
6591556737 点名这两处为落地前的欠项。
- 风险与回滚:只改文字和重新生成的参考文档,运行时与作者可写的键都不变。第二次合入 main 时 field.form.ts 与 #29639
新增的 `referenceNameVisible` 行相邻冲突,已手工合并、两边都保留。#29253 的未发布 changeset
仍是有意更正,`check-empty-changeset` 按设计保持红灯(与 #29553 相同)。回滚即 revert。
-
先看:packages/spec/src/data/field.form.ts(合并冲突的解决处:`referenceNameVisible`
行与其下的 `deleteBehavior`
行);packages/spec/src/api/protocol.zod.ts(`GetMetaItemResponseSchema.cascadeDeleteObjects`);.changeset/29415-user-delete-behavior-entry.md(新增的同版更正段)。
- 两分钟验证:`grep -c "or .user. field that declares"
content/docs/references/api/protocol.mdx`,预期输出 1(`cascadeDeleteObjects`
那一行)。
- 需要你做的:在本 PR 上确认对 #29253 未发布 changeset 的这次更正(check-empty-changeset
的人工确认路径,与 #29553 相同)。
## What changes
This PR carries the three commits of #29553 (`44bec0e9`, `21cd9672`,
`59709cbb`) unchanged, merges `origin/main` twice (`744211fc`, then
`1c1a5d40`), and adds the delta that the `protocol.ts` freeze held back.
#29553's body describes the inherited part: the semantic entry
`user-field-delete-behavior-enforced`, the correction of the unreleased
#29253 changeset, the prose in `field.zod.ts`, `hook.zod.ts`,
`objectql-engine.ts` and the `user-field-foreign-reference-refused`
entry, and the `deleteBehavior` visibility rule in both forms.
The delta:
- **`packages/spec/src/api/protocol.zod.ts`,
`GetMetaItemResponseSchema.cascadeDeleteObjects`.** The describe listed
the cascading relations as "a `master_detail` by default, a `lookup` or
`tree` that declares `deleteBehavior: 'cascade'`". It now reads "a
`master_detail` by default, a `lookup`, `tree` or `user` field that
declares `deleteBehavior: 'cascade'`", the wording of the
`getCascadeDeleteObjects` contract docblock. The engine side already
holds: `getCascadeDeleteObjects` walks `cascadeRelationBehavior`, whose
family test is `statesDeleteSemantics`, which admits a `user` field that
declares a `deleteBehavior` (`packages/objectql/src/engine.ts`, on
`744211fc`).
- **The other three sites the order named, measured and left as they
are.** `GetMetaItemCachedResponseSchema.cascadeDeleteObjects` points at
"the item read's `cascadeDeleteObjects`" and lists no relation kinds;
the two `[#28001]` docblocks (above `GetMetaItemResponseSchema` and
`GetMetaItemCachedResponseSchema`) speak of "the rule its delete walk
runs" and list none either. None of the three says or implies that a
`user` field stays out of the walk, so none is edited.
- **`packages/spec/src/data/field.zod.ts`, the `deleteBehavior` docblock
(#9784 paragraph).** "and on a `user` field that AUTHORS one" read as a
`user` field authoring a `reference`, which the same schema refuses. It
now reads "and on a `user` field that declares a `deleteBehavior`"; the
rest of the parenthetical is re-wrapped, unchanged.
- **Regenerated:** `content/docs/references/api/protocol.mdx` (1 row)
and `content/docs/references/api/app-bundle.mdx` (5 rows), both by
`gen:docs`. No other artifact moved (`check:generated`: all 14 up to
date).
- **Changeset** `.changeset/29415-user-delete-behavior-entry.md` stays a
`@objectstack/spec` patch. Its spec-text bullet now names the
`cascadeDeleteObjects` description on the metadata `object` read beside
the other corrected texts.
- **DELIBERATE CORRECTION of the unreleased #28001 note**
(`.changeset/28001-cascade-delete-objects-beside-item.md`, patch round 1
at `abde58e1`, the contract review's should-fix 1): its one sentence
listing the cascading relations now reads "a `lookup`, `tree` or `user`
field that declares `deleteBehavior: 'cascade'`", word for word the
corrected describe, so the note is true on the day it ships.
`check-empty-changeset` reds on this file and on
`.changeset/29253-user-field-delete-behavior.md`, both corrections by
design.
- **Maintainer authorization of the changeset corrections**, verbatim in
the card thread, 2026-11-03T02:56Z: 「授权你修改」.
## Why
Release 6591556737 on #29415 names exactly this delta as owed before
landing; the freeze that held `protocol.zod.ts` was lifted at 6588593530
on #28677. Triage's at-tier record 6588315424 (PASS on `59709cbb`)
covers the inherited commits; contract-review-hold 6588339023 covers the
old head until this edit lands.
## Tests
No test added: the delta is describe and comment text, and no reader
parses it. Text only, so no accept set moves: `Clause-②: no`,
`Metadata-protocol: none`.
<details><summary><code>pnpm --filter @objectstack/spec test</code> and
<code>typecheck</code>, head <code>72a8bffd</code></summary>
- `pnpm --filter @objectstack/spec test`: Test Files 803 passed (803),
Tests 23790 passed and 1 todo.
- `pnpm --filter @objectstack/spec typecheck`: `tsc --noEmit`,
`check:scripts-typecheck` and `check:test-typecheck` exit 0 (52 files /
240 errors / 131 pinned signatures held in the debt ledger, unchanged).
- `pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2
src/validate-predicate-path-refs.test.ts`: 62 passed (62), with main's
predicate count 91 and this branch's literal-comparison count 63 side by
side after the merge.
- All three in one locked run: `VERDICT command-exit 0`.
- The same spec suite on the pre-merge head `89540569` (before the
second `origin/main` merge): Test Files 802 passed (802), Tests 23736
passed and 1 todo, typecheck exit 0.
</details>
## Verification
<details><summary>Build, generated artifacts and derived gates, head
<code>72a8bffd</code></summary>
- Two merges of `origin/main`: `83189767` (onto `744211fc`, clean) and
`72a8bffd` (onto `1c1a5d40`). The second hit one conflict in
`packages/spec/src/data/field.form.ts`: #29639 put its
`referenceNameVisible` row directly above the `deleteBehavior` row this
branch respells. Resolved by hand, keeping both: main's comment and row,
and this branch's `data.type in ['lookup','user']` gate on
`deleteBehavior`. `scripts/pm/os-regen-merge.sh` ran after each merge.
For `app-bundle.mdx`, `protocol.mdx` and `hook.mdx` it kept the branch's
bytes, because main did not touch them.
- Full build after the second merge (`turbo run build
--filter=!@objectstack/docs --concurrency=2`, under the verify lock):
117/117 tasks, `VERDICT command-exit 0`. Then `pnpm --filter
@objectstack/spec check:generated`: all 14 generated artifacts up to
date.
- Derived gates (`node scripts/pm/dispatch-gates.mjs --commands`, 105
commands on `72a8bffd`), run one after another with `CMD :: exit N`
recorded: 104 exit 0, and 1 exits 1 by design, `check-empty-changeset
--base origin/main` on `.changeset/29253-user-field-delete-behavior.md`
(see Acceptance notes). `dispatch-gates --ran`: 105 derived, 105 run, 0
NOT-MEASURED, 0 UNRUN, exit 0.
- No gate is left NOT MEASURED. The built-output gates
(`check:dual-build-cjs-loads`, `check:lean-entry-closure`, `check:i18n`,
`check:docs-transcript-drift`, `spec check:skill-examples`, `lint
check:doc-formula-expressions`, `lint check:doc-security-posture`) ran
on a full build and exit 0. `check:dual-build-cjs-loads` was NOT
MEASURED on #29553.
- Local-only state gates: `pnpm check:dev-prereqs` and `pnpm
check:skill-frame-freshness` exit 0.
</details>
## Acceptance notes
- `check-empty-changeset` stays red by design, as on #29553: this PR
rewrites the pending #29253 release note it did not add (the DELIBERATE
CORRECTION class). The remedy is a confirmation on the PR, not a
restore.
- The `#7010 corpus` census pin in
`packages/lint/src/validate-predicate-path-refs.test.ts` (63) is
inherited from `59709cbb`. `origin/main` moved no `visibleWhen` or
`data.type` predicate under `packages/spec/src` between the fork point
`399df5bb` and `744211fc` (`git diff -G` over that range: zero files),
so the count still holds. The test file passes on the final head
(62/62). The second merge brought #29639's `referenceNameVisible` row,
which is an in-list too: it moves main's predicate count to 91 and
leaves the literal-comparison count at 63.
- The inherited acceptance notes of #29553 stand (the `tree` control,
the form's missing empty option, #29400).
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
- [x] 2. Every name I added uses the casing for its kind.
- [ ] 3. No formatter ran; `pnpm lint` passes. (No formatter ran. `pnpm
lint` was not run locally: it is CI's run.)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01WGufzgmDWPyn8w47uKA3CW)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3eeb81d commit 63f962f
16 files changed
Lines changed: 150 additions & 43 deletions
File tree
- .changeset
- content/docs/references
- api
- data
- packages
- lint/src
- spec/src
- api
- contracts
- data
- migrations/entries/semantic
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
| 14 | + | |
15 | 15 | | |
16 | 16 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
7 | 7 | | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
| 10 | + | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
20 | | - | |
| 20 | + | |
21 | 21 | | |
22 | 22 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
0 commit comments