Split out of #12935 while fixing it, so the residue is recorded rather than left
implicit. Filed unassigned. #12935's scope was the field-levelvisible key (3
occurrences, 2 files); these four are the same key name at two other tiers, with two
different mechanisms, and repairing them needs a judgment call that card did not have
a mandate to make.
Measured on origin/main @ db39dfc1c9b09681474475cea6e77537ab2c89ab. Instrument:
git grep -n -E '^[[:space:]]*[-[:space:]]*("?visible"?)[[:space:]]*:' \
-- content/docs/protocol/objectui/concept.mdx content/docs/protocol/objectui/layout-dsl.mdx
After #12935's fix that instrument returns exactly these four.
A. Section tier — key refused by name (same mechanism as #12935)
content/docs/protocol/objectui/layout-dsl.mdx:363 and :369, section "Conditional
Sections":
sections:
- label: Billing Informationvisible:
field: account_typevalue: premium
- label: Admin Settingsvisible:
permission: admin
FormSectionSchema is strict and declares visibleWhen plus the deprecated alias
visibleOn — never visible. visible matches VISIBILITY_KEY_PATTERN
(packages/spec/src/shared/visibility.ts), so it is a loud parse error that redirects
the author to visibleWhen. Neither value shape exists either: visibleWhen takes a CEL
predicate string, not a field/value pair and not a permission name.
The same page already carries the correct spelling of the first example, 440 lines
below at its "Visibility Rule" section: visibleWhen: "record.account_type == 'premium'".
So the page contradicts itself, and the wrong half comes first.
Why #12935 did not repair it: the second example is the problem. Rewriting
permission: admin as a visibleWhen positions test would teach the exact thing the
spec warns against — FormSectionSchema.visibleWhen's own description says nothing
server-side evaluates a form-view section predicate, so "a role test here hides the
controls and protects no data (declare permission-set field-level security for that)",
and on the public /f/:slug route the root is unbound and the predicate faults open.
The honest repair is therefore either to drop that example or to replace it with a
pointer to field-level security — a documentation judgment, not a rename.
B. Action tier — live key, wrong value shape (a DIFFERENT defect)
content/docs/protocol/objectui/concept.mdx:592 and :595, section "2. Contextual
Actions":
actions:
- type: standard_editvisible: { status: { $ne: 'locked' } }
- type: workflow_approvevisible: { permissions: { canApprove: true } }Here visibleis a declared key — content/docs/references/ui/action.mdx:84 gives
its type as boolean or a CEL string or a {dialect, source} envelope. A filter object
is in none of those arms. So unlike every other occurrence in this family the key is
fine and the value is the defect, which is why it is recorded separately rather than
folded into the field-level card.
Every other action example in the docs already uses the CEL string form, e.g.
content/docs/protocol/objectui/actions.mdx:303 — visible: "record.status == 'draft'".
The $ne spelling here is Mongo query syntax, which appears nowhere in the action
contract. The adjacent disabled: { has_children: true } on line 599 is very likely the
same defect and was not separately verified.
Why worth recording rather than folding into #12935
These are cheap to fix and the correct form for A is pinned by the page itself, but they
are not the same defect: A is a different schema tier whose repair needs a call about a
documented anti-pattern, and B is a value-shape error on a key that genuinely exists.
Bundling them would have made #12935's claim ("FieldSchema refuses the spelling by
name") false of half its own diff.
Related: #13086 records why this class survives — no gate reads YAML doc fences.
Re-check commands:
- the
git grep above git grep -n "visibleWhen" -- content/docs/protocol/objectui/layout-dsl.mdx (the page's own correct spelling)grep -n "visible" content/docs/references/ui/action.mdx (the declared action value union)
Generated by Claude Code
Split out of #12935 while fixing it, so the residue is recorded rather than left
implicit. Filed unassigned. #12935's scope was the field-level
visiblekey (3occurrences, 2 files); these four are the same key name at two other tiers, with two
different mechanisms, and repairing them needs a judgment call that card did not have
a mandate to make.
Measured on
origin/main@db39dfc1c9b09681474475cea6e77537ab2c89ab. Instrument:After #12935's fix that instrument returns exactly these four.
A. Section tier — key refused by name (same mechanism as #12935)
content/docs/protocol/objectui/layout-dsl.mdx:363and:369, section "ConditionalSections":
FormSectionSchemais strict and declaresvisibleWhenplus the deprecated aliasvisibleOn— nevervisible.visiblematchesVISIBILITY_KEY_PATTERN(
packages/spec/src/shared/visibility.ts), so it is a loud parse error that redirectsthe author to
visibleWhen. Neither value shape exists either:visibleWhentakes a CELpredicate string, not a
field/valuepair and not apermissionname.The same page already carries the correct spelling of the first example, 440 lines
below at its "Visibility Rule" section:
visibleWhen: "record.account_type == 'premium'".So the page contradicts itself, and the wrong half comes first.
Why #12935 did not repair it: the second example is the problem. Rewriting
permission: adminas avisibleWhenpositions test would teach the exact thing thespec warns against —
FormSectionSchema.visibleWhen's own description says nothingserver-side evaluates a form-view section predicate, so "a role test here hides the
controls and protects no data (declare permission-set field-level security for that)",
and on the public
/f/:slugroute the root is unbound and the predicate faults open.The honest repair is therefore either to drop that example or to replace it with a
pointer to field-level security — a documentation judgment, not a rename.
B. Action tier — live key, wrong value shape (a DIFFERENT defect)
content/docs/protocol/objectui/concept.mdx:592and:595, section "2. ContextualActions":
Here
visibleis a declared key —content/docs/references/ui/action.mdx:84givesits type as
booleanor a CEL string or a{dialect, source}envelope. A filter objectis in none of those arms. So unlike every other occurrence in this family the key is
fine and the value is the defect, which is why it is recorded separately rather than
folded into the field-level card.
Every other action example in the docs already uses the CEL string form, e.g.
content/docs/protocol/objectui/actions.mdx:303—visible: "record.status == 'draft'".The
$nespelling here is Mongo query syntax, which appears nowhere in the actioncontract. The adjacent
disabled: { has_children: true }on line 599 is very likely thesame defect and was not separately verified.
Why worth recording rather than folding into #12935
These are cheap to fix and the correct form for A is pinned by the page itself, but they
are not the same defect: A is a different schema tier whose repair needs a call about a
documented anti-pattern, and B is a value-shape error on a key that genuinely exists.
Bundling them would have made #12935's claim ("
FieldSchemarefuses the spelling byname") false of half its own diff.
Related: #13086 records why this class survives — no gate reads YAML doc fences.
Re-check commands:
git grepabovegit grep -n "visibleWhen" -- content/docs/protocol/objectui/layout-dsl.mdx(the page's own correct spelling)grep -n "visible" content/docs/references/ui/action.mdx(the declared action value union)Generated by Claude Code