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
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
CEL blocking errors are dropped on the floor in ConditionBuilder and ConditionalFormattingEditor too — same ungated-Save family as #4306 #4527
While measuring #4306 (field inspector Save not gated on CEL errors) I found the same
wiring gap in two more CelPredicateField hosts, reaching four further inspectors.
CelPredicateField reports its lint verdict upward through onLintChange(issues)
(packages/app-shell/src/views/metadata-admin/CelPredicateField.tsx line 97, fired at
line 160). Only PermissionAdvancedFacets passes it. Every other mount site discards
the verdict, so a blocking parse fault is rendered inline and nothing acts on it.
Measured mount sites that pass no onLintChange
packages/app-shell/src/views/metadata-admin/inspectors/ConditionBuilder.tsx line 184
— reached by PageBlockInspector, HookDefaultInspector, ActionDefaultInspector
(and widgets.tsx).
packages/app-shell/src/views/metadata-admin/ConditionalFormattingEditor.tsx line 272
— reached by ViewVariantInspector.
Zero hits for onLintChange or onCelErrorsChange in either file, confirmed against a
known-present neighbour (PermissionAdvancedFacets.tsx lines 364 / 380), so this is an
absence rather than a search miss.
Why this is filed separately and blocked
The fix is not local to these components. Like #4306, the Save button these editors would
have to gate belongs to a host — StudioDesignSurface.tsx or ResourceEditPage.tsx —
reached only through the MetadataInspectorProps registry contract, which today carries
no error channel, and there is no React context anywhere in metadata-admin or studio-design to carry one instead (zero createContext hits in both trees).
So whichever channel #4306 settles on decides this one too. If that channel is named for
CEL specifically it will need renaming to cover these sites; if it is named for blocking
issues generally, wiring these four inspectors is mostly mechanical.
CLAIM — session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4527-inspector-family-wiring. Dispatching a dev agent now; the blocker (#4306 / PR #4536) is armed on green CI, so the gate opens in minutes.
PM ruling (delegated decision authority; maintainer veto window open — record objections here):
Wire through the shipped contract, mechanically. PR fix(app-shell): inspectors can block Save — the field inspector gates on CEL errors (#4306) #4536's onBlockingIssuesChange on MetadataInspectorProps was named for blocking issues generally precisely so this card is a wiring exercise, not a design one. The two shared editors (ConditionBuilder.tsx ~:184, ConditionalFormattingEditor.tsx ~:272) surface their CelPredicateField onLintChange blocking-error counts upward via a new optional callback prop; each of the five inspectors (PageBlockInspector, HookDefaultInspector, ActionDefaultInspector, widgets.tsx's, ViewVariantInspector) aggregates and reports through the contract.
Mirror fix(app-shell): inspectors can block Save — the field inspector gates on CEL errors (#4306) #4536's DERIVATION mechanism, not reset effects: stamp counts with what they describe (row/field/selection) and treat mismatch as 0 — no reset-effect windows, no set-state-in-effect warnings. Multi-instance editors (ConditionBuilder rows; multiple formatting rules) key a per-row/per-rule map with prune-by-derivation so a removed row cannot wedge Save.
Hosts (StudioDesignSurface, ResourceEditPage) already hold, gate and expire the count — do NOT touch them, or inspector-registry.ts, or ObjectFieldInspector.tsx.
Mutual exclusion: ⛔ #4271 is IN FLIGHT (metadata-client.ts, PermissionMatrixEditor ensureFields, celAuthoring/loadObjectFields + a census of client.get() call sites) — do not touch those; if a file you edit contains a client.get( call site, keep your edits away from those lines and note it in the report. Disjoint from #4272 (fields/plugin-grid/plugin-gantt), #4006 (fields/plugin-editor config), #4529 (plugin-charts). Gate worktree creation on PR #4536 visible in origin/main.
Q1 — the three default-family sites: option A. Extend MetadataDefaultInspectorProps with the SAME optional onBlockingIssuesChange member (symmetric with #4536's), have HookDefaultInspector, ActionDefaultInspector and ViewVariantInspector's home path aggregate exactly as the scoped family now does, and wire the host render sites that mount default inspectors — ResourceEditPage (:2341), StudioDesignSurface (:1592), and the three panel hosts the census surfaced (ObjectSettingsPanel:123, ObjectActionsPanel:215, ObjectHooksPanel:263), each holding/expiring its own stamped count and folding it into its own Save. Option C (context) is REJECTED for the reasons the dev gave and I adopt: a second implicit mechanism for the same fact makes "who gates Save" invisible at the call site — the ambient coupling that gets left silently unwired is the exact defect class this family exists to kill.
Q2 — StudioDesignSurface's DESIGN-pillar scoped render (~:1539): wire it. This is an unfinished edge of #4536, not new scope: the same malformed-CEL publish is reachable through Studio's design pillar today, gate inert, including for ObjectFieldInspector reached that way. One render site plus the stamped-count hold DataPillar already carries in the same file.
Also in phase 2: ObjectValidationsPanel:310 — the sixth ConditionBuilder consumer, which owns its own Save. Now that ConditionBuilder carries the optional reporter (PR #4547), wiring the panel is mechanical; include it, sized by measurement.
Explicitly DEFERRED (not in phase 2): widgets.tsx's ConditionWidget. It is a SchemaForm widget needing widget-context plumbing — a materially larger surface — and whether authors reach a CEL predicate through the generic form at all is unmeasured. It stays recorded here; a future card takes it only with that measurement in hand.
Grading forecast: MetadataDefaultInspectorProps is presumably entry-reachable like its sibling — if measurement confirms, minor; otherwise per the diff. The do-not-touch list from phase 1 is lifted for ResourceEditPage.tsx and StudioDesignSurface.tsx (their prior owners #4306/#4271 have landed); the census's client.get() sites in those files are landed context, not exclusions. Same dev continues with full context; PR #4547 (phase 1) is armed and landing.
Activity
yinlianghui commentedon Aug 13, 2026
CLAIM — session_017Qqyix2QcnpUC9XeYVDzx3, branch
claude/issue-4527-inspector-family-wiring. Dispatching a dev agent now; the blocker (#4306 / PR #4536) is armed on green CI, so the gate opens in minutes.PM ruling (delegated decision authority; maintainer veto window open — record objections here):
onBlockingIssuesChangeon MetadataInspectorProps was named for blocking issues generally precisely so this card is a wiring exercise, not a design one. The two shared editors (ConditionBuilder.tsx ~:184, ConditionalFormattingEditor.tsx ~:272) surface their CelPredicateFieldonLintChangeblocking-error counts upward via a new optional callback prop; each of the five inspectors (PageBlockInspector, HookDefaultInspector, ActionDefaultInspector, widgets.tsx's, ViewVariantInspector) aggregates and reports through the contract.Mutual exclusion: ⛔ #4271 is IN FLIGHT (metadata-client.ts, PermissionMatrixEditor ensureFields, celAuthoring/loadObjectFields + a census of client.get() call sites) — do not touch those; if a file you edit contains a
client.get(call site, keep your edits away from those lines and note it in the report. Disjoint from #4272 (fields/plugin-grid/plugin-gantt), #4006 (fields/plugin-editor config), #4529 (plugin-charts). Gate worktree creation on PR #4536 visible inorigin/main.Generated by Claude Code
Generated by Claude Code
yinlianghui commentedon Aug 13, 2026
PM phase-2 ruling after PR #4547's measured escalation (session_017Qqyix2QcnpUC9XeYVDzx3; delegated decision authority, maintainer veto window open):
Q1 — the three default-family sites: option A. Extend
MetadataDefaultInspectorPropswith the SAME optionalonBlockingIssuesChangemember (symmetric with #4536's), have HookDefaultInspector, ActionDefaultInspector and ViewVariantInspector's home path aggregate exactly as the scoped family now does, and wire the host render sites that mount default inspectors — ResourceEditPage (:2341), StudioDesignSurface (:1592), and the three panel hosts the census surfaced (ObjectSettingsPanel:123, ObjectActionsPanel:215, ObjectHooksPanel:263), each holding/expiring its own stamped count and folding it into its own Save. Option C (context) is REJECTED for the reasons the dev gave and I adopt: a second implicit mechanism for the same fact makes "who gates Save" invisible at the call site — the ambient coupling that gets left silently unwired is the exact defect class this family exists to kill.Q2 — StudioDesignSurface's DESIGN-pillar scoped render (~:1539): wire it. This is an unfinished edge of #4536, not new scope: the same malformed-CEL publish is reachable through Studio's design pillar today, gate inert, including for ObjectFieldInspector reached that way. One render site plus the stamped-count hold DataPillar already carries in the same file.
Also in phase 2: ObjectValidationsPanel:310 — the sixth ConditionBuilder consumer, which owns its own Save. Now that ConditionBuilder carries the optional reporter (PR #4547), wiring the panel is mechanical; include it, sized by measurement.
Explicitly DEFERRED (not in phase 2): widgets.tsx's ConditionWidget. It is a SchemaForm widget needing widget-context plumbing — a materially larger surface — and whether authors reach a CEL predicate through the generic form at all is unmeasured. It stays recorded here; a future card takes it only with that measurement in hand.
Grading forecast: MetadataDefaultInspectorProps is presumably entry-reachable like its sibling — if measurement confirms, minor; otherwise per the diff. The do-not-touch list from phase 1 is lifted for ResourceEditPage.tsx and StudioDesignSurface.tsx (their prior owners #4306/#4271 have landed); the census's client.get() sites in those files are landed context, not exclusions. Same dev continues with full context; PR #4547 (phase 1) is armed and landing.
Generated by Claude Code
Generated by Claude Code
fix(app-shell): the default-inspector family and its panel hosts gate…
fix(app-shell): inspectors can block Save — the field inspector gates…
fix(app-shell): all CEL-hosting inspectors block Save on parse faults (…