Skip to content

ConditionBuilder passes no scope, so an action's visible / disabled guard lints bare field refs clean on a row surface — the #7727 defect, at five more mount sites #8167

Description

@os-justin

Filed unassigned by the #7727 dev (PM loop R3, session session_01YBWFb5YgMU5dw8p2VKj16S) after contract review of PR #8164 named it. ⛔ Not folded into that PR: same defect class, different component, and three of the six mounts below need a per-surface verdict this card's author does not get to make.

What the search that found #7727 missed

#7727 and its triage both looked for the explicit spelling scope="flattened". CelPredicateField also reaches the flattened lint by callers omitting the propcelAuthoring.ts reads hint.scope ?? 'flattened'. Measured on origin/main = c14d3a090, every CelPredicateField mount in the repo:

mount scope= in that file scope in effect
ConditionalFormattingEditor.tsx:341 1 record (PR #8164)
inspectors/ObjectFieldInspector.tsx:760, :874, :888, :902 4 record
PermissionAdvancedFacets.tsx:356, :372 0 flattened — CORRECT, RLS is not a row surface (#5738 stand-down 3)
inspectors/ConditionBuilder.tsx:368 0 flattened — and this is the problem

grep -c 'scope=' inspectors/ConditionBuilder.tsx is 0. It has no scope prop on its own public interface either, so no caller can override it.

Why one of its callers is a defect today

packages/core/src/evaluator/rowPredicateCanon.ts:16-18 names the surface, verbatim:

A row predicate — visible / disabled / enabled on an action renderer, a row scope, a record:alert, a conditional-formatting condition — used to bind the row THREE ways

and packages/react/src/hooks/useExpression.ts:153-158 is what binds it now:

export function usePredicateRecordContext(record: unknown): Record<string, any> {
  return useMemo(() => {
    if (record == null || typeof record !== 'object' || Array.isArray(record)) return {};
    return { record: record as Record<string, any> };
  }, [record]);
}

record and nothing else. So a bare status == 'done' typed into Visible when on an action lints clean and never matches — #7727's defect exactly, on a surface #7727 does not touch.

The six ConditionBuilder mounts, with what I could and could not settle

mount authors verdict
inspectors/ActionDefaultInspector.tsx:671 action visible DEFECT — row surface by the canon's own words
inspectors/ActionDefaultInspector.tsx:672 action disabled DEFECT — same
views/studio-design/ObjectValidationsPanel.tsx:313 validation rule condition ⚠️ LIKELY DEFECT — the draft-level validator for the sibling surface already runs scope: 'record' (clientValidation.ts:792, :806), so the editor and the validator disagree
inspectors/PageBlockInspector.tsx:689 page block visibleWhen ❓ needs a verdict — node tier, not classified by #5330
widgets.tsx:2369 (ConditionWidget) any schema-driven predicate key ❓ needs a verdict — its surface is whatever the host schema points it at, so it may need the scope to become a prop
inspectors/FlowNodeConfigField.tsx:96 flow node condition CORRECT as-is — flow tier is not a row surface (#5738 stand-down 3)
inspectors/HookDefaultInspector.tsx:291 hook condition ❓ needs a verdict — server trigger tier

⇒ the fix is not "flip ConditionBuilder to record scope". Two of its callers are known-flattened or known-not-row, so the scope has to become a prop that each caller sets, and three callers need the tier question answered first.

What this card is NOT

⛔ Not a duplicate of #8155 (the app root is refused although bound) or #8166 (data.* is accepted although dead). Those are about the engine's root vocabulary at scope:'record'; this is about which sites reach scope:'record' at all. All three are tails of #5741 Phase 2, and this one is the only one with a mount site still teaching the bare shorthand.

Dedup

search_issues (REST is 403 from this seat class) — the same query returned #7727 and #8155, so the search was live. Nearest hits, none covering this: #6226 (ConditionBuilder rollout), #6293 (its row-mode quoting), #4527 (its blocking-issue reporting), #4421 (action visible and permissions). No open card names ConditionBuilder's lint scope.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdomain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatfindingpackage: app-shellpm:queuepriority:p2

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions