Repository navigation
Commit a5cb4f1
docs(spec): the security-service contract describes an empty optional controlled_by_parent master reference (#31126)
<!-- claude-projects-attribution: {"github_login":"marchtian"} -->
_Requested by **田騏** · [project
thread](https://claude.ai/code/project/chan_01VmuUhXU9SSUzqJYyXSmYSi?thread=cmsg_01VmuUhXU9SSUzqJYyXSmYSiPNRknnohwjfU4LkaBEoT56)_
Fixes #31094
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:只改 `packages/spec` 里安全服务契约的注释(JSDoc):`master_chain`
拒绝、`master_reference_missing` 原因、`allow` 结果和
`checkControlledByParentWrite`
自身说明,现在都写明「可选主表为空」的行按属主规则判:属主或该对象「修改全部」可写,其他人在 `master_chain`
上被拒;链上某一跳的可选主表为空时,链在那一跳按同一规则结束。必填主表为空仍是原来的答案。
- **为什么改**:您对 #30905 的裁决「A」已由 PR #31082
落到写门,但契约注释还写着「主表一定必填」「写子记录一定要主记录编辑权」,读契约的人会得出错误结论。
- **风险与回滚**:纯注释加一个 patch changeset,类型、导出、运行时行为都不变;回滚即 revert。
- **先看**:`packages/spec/src/contracts/security-service.ts` 里
`ControlledByParentWriteDenialLeg` 的 `master_chain` 一条。
- **两分钟验证**:`git diff origin/main --
packages/spec/src/contracts/security-service.ts`,预期只有注释行变化。
- **需要你做的**:无,席位落地。
## What changes
JSDoc only, in `packages/spec/src/contracts/security-service.ts`, plus
an `'@objectstack/spec': patch` changeset. Each sentence was checked
against the write gate
(`packages/plugins/plugin-security/src/security-plugin-cbp-write-gate.ts`)
and PR #31082's tests (`controlled-by-parent-optional-master.test.ts`),
under ADR-0055 §3 as amended 2026-11-07 (maintainer ruling 「A」 on #30905
/ #30906):
1. `ControlledByParentWriteDenialLeg`: the intro and `master_chain` now
cover the record whose own optional master reference is empty (refused
to a principal who neither owns it nor holds Modify All on its object; a
row with no owner, or of an object without `owner_id`, is Modify All's
alone), and a master above whose optional master is empty (the three
legs run on it, then that row's owner rule ends the chain). Only a
required master's empty reference above the record is the chain-walk
refusal the old text described.
2. `ControlledByParentWriteUnresolvedReason`: `master_reference_missing`
is a stored **required** master reference left empty; an empty optional
one answers `allow` or `deny` on `master_chain`.
3. `ISecurityService.checkControlledByParentWrite`: "requires EDIT
access to its master, or, where its optional master reference is empty,
ownership of the record or Modify All on its object".
Beyond the card's three items, the same file's sentences that the ruling
also made false were corrected in place (same defect class, same file):
the `allow` bullet of `ControlledByParentWriteOutcome`, the "answers the
master check alone" sentence, and the empty-permission-set bullet (such
a principal answers on `master_chain`, never `object_permission`, for a
record whose optional master is empty). The ⛔ lines at the end of the
member's docblock are untouched.
## Tests
No behaviour change, so no test is added. The behaviour the text
describes is pinned by
`packages/plugins/plugin-security/src/controlled-by-parent-optional-master.test.ts`
(`ISecurityService.checkControlledByParentWrite answers as the write
path does`, including the required-master `master_reference_missing`
control).
## Acceptance notes
- No generated reference embeds this JSDoc: `content/docs/references/**`
has no hit for these names, and `api-surface/contracts.json` /
`export-origins/contracts.json` list the type names only, so nothing is
regenerated.
- Noted, not fixed here (pre-existing): the `allow` bullet does not
mention the `sharing.controlledByParent.ownerMayEdit` opt-in leg
(ADR-0055 §3 amendment of 2026-10-26), through which a by-id update by
the row's owner with READ on the master also resolves `allow`. Handed to
the seat for a separate card.
- An independent full review of the diff found one should-fix and two
nits, all applied; the delta review passed. Its verdict is posted as a
comment on this PR.
## Verification
Local gates on the final head are listed in the card's `os-dev-report`;
CI runs the full set.
---
_Generated by [Claude
Code](https://claude.ai/code/session_017ihL2etQ7BmrJuMddPx75W)_
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 962ea9d commit a5cb4f1
2 files changed
Lines changed: 59 additions & 19 deletions
File tree
- .changeset
- packages/spec/src/contracts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
328 | 328 | | |
329 | 329 | | |
330 | 330 | | |
331 | | - | |
332 | | - | |
333 | | - | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
334 | 337 | | |
335 | 338 | | |
336 | 339 | | |
| |||
340 | 343 | | |
341 | 344 | | |
342 | 345 | | |
343 | | - | |
344 | | - | |
345 | | - | |
346 | | - | |
347 | | - | |
348 | | - | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
349 | 360 | | |
350 | 361 | | |
351 | 362 | | |
| |||
374 | 385 | | |
375 | 386 | | |
376 | 387 | | |
377 | | - | |
378 | | - | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
379 | 393 | | |
380 | 394 | | |
381 | 395 | | |
| |||
389 | 403 | | |
390 | 404 | | |
391 | 405 | | |
392 | | - | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
393 | 410 | | |
394 | 411 | | |
395 | 412 | | |
| |||
1062 | 1079 | | |
1063 | 1080 | | |
1064 | 1081 | | |
1065 | | - | |
1066 | | - | |
1067 | | - | |
1068 | | - | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
1069 | 1090 | | |
1070 | 1091 | | |
1071 | 1092 | | |
| |||
1080 | 1101 | | |
1081 | 1102 | | |
1082 | 1103 | | |
1083 | | - | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
1084 | 1107 | | |
1085 | 1108 | | |
1086 | 1109 | | |
1087 | 1110 | | |
1088 | | - | |
1089 | | - | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
1090 | 1116 | | |
1091 | 1117 | | |
1092 | 1118 | | |
| |||
0 commit comments