From 3c693d15c017257d9b3cc6509bf92914d7e95c08 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 19 Aug 2026 04:37:05 +0000 Subject: [PATCH] docs(validating-metadata): the four-door table records the object runtime door after #4716 (#9836) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Three rows of the "one gate, four doors" table read `—` in the `runtime publish` column for rules that now run there. #4716 (PR #9825, squash 1408ae337) crossed five gating object rules onto that door, taking it from 2 rules to 7. Corrected against the built registry, not the source text: :392 functional completeness + managed API methods — -> ✓ᵒ :413 autonumber `{field}` interpolation — -> ✓ᵒ The "declared enforcement that cannot run" row is SPLIT rather than edited. It bundled four rule ids that now sit on opposite sides of the wall: `validateRuleCompilability` (#4762) and `validateRuleSchemaFormats` (#5178) carry `runtimeTypes: ['object']`, while `validateSharingRuleEnforceability` (#4698) and `validateRlsPredicateEnforceability` (#4983) are `CLI_ONLY`. `✓ᵒ` on the merged row would claim the door judges an RLS predicate on an object write; `—` keeps the current falsehood. The split is drawn by which collection carries the declaration each rule reads, and a new paragraph states that rule so the next crossing does not re-derive it — following the precedent the page already sets for the security vocabulary freeze. Also: #4716 appended to the crossing-history clause, and the `—`-reasons paragraph gains the reason class #4716 created. All four existing reasons still hold, but the advisory-tier object rules moved: their old `RUNTIME_OBJECT_WRITES_P2` reason is retired (0 occurrences), replaced by `RUNTIME_OBJECT_ADVISORY_VOLUME` on six rules whose registry text says crossing them is "explicitly NOT a bare `runtimeTypes` edit" — the opposite of what the paragraph's third reason would have told a reader. No change to `AUTHORING_RULES`, no rule's `runtimeTypes`, nothing under `content/docs/releases/`. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_019yDEhPBC3tcGkW9bkce1HM --- .../docs/deployment/validating-metadata.mdx | 56 ++++++++++++++----- 1 file changed, 41 insertions(+), 15 deletions(-) diff --git a/content/docs/deployment/validating-metadata.mdx b/content/docs/deployment/validating-metadata.mdx index 6847aeae39..04ef2d6a65 100644 --- a/content/docs/deployment/validating-metadata.mdx +++ b/content/docs/deployment/validating-metadata.mdx @@ -389,7 +389,7 @@ one. `sys_metadata` overlay rows are not in any config file, so there is no | Protocol schema (Zod) | ✓ | ✓ | — | ✓ | | CEL / predicate validation (ADR-0032) | ✓ | ✓ | ✓ | ✓ᶠ | | List-view navigation modes (ADR-0053) | ✓ | ✓ | ✓ | — | -| Zod-valid but functionally inert declarations — a `summary` with no operations (ADR-0078), a managed object advertising an API method its affordances refuse (#7521) | ✓ | ✓ | ✓ | — | +| Zod-valid but functionally inert declarations — a `summary` with no operations (ADR-0078), a managed object advertising an API method its affordances refuse (#7521) | ✓ | ✓ | ✓ | ✓ᵒ | | View container shape | ✓ | ✓ | ✓ | — | | Widget-binding integrity (ADR-0021) | ✓ | ✓ | ✓ | ✓ᵈ | | Dashboard action/route references (ADR-0049) | ✓ | ✓ | ✓ | — | @@ -408,9 +408,10 @@ one. `sys_metadata` overlay rows are not in any config file, so there is no | Security posture (ADR-0090 — e.g. every custom object declares `sharingModel`) | ✓ | ✓ | ✓ | ✓ˢᵖᵉᵇᵒ | | Security vocabulary freeze (ADR-0090 D3 — the reserved word, replaced by `permission_set` / `position` / `business_unit`) | ✓ | ✓ | ✓ | — | | Organization-axis red lines (ADR-0105 D6) | ✓ | ✓ | ✓ | — | -| Declared enforcement that cannot run — sharing-rule conditions (#4698), row-level-security predicates (#4983), a validation rule's regex / JSON Schema (#4762) and its `format` names (#5178) | ✓ | ✓ | ✓ | — | +| Declared enforcement that cannot run, **declared on the object being written** — a validation rule's regex / JSON Schema (#4762) and its `format` names (#5178) | ✓ | ✓ | ✓ | ✓ᵒ | +| Declared enforcement that cannot run, **declared on another collection** — sharing-rule conditions (#4698), row-level-security predicates (#4983) | ✓ | ✓ | ✓ | — | | Platform-schedule `create_record` organization (#6285) | — | — | — | ✓ᶠ | -| Autonumber `{field}` interpolation | ✓ | ✓ | ✓ | — | +| Autonumber `{field}` interpolation | ✓ | ✓ | ✓ | ✓ᵒ | | View references — form targets, view-key collisions (#2554) | ✓ | ✓ | ✓ | — | | Flow authoring anti-patterns (#1874) | ✓ | ✓ | ✓ | ✓ᶠ | | Flow trigger readiness — a flow that looks armed and never launches (#5762) | ✓ | ✓ | ✓ | ✓ᶠ | @@ -432,8 +433,10 @@ grown a type at a time (#4463 shipped P1 as `flow` and four rule families, #7220 moved the whole `views[]` visibility-predicate family across in one edit, #7529 put widget-binding integrity on `dashboard`, #8307 → #8310 walked the ADR-0090 security-posture block across `seed`, then `permission` and `book`, then -`object`), so read the rule rather than assuming a save of some other type -reaches storage unjudged. +`object`, and #4716 crossed the five remaining **gating** object rules — +functional completeness, managed API methods, autonumber formats, and both +validation-rule enforceability checks — onto `object`), so read the rule rather +than assuming a save of some other type reaches storage unjudged. That last move is also why the vocabulary freeze is a row of its own. It was split out of the security-posture rule on the day the rest of that block @@ -441,17 +444,40 @@ crossed, because it judges collections the per-write snapshot does not carry: one rule id has to sit on ONE side of the wall, so it stayed behind whole rather than crossing for some of the collections it judges and not others. -The `—` cells above are `—` for more than one reason, and only the first two are -about the rule being unable to run there: some rules read a stack-wide +**Declared enforcement that cannot run** is two rows for the mirror-image +reason, and #4716 is where it split. That heading covers four rule ids, and +the split is drawn by **which collection carries the declaration each one +reads** — not by what the rules have in common, which is everything. +`validateRuleCompilability` (#4762) and `validateRuleSchemaFormats` (#5178) +read `validationRules[]` on the object being written, so an `object` write +already carries every declaration they judge and they crossed with the rest of +#4716. `validateSharingRuleEnforceability` (#4698) reads `sharingRules[]` and +`validateRlsPredicateEnforceability` (#4983) reads `permissions[]`, so neither +is answered by an `object` write at all — and each is held by something +different: the door does not accept `sharing_rule` as a type yet, whereas +`permissions` has been in the snapshot since #8309 and only the declaration is +missing. The freeze kept one id whole by staying behind; here four ids stopped +agreeing, and one row cannot say two things. **When the next crossing lands on +a shared row, check the rule ids before the cell: if they disagree, split the +row by the collection each id reads, and neither `✓` nor `—` has to lie.** + +The `—` cells above are `—` for more than one reason, and only the first two +are about the rule being unable to run there: some rules read a stack-wide collection a one-item write does not carry (pages, dashboards, navigation, -positions, apps — the snapshot has carried `permissions` and `books` since #8309 -and `datasets` since #7529, so those three are no longer in this class); some parse -authored source through `typescript`, which the kernel boot path must never -load; some are snapshot-safe and simply have not been rolled out to a type yet -(a sharing rule or an RLS predicate crosses on a `runtimeTypes` edit, not on new -wiring); and the capability-reference rule would *graduate* from advisory to -gating at that door, since the live registry decides what the CLI has to hedge — -a severity change on a published rule id, which is its own PR rather than a +positions, apps — the snapshot has carried `permissions` and `books` since +#8309 and `datasets` since #7529, so those three are no longer in this class); +some parse authored source through `typescript`, which the kernel boot path +must never load; some are snapshot-safe and simply have not been rolled out to +a type yet (a sharing rule or an RLS predicate crosses on a `runtimeTypes` +edit, not on new wiring); some judge an object declaration at **advisory** +tier, where what holds them back is advisory VOLUME rather than anything they +are unable to do — #4716 crossed the gating object rules and left these six +measured at ~8 findings per object write on unswept metadata, which Studio's +designer has rendered on every field edit since #4717, so crossing one is a UX +decision with its own card and explicitly *not* a bare `runtimeTypes` edit; +and the capability-reference rule would *graduate* from advisory to gating at +that door, since the live registry decides what the CLI has to hedge — a +severity change on a published rule id, which is its own PR rather than a wiring change. The visibility family crossed **together**, and that is the point rather than an