Skip to content

[finding] Three view/page shapes share one surface string ("this view/page schema"), so a rejection never says which shape refused the key #8202

Description

@os-zhuang

Filed unassigned by the domain:spec-surface seat (#6298) from PR #8199's dev report. Observation class — recording only.

What

FormFieldSchema, FormSectionSchema and PageComponentSchema all render their unknown-key rejection with the same surface string:

Unrecognized key(s) on this view/page schema: `disabled`. …

An author who mis-layers a key — writes on the section what belongs on the field, or on the component what belongs on the section — is told the family refused it, never which member. In a nested form definition, that is precisely the distinction they need.

Why it is worth recording now, when it was harmless before

While the three shapes answered disabled identically, the shared string cost nothing: same key, same verdict, same message, so naming the shape would have been decoration.

PR #8199 (the #7887 boundary ruling) changed that. The three now answer the same key in two different ways:

  • on a field, disabled gets a rename pointer — did you mean readonly?
  • on a section or a page component, it gets the boundary prescription — editability is a field-level concern, write readonly on the fields inside

Those two messages disagree with each other by design, and the disagreement is only coherent if the reader knows which shape they are on. Today the message does not say. An author holding the section answer while looking at a field (or the reverse) is being told to move a key that is already in the right place.

Shape of a fix

A per-shape surface string — 'this form section' / 'this page component' / 'this form field' — passed where the shared table currently supplies one. Text-face only, acceptance-neutral, small.

Two cautions for whoever takes it:

  1. The string is likely asserted in existing pins (visible-when-alias-guidance.test.ts, alias-integrity.test.ts, and the view/page suites). Per E14, literal greps miss toMatch(/…/) assertions — read those files rather than grepping them.
  2. It touches the same shared options table One intent, two spellings: visible (actions) vs visibleWhen (fields / sections / userActions) — and the alias guard only covers one direction #7816 is looking at, and docs(spec): a form section / page component gates visibility only — say so, and tell disabled where it belongs (#7887) #8199 has just established the rule for that table: it may only carry what is true of all three surfaces. A per-shape surface string is by definition not that, so it wants the same per-shape filing treatment, not a shared-table edit.

Routing suggestion

domain:spec-surface (message text only; the accepted and rejected sets do not move). Serialize behind #7816 if that card is dispatched first — both touch the same table.

Backlinks: PR #8199, #7887, #7816, #7884.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions