You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
feat(spec): builder forces required: true on a master_detail reference under controlled_by_parent (#9138) (#9206)
* feat(spec): builder forces required: true on a master_detail reference under controlled_by_parent (#9138)
Direction 2 of the #8772 maintainer ruling (2026-08-16, comment 5306089973):
ObjectSchema.create() now forces required: true on every master_detail
reference of a sharingModel: 'controlled_by_parent' object when the author
omits it, and refuses an explicit required: false there with a located,
prescriptive error. Raw .parse()/.safeParse() stay tolerant — metadata at
rest keeps loading unrewritten; runtime (resolveCbpRelation) and lint
severity are deliberately untouched (they are separate ruled slices).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y26DJEHSBhhAQ6wwfsHNza
* chore(spec): register cbp-master-detail-required-forced (protocol 18) + changeset (#9138)
ADR-0087 disposition: registered. The semantic entry carries the FROM -> TO
prescription; spec-changes.json and the upgrade guide project only released
majors, so they are byte-identical until the v18 cut (verified by regenerating
both).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y26DJEHSBhhAQ6wwfsHNza
---------
Co-authored-by: Claude <noreply@anthropic.com>
feat(spec): the builder forces `required: true` on a `master_detail` reference under `controlled_by_parent` (#9138 — #8772 maintainer ruling, Direction 2)
6
+
7
+
**BREAKING** accept-face narrowing on the authoring builder, landing after the
8
+
v17.0.0 cut (the lockstep launch-window convention ships it as `minor`; the
9
+
prescription is registered under protocol major 18, where `os migrate meta`
10
+
users will look).
11
+
12
+
A `controlled_by_parent` object derives ALL of its record access from the
13
+
master its `master_detail` reference names (ADR-0055). A master reference that
14
+
is not `required` arms the worst measured failure shape: an insert may omit
15
+
the master FK, the row lands with a null FK that the derived read filter
16
+
(`masterFK IN (accessible master ids)`) can never match — unreadable by
17
+
everyone — and every later by-id write answers `422 MISSING_REQUIRED_FIELD`.
18
+
#8772 measured that only the security gate closed that shape while the
19
+
declaration surface accepted it.
20
+
21
+
`ObjectSchema.create()` now makes the unsafe shape impossible to newly
22
+
declare:
23
+
24
+
- an **omitted**`required` on a `master_detail` reference under
25
+
`sharingModel: 'controlled_by_parent'` is **forced to `true`** in the
26
+
emitted object;
27
+
- an **explicit `required: false`** there is **refused** with a located error
28
+
naming the object, the field, the consequence and the fix — an explicitly
29
+
authored contradiction is not silently rewritten (ADR-0032).
30
+
31
+
## FROM → TO
32
+
33
+
```ts
34
+
// before — parsed green; the null-FK trap stayed armed behind the security gate
0 commit comments